dpt.c revision 1.12 1 /* $NetBSD: dpt.c,v 1.12 1999/10/23 16:26:33 ad Exp $ */
2
3 /*-
4 * Copyright (c) 1997, 1998, 1999 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Andy Doran, Charles M. Hannum and by Jason R. Thorpe of the Numerical
9 * Aerospace Simulation Facility, NASA Ames Research Center.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. All advertising materials mentioning features or use of this software
20 * must display the following acknowledgement:
21 * This product includes software developed by the NetBSD
22 * Foundation, Inc. and its contributors.
23 * 4. Neither the name of The NetBSD Foundation nor the names of its
24 * contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
28 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
29 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
31 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37 * POSSIBILITY OF SUCH DAMAGE.
38 */
39
40 /*
41 * Portions of this code fall under the following copyright:
42 *
43 * Originally written by Julian Elischer (julian (at) tfs.com)
44 * for TRW Financial Systems for use under the MACH(2.5) operating system.
45 *
46 * TRW Financial Systems, in accordance with their agreement with Carnegie
47 * Mellon University, makes this software available to CMU to distribute
48 * or use in any manner that they see fit as long as this message is kept with
49 * the software. For this reason TFS also grants any other persons or
50 * organisations permission to use or modify this software.
51 *
52 * TFS supplies this software to be publicly redistributed
53 * on the understanding that TFS is not responsible for the correct
54 * functioning of this software in any circumstances.
55 */
56
57 /*
58 * Driver for DPT EATA SCSI adapters.
59 *
60 * TODO:
61 *
62 * o Need a front-end for (newer) ISA boards.
63 * o Handle older firmware better.
64 * o Find a bunch of different firmware EEPROMs and try them out.
65 * o Test with a bunch of different boards.
66 * o dpt_readcfg() should not be using CP_PIO_GETCFG.
67 * o An interface to userland applications.
68 * o Some sysctls or a utility (eg dptctl(8)) to control parameters.
69 */
70
71 #include <sys/cdefs.h>
72 __KERNEL_RCSID(0, "$NetBSD: dpt.c,v 1.12 1999/10/23 16:26:33 ad Exp $");
73
74 #include <sys/param.h>
75 #include <sys/systm.h>
76 #include <sys/kernel.h>
77 #include <sys/device.h>
78 #include <sys/queue.h>
79 #include <sys/proc.h>
80 #include <sys/buf.h>
81
82 #include <machine/endian.h>
83 #include <machine/bswap.h>
84 #include <machine/bus.h>
85
86 #include <dev/scsipi/scsi_all.h>
87 #include <dev/scsipi/scsipi_all.h>
88 #include <dev/scsipi/scsiconf.h>
89
90 #include <dev/ic/dptreg.h>
91 #include <dev/ic/dptvar.h>
92
93 /* A default for our link struct */
94 static struct scsipi_device dpt_dev = {
95 NULL, /* Use default error handler */
96 NULL, /* have a queue, served by this */
97 NULL, /* have no async handler */
98 NULL, /* Use default 'done' routine */
99 };
100
101 static char *dpt_cname[] = {
102 #ifdef notdef
103 "PM3755", "SmartRAID V",
104 "PM3754", "SmartRAID V",
105 "PM2654", "SmartRAID V",
106 "PM2554", "SmartRAID V",
107 "PM1554", "SmartRAID V",
108 #endif
109 "PM3334", "SmartRAID IV",
110 "PM3332", "SmartRAID IV",
111 "PM2144", "SmartCache IV",
112 "PM2044", "SmartCache IV",
113 "PM2142", "SmartCache IV",
114 "PM2042", "SmartCache IV",
115 "PM2041", "SmartCache IV",
116 "PM3224", "SmartRAID III",
117 "PM3222", "SmartRAID III",
118 "PM3021", "SmartRAID III",
119 "PM2124", "SmartCache III",
120 "PM2024", "SmartCache III",
121 "PM2122", "SmartCache III",
122 "PM2022", "SmartCache III",
123 "PM2021", "SmartCache III",
124 "SK2012", "SmartCache Plus",
125 "SK2011", "SmartCache Plus",
126 NULL, "unknown adapter, please report using send-pr(1)",
127 };
128
129 /*
130 * Handle an interrupt from the HBA.
131 */
132 int
133 dpt_intr(xxx_sc)
134 void *xxx_sc;
135 {
136 struct dpt_softc *sc;
137 struct dpt_ccb *ccb;
138 struct eata_sp *sp;
139 static int moretimo;
140 int more;
141
142 sc = xxx_sc;
143 sp = sc->sc_statpack;
144 more = 0;
145
146 #ifdef DEBUG
147 if ((dpt_inb(sc, HA_AUX_STATUS) & HA_AUX_INTR) == 0)
148 printf("%s: spurious intr\n", sc->sc_dv.dv_xname);
149 #endif
150
151 /* Don't get stalled by HA_ST_MORE */
152 if (moretimo < DPT_MORE_TIMEOUT / 100)
153 moretimo = 0;
154
155 for (;;) {
156 /*
157 * HBA might have interrupted while we were dealing with the
158 * last completed command, since we ACK before we deal; keep
159 * polling. If no interrupt is signalled, but the HBA has
160 * indicated that more data will be available soon, hang
161 * around.
162 */
163 if ((dpt_inb(sc, HA_AUX_STATUS) & HA_AUX_INTR) == 0) {
164 if (more != 0 && moretimo++ < DPT_MORE_TIMEOUT / 100) {
165 DELAY(10);
166 continue;
167 }
168 break;
169 }
170
171 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_ccb, sc->sc_spoff,
172 sizeof(struct eata_sp), BUS_DMASYNC_POSTREAD);
173
174 /* Might have looped before HBA can reset HBA_AUX_INTR */
175 if (sp->sp_ccbid == -1) {
176 DELAY(50);
177 #ifdef DIAGNOSTIC
178 printf("%s: slow reset of HA_AUX_STATUS?",
179 sc->sc_dv.dv_xname);
180 #endif
181 if ((dpt_inb(sc, HA_AUX_STATUS) & HA_AUX_INTR) == 0)
182 return (0);
183 #ifdef DIAGNOSTIC
184 printf("%s: was a slow reset of HA_AUX_STATUS",
185 sc->sc_dv.dv_xname);
186 #endif
187 /* Re-sync DMA map */
188 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_ccb,
189 sc->sc_spoff, sizeof(struct eata_sp),
190 BUS_DMASYNC_POSTREAD);
191 }
192
193 /* Make sure CCB ID from status packet is realistic */
194 if (sp->sp_ccbid >= 0 && sp->sp_ccbid < sc->sc_nccbs) {
195 /* Sync up DMA map and cache cmd status */
196 ccb = sc->sc_ccbs + sp->sp_ccbid;
197
198 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_ccb,
199 CCB_OFF(sc, ccb), sizeof(struct dpt_ccb),
200 BUS_DMASYNC_POSTWRITE);
201
202 ccb->ccb_hba_status = sp->sp_hba_status & 0x7F;
203 ccb->ccb_scsi_status = sp->sp_scsi_status;
204
205 /*
206 * Ack the interrupt and process the CCB. If this
207 * is a private CCB it's up to dpt_poll() to notice.
208 */
209 sp->sp_ccbid = -1;
210 ccb->ccb_flg |= CCB_INTR;
211 more = dpt_inb(sc, HA_STATUS) & HA_ST_MORE;
212 if ((ccb->ccb_flg & CCB_PRIVATE) == 0)
213 dpt_done_ccb(sc, ccb);
214 } else {
215 printf("%s: bogus status (returned CCB id %d)\n",
216 sc->sc_dv.dv_xname, sp->sp_ccbid);
217
218 /* Ack the interrupt */
219 sp->sp_ccbid = -1;
220 more = dpt_inb(sc, HA_STATUS) & HA_ST_MORE;
221 }
222
223 /* Don't get stalled by HA_ST_MORE */
224 if (moretimo < DPT_MORE_TIMEOUT / 100)
225 moretimo = 0;
226 }
227
228 return (0);
229 }
230
231 /*
232 * Initialize and attach the HBA. This is the entry point from bus
233 * specific probe-and-attach code.
234 */
235 void
236 dpt_init(sc, intrstr)
237 struct dpt_softc *sc;
238 const char *intrstr;
239 {
240 struct eata_inquiry_data *ei;
241 int i, j, error, rseg, mapsize;
242 bus_dma_segment_t seg;
243 struct eata_cfg *ec;
244 char model[16];
245
246 ec = &sc->sc_ec;
247
248 /* Allocate the CCB/status packet/scratch DMA map and load */
249 sc->sc_nccbs = min(SWAP16(*(int16_t *)ec->ec_queuedepth), DPT_MAX_CCBS);
250 sc->sc_spoff = sc->sc_nccbs * sizeof(struct dpt_ccb);
251 sc->sc_scroff = sc->sc_spoff + sizeof(struct eata_sp);
252 sc->sc_scrlen = 256; /* XXX */
253 mapsize = sc->sc_nccbs * sizeof(struct dpt_ccb) + sc->sc_scrlen +
254 sizeof(struct eata_sp);
255
256 if ((error = bus_dmamem_alloc(sc->sc_dmat, mapsize, NBPG, 0,
257 &seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) {
258 printf("%s: unable to allocate CCBs, error = %d\n",
259 sc->sc_dv.dv_xname, error);
260 return;
261 }
262
263 if ((error = bus_dmamem_map(sc->sc_dmat, &seg, rseg, mapsize,
264 (caddr_t *)&sc->sc_ccbs, BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) != 0) {
265 printf("%s: unable to map CCBs, error = %d\n",
266 sc->sc_dv.dv_xname, error);
267 return;
268 }
269
270 if ((error = bus_dmamap_create(sc->sc_dmat, mapsize, mapsize, 1, 0,
271 BUS_DMA_NOWAIT, &sc->sc_dmamap_ccb)) != 0) {
272 printf("%s: unable to create CCB DMA map, error = %d\n",
273 sc->sc_dv.dv_xname, error);
274 return;
275 }
276
277 if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap_ccb,
278 sc->sc_ccbs, mapsize, NULL, BUS_DMA_NOWAIT)) != 0) {
279 printf("%s: unable to load CCB DMA map, error = %d\n",
280 sc->sc_dv.dv_xname, error);
281 return;
282 }
283
284 sc->sc_statpack = (struct eata_sp *)((caddr_t)sc->sc_ccbs +
285 sc->sc_spoff);
286 sc->sc_sppa = sc->sc_dmamap_ccb->dm_segs[0].ds_addr + sc->sc_spoff;
287 sc->sc_scr = (caddr_t)sc->sc_ccbs + sc->sc_scroff;
288 sc->sc_scrpa = sc->sc_dmamap_ccb->dm_segs[0].ds_addr + sc->sc_scroff;
289 sc->sc_statpack->sp_ccbid = -1;
290
291 /* Initialize the CCBs */
292 TAILQ_INIT(&sc->sc_free_ccb);
293 i = dpt_create_ccbs(sc, sc->sc_ccbs, sc->sc_nccbs);
294
295 if (i == 0) {
296 printf("%s: unable to create CCBs\n", sc->sc_dv.dv_xname);
297 return;
298 } else if (i != sc->sc_nccbs) {
299 printf("%s: %d/%d CCBs created!\n", sc->sc_dv.dv_xname, i,
300 sc->sc_nccbs);
301 sc->sc_nccbs = i;
302 }
303
304 /* Set shutdownhook before we start any device activity */
305 sc->sc_sdh = shutdownhook_establish(dpt_shutdown, sc);
306
307 /* Get the page 0 inquiry data from the HBA */
308 dpt_hba_inquire(sc, &ei);
309
310 /*
311 * dpt0 at pci0 dev 12 function 0: DPT SmartRAID III (PM3224A/9X-R)
312 * dpt0: interrupting at irq 10
313 * dpt0: 64 queued commands, 1 channel(s), adapter on ID(s) 7
314 */
315 for (i = 0; ei->ei_vendor[i] != ' ' && i < 8; i++)
316 ;
317 ei->ei_vendor[i] = '\0';
318
319 for (i = 0; ei->ei_model[i] != ' ' && i < 7; i++)
320 model[i] = ei->ei_model[i];
321 for (j = 0; ei->ei_suffix[j] != ' ' && j < 7; j++)
322 model[i++] = ei->ei_model[i];
323 model[i] = '\0';
324
325 /* Find the cannonical name for the board */
326 for (i = 0; dpt_cname[i] != NULL; i += 2)
327 if (memcmp(ei->ei_model, dpt_cname[i], 6) == 0)
328 break;
329
330 printf("%s %s (%s)\n", ei->ei_vendor, dpt_cname[i + 1], model);
331
332 if (intrstr != NULL)
333 printf("%s: interrupting at %s\n", sc->sc_dv.dv_xname, intrstr);
334
335 printf("%s: %d queued commands, %d channel(s), adapter on ID(s)",
336 sc->sc_dv.dv_xname, sc->sc_nccbs, ec->ec_maxchannel + 1);
337
338 for (i = 0; i <= ec->ec_maxchannel; i++)
339 printf(" %d", ec->ec_hba[3 - i]);
340 printf("\n");
341
342 /* Reset the SCSI bus */
343 if (dpt_cmd(sc, NULL, 0, CP_IMMEDIATE, CPI_BUS_RESET))
344 panic("%s: dpt_cmd failed", sc->sc_dv.dv_xname);
345 DELAY(20000);
346
347 /* Fill in the adapter, each link and attach in turn */
348 sc->sc_adapter.scsipi_cmd = dpt_scsi_cmd;
349 sc->sc_adapter.scsipi_minphys = dpt_minphys;
350
351 for (i = 0; i <= ec->ec_maxchannel; i++) {
352 struct scsipi_link *link;
353
354 sc->sc_hbaid[i] = ec->ec_hba[3 - i];
355 link = &sc->sc_link[i];
356 link->scsipi_scsi.channel = i;
357 link->scsipi_scsi.adapter_target = sc->sc_hbaid[i];
358 link->scsipi_scsi.max_lun = ec->ec_maxlun;
359 link->scsipi_scsi.max_target = ec->ec_maxtarget;
360 link->type = BUS_SCSI;
361 link->device = &dpt_dev;
362 link->adapter = &sc->sc_adapter;
363 link->adapter_softc = sc;
364 link->openings = sc->sc_nccbs;
365 config_found(&sc->sc_dv, link, scsiprint);
366 }
367 }
368
369 /*
370 * Our 'shutdownhook' to cleanly shut down the HBA. The HBA must flush
371 * all data from it's cache and mark array groups as clean.
372 */
373 void
374 dpt_shutdown(xxx_sc)
375 void *xxx_sc;
376 {
377 struct dpt_softc *sc;
378
379 sc = xxx_sc;
380 printf("shutting down %s...", sc->sc_dv.dv_xname);
381 dpt_cmd(sc, NULL, 0, CP_IMMEDIATE, CPI_POWEROFF_WARN);
382 DELAY(5000*1000);
383 printf(" done\n");
384 }
385
386 /*
387 * Send an EATA command to the HBA.
388 */
389 int
390 dpt_cmd(sc, cp, addr, eatacmd, icmd)
391 struct dpt_softc *sc;
392 struct eata_cp *cp;
393 u_int32_t addr;
394 int eatacmd, icmd;
395 {
396 int i;
397
398 for (i = 20000; i; i--) {
399 if ((dpt_inb(sc, HA_AUX_STATUS) & HA_AUX_BUSY) == 0)
400 break;
401 DELAY(50);
402 }
403
404 /* Not the most graceful way to handle this */
405 if (i == 0) {
406 printf("%s: HBA timeout on EATA command issue; aborting\n",
407 sc->sc_dv.dv_xname);
408 return (-1);
409 }
410
411 if (cp == NULL)
412 addr = 0;
413
414 dpt_outb(sc, HA_DMA_BASE + 0, (u_int32_t)addr);
415 dpt_outb(sc, HA_DMA_BASE + 1, (u_int32_t)addr >> 8);
416 dpt_outb(sc, HA_DMA_BASE + 2, (u_int32_t)addr >> 16);
417 dpt_outb(sc, HA_DMA_BASE + 3, (u_int32_t)addr >> 24);
418
419 if (eatacmd == CP_IMMEDIATE) {
420 if (cp == NULL) {
421 /* XXX should really pass meaningful values */
422 dpt_outb(sc, HA_ICMD_CODE2, 0);
423 dpt_outb(sc, HA_ICMD_CODE1, 0);
424 }
425 dpt_outb(sc, HA_ICMD, icmd);
426 }
427
428 dpt_outb(sc, HA_COMMAND, eatacmd);
429 return (0);
430 }
431
432 /*
433 * Wait for the HBA to reach an arbitrary state.
434 */
435 int
436 dpt_wait(sc, mask, state, ms)
437 struct dpt_softc *sc;
438 u_int8_t mask, state;
439 int ms;
440 {
441
442 for (ms *= 10; ms; ms--) {
443 if ((dpt_inb(sc, HA_STATUS) & mask) == state)
444 return (0);
445 DELAY(100);
446 }
447 return (-1);
448 }
449
450 /*
451 * Wait for the specified CCB to finish. This is used when we may not be
452 * able to sleep and/or interrupts are disabled (eg autoconfiguration).
453 * The timeout value from the CCB is used. This should only be used for
454 * CCB_PRIVATE requests; otherwise the CCB will get recycled before we get
455 * a look at it.
456 */
457 int
458 dpt_poll(sc, ccb)
459 struct dpt_softc *sc;
460 struct dpt_ccb *ccb;
461 {
462 int i;
463
464 #ifdef DEBUG
465 if ((ccb->ccb_flg & CCB_PRIVATE) == 0)
466 panic("dpt_poll: called for non-CCB_PRIVATE request\n");
467 #endif
468
469 if ((ccb->ccb_flg & CCB_INTR) != 0)
470 return (0);
471
472 for (i = ccb->ccb_timeout * 20; i; i--) {
473 if ((dpt_inb(sc, HA_AUX_STATUS) & HA_AUX_INTR) != 0)
474 dpt_intr(sc);
475 if ((ccb->ccb_flg & CCB_INTR) != 0)
476 return (0);
477 DELAY(50);
478 }
479 return (-1);
480 }
481
482 /*
483 * Read the EATA configuration from the HBA and perform some sanity checks.
484 */
485 int
486 dpt_readcfg(sc)
487 struct dpt_softc *sc;
488 {
489 struct eata_cfg *ec;
490 int i, j, stat;
491 u_int16_t *p;
492
493 ec = &sc->sc_ec;
494
495 /* Older firmware may puke if we talk to it too soon after reset */
496 dpt_outb(sc, HA_COMMAND, CP_RESET);
497 DELAY(750000);
498
499 for (i = 1000; i; i--) {
500 if ((dpt_inb(sc, HA_STATUS) & HA_ST_READY) != 0)
501 break;
502 DELAY(2000);
503 }
504
505 if (i == 0) {
506 printf("%s: HBA not ready after reset: %02x\n",
507 sc->sc_dv.dv_xname, dpt_inb(sc, HA_STATUS));
508 return (-1);
509 }
510
511 while((((stat = dpt_inb(sc, HA_STATUS))
512 != (HA_ST_READY|HA_ST_SEEK_COMPLETE))
513 && (stat != (HA_ST_READY|HA_ST_SEEK_COMPLETE|HA_ST_ERROR))
514 && (stat != (HA_ST_READY|HA_ST_SEEK_COMPLETE|HA_ST_ERROR|HA_ST_DRQ)))
515 || (dpt_wait(sc, HA_ST_BUSY, 0, 2000))) {
516 /* RAID drives still spinning up? */
517 if((dpt_inb(sc, HA_ERROR) != 'D')
518 || (dpt_inb(sc, HA_ERROR + 1) != 'P')
519 || (dpt_inb(sc, HA_ERROR + 2) != 'T')) {
520 printf("%s: HBA not ready\n", sc->sc_dv.dv_xname);
521 return (-1);
522 }
523 }
524
525 /*
526 * Issue the read-config command and wait for the data to appear.
527 * XXX we shouldn't be doing this with PIO, but it makes it a lot
528 * easier as no DMA setup is required.
529 */
530 dpt_outb(sc, HA_COMMAND, CP_PIO_GETCFG);
531 memset(ec, 0, sizeof(*ec));
532 i = ((int)&((struct eata_cfg *)0)->ec_cfglen +
533 sizeof(ec->ec_cfglen)) >> 1;
534 p = (u_int16_t *)ec;
535
536 if (dpt_wait(sc, 0xFF, HA_ST_DATA_RDY, 2000)) {
537 printf("%s: cfg data didn't appear (status:%02x)\n",
538 sc->sc_dv.dv_xname, dpt_inb(sc, HA_STATUS));
539 return (-1);
540 }
541
542 /* Begin reading */
543 while (i--)
544 *p++ = dpt_inw(sc, HA_DATA);
545
546 if ((i = ec->ec_cfglen) > (sizeof(struct eata_cfg)
547 - (int)(&(((struct eata_cfg *)0L)->ec_cfglen))
548 - sizeof(ec->ec_cfglen)))
549 i = sizeof(struct eata_cfg)
550 - (int)(&(((struct eata_cfg *)0L)->ec_cfglen))
551 - sizeof(ec->ec_cfglen);
552
553 j = i + (int)(&(((struct eata_cfg *)0L)->ec_cfglen)) +
554 sizeof(ec->ec_cfglen);
555 i >>= 1;
556
557 while (i--)
558 *p++ = dpt_inw(sc, HA_DATA);
559
560 /* Flush until we have read 512 bytes. */
561 i = (512 - j + 1) >> 1;
562 while (i--)
563 dpt_inw(sc, HA_DATA);
564
565 /* Defaults for older Firmware */
566 if (p <= (u_short *)&ec->ec_hba[DPT_MAX_CHANNELS - 1])
567 ec->ec_hba[DPT_MAX_CHANNELS - 1] = 7;
568
569 if ((dpt_inb(sc, HA_STATUS) & HA_ST_ERROR) != 0) {
570 printf("%s: HBA error\n", sc->sc_dv.dv_xname);
571 return (-1);
572 }
573
574 if (!ec->ec_hbavalid) {
575 printf("%s: ec_hba field invalid\n", sc->sc_dv.dv_xname);
576 return (-1);
577 }
578
579 if (memcmp(ec->ec_eatasig, "EATA", 4) != 0) {
580 printf("%s: EATA signature mismatch\n", sc->sc_dv.dv_xname);
581 return (-1);
582 }
583
584 if (!ec->ec_dmasupported) {
585 printf("%s: DMA not supported\n", sc->sc_dv.dv_xname);
586 return (-1);
587 }
588
589 return (0);
590 }
591
592 /*
593 * Adjust the size of each I/O before it passes to the SCSI layer.
594 */
595 void
596 dpt_minphys(bp)
597 struct buf *bp;
598 {
599
600 if (bp->b_bcount > DPT_MAX_XFER)
601 bp->b_bcount = DPT_MAX_XFER;
602 minphys(bp);
603 }
604
605 /*
606 * Put a CCB onto the freelist.
607 */
608 void
609 dpt_free_ccb(sc, ccb)
610 struct dpt_softc *sc;
611 struct dpt_ccb *ccb;
612 {
613 int s;
614
615 s = splbio();
616 ccb->ccb_flg = 0;
617 TAILQ_INSERT_HEAD(&sc->sc_free_ccb, ccb, ccb_chain);
618
619 /* Wake anybody waiting for a free ccb */
620 if (ccb->ccb_chain.tqe_next == 0)
621 wakeup(&sc->sc_free_ccb);
622 splx(s);
623 }
624
625 /*
626 * Initialize the specified CCB.
627 */
628 int
629 dpt_init_ccb(sc, ccb)
630 struct dpt_softc *sc;
631 struct dpt_ccb *ccb;
632 {
633 int error;
634
635 /* Create the DMA map for this CCB's data */
636 error = bus_dmamap_create(sc->sc_dmat, DPT_MAX_XFER, DPT_SG_SIZE,
637 DPT_MAX_XFER, 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
638 &ccb->ccb_dmamap_xfer);
639
640 if (error) {
641 printf("%s: can't create ccb dmamap (%d)\n",
642 sc->sc_dv.dv_xname, error);
643 return (error);
644 }
645
646 ccb->ccb_flg = 0;
647 ccb->ccb_ccbpa = sc->sc_dmamap_ccb->dm_segs[0].ds_addr +
648 CCB_OFF(sc, ccb);
649 return (0);
650 }
651
652 /*
653 * Create a set of CCBs and add them to the free list.
654 */
655 int
656 dpt_create_ccbs(sc, ccbstore, count)
657 struct dpt_softc *sc;
658 struct dpt_ccb *ccbstore;
659 int count;
660 {
661 struct dpt_ccb *ccb;
662 int i, error;
663
664 memset(ccbstore, 0, sizeof(struct dpt_ccb) * count);
665
666 for (i = 0, ccb = ccbstore; i < count; i++, ccb++) {
667 if ((error = dpt_init_ccb(sc, ccb)) != 0) {
668 printf("%s: unable to init ccb, error = %d\n",
669 sc->sc_dv.dv_xname, error);
670 break;
671 }
672 ccb->ccb_id = i;
673 TAILQ_INSERT_TAIL(&sc->sc_free_ccb, ccb, ccb_chain);
674 }
675
676 return (i);
677 }
678
679 /*
680 * Get a free ccb. If there are none, see if we can allocate a new one. If
681 * none are available right now and we are permitted to sleep, then wait
682 * until one becomes free, otherwise return an error.
683 */
684 struct dpt_ccb *
685 dpt_alloc_ccb(sc, flg)
686 struct dpt_softc *sc;
687 int flg;
688 {
689 struct dpt_ccb *ccb;
690 int s;
691
692 s = splbio();
693
694 for (;;) {
695 ccb = TAILQ_FIRST(&sc->sc_free_ccb);
696 if (ccb) {
697 TAILQ_REMOVE(&sc->sc_free_ccb, ccb, ccb_chain);
698 break;
699 }
700 if ((flg & XS_CTL_NOSLEEP) != 0) {
701 splx(s);
702 return (NULL);
703 }
704 tsleep(&sc->sc_free_ccb, PRIBIO, "dptccb", 0);
705 }
706
707 ccb->ccb_flg |= CCB_ALLOC;
708 splx(s);
709 return (ccb);
710 }
711
712 /*
713 * We have a CCB which has been processed by the HBA, now we look to see how
714 * the operation went. CCBs marked with CCB_PRIVATE are not automatically
715 * passed here by dpt_intr().
716 */
717 void
718 dpt_done_ccb(sc, ccb)
719 struct dpt_softc *sc;
720 struct dpt_ccb *ccb;
721 {
722 struct scsipi_sense_data *s1, *s2;
723 struct scsipi_xfer *xs;
724 bus_dma_tag_t dmat;
725
726 dmat = sc->sc_dmat;
727 xs = ccb->ccb_xs;
728
729 SC_DEBUG(xs->sc_link, SDEV_DB2, ("dpt_done_ccb\n"));
730
731 /*
732 * If we were a data transfer, unload the map that described the
733 * data buffer.
734 */
735 if (xs->datalen) {
736 bus_dmamap_sync(dmat, ccb->ccb_dmamap_xfer, 0,
737 ccb->ccb_dmamap_xfer->dm_mapsize,
738 (xs->xs_control & XS_CTL_DATA_IN) ? BUS_DMASYNC_POSTREAD :
739 BUS_DMASYNC_POSTWRITE);
740 bus_dmamap_unload(dmat, ccb->ccb_dmamap_xfer);
741 }
742
743 /*
744 * Otherwise, put the results of the operation into the xfer and
745 * call whoever started it.
746 */
747 #ifdef DIAGNOSTIC
748 if ((ccb->ccb_flg & CCB_ALLOC) == 0) {
749 panic("%s: done ccb not allocated!\n", sc->sc_dv.dv_xname);
750 return;
751 }
752 #endif
753
754 if (xs->error == XS_NOERROR) {
755 if (ccb->ccb_hba_status != HA_NO_ERROR) {
756 switch (ccb->ccb_hba_status) {
757 case HA_ERROR_SEL_TO:
758 xs->error = XS_SELTIMEOUT;
759 break;
760 case HA_ERROR_RESET:
761 xs->error = XS_RESET;
762 break;
763 default: /* Other scsi protocol messes */
764 printf("%s: HBA status %x\n",
765 sc->sc_dv.dv_xname, ccb->ccb_hba_status);
766 xs->error = XS_DRIVER_STUFFUP;
767 }
768 } else if (ccb->ccb_scsi_status != SCSI_OK) {
769 switch (ccb->ccb_scsi_status) {
770 case SCSI_CHECK:
771 s1 = &ccb->ccb_sense;
772 s2 = &xs->sense.scsi_sense;
773 *s2 = *s1;
774 xs->error = XS_SENSE;
775 break;
776 case SCSI_BUSY:
777 xs->error = XS_BUSY;
778 break;
779 default:
780 printf("%s: SCSI status %x\n",
781 sc->sc_dv.dv_xname, ccb->ccb_scsi_status);
782 xs->error = XS_DRIVER_STUFFUP;
783 }
784 } else
785 xs->resid = 0;
786
787 xs->status = ccb->ccb_scsi_status;
788 }
789
790 /* Free up the CCB and mark the command as done */
791 dpt_free_ccb(sc, ccb);
792 xs->xs_status |= XS_STS_DONE;
793 scsipi_done(xs);
794
795 /*
796 * If there are entries in the software queue, try to run the first
797 * one. We should be more or less guaranteed to succeed, since we
798 * just freed an CCB. NOTE: dpt_scsi_cmd() relies on our calling it
799 * with the first entry in the queue.
800 */
801 if ((xs = TAILQ_FIRST(&sc->sc_queue)) != NULL)
802 dpt_scsi_cmd(xs);
803 }
804
805 /*
806 * Start a SCSI command.
807 */
808 int
809 dpt_scsi_cmd(xs)
810 struct scsipi_xfer *xs;
811 {
812 int error, i, flags, s, fromqueue, dontqueue;
813 struct scsipi_link *sc_link;
814 struct dpt_softc *sc;
815 struct dpt_ccb *ccb;
816 struct eata_sg *sg;
817 struct eata_cp *cp;
818 bus_dma_tag_t dmat;
819 bus_dmamap_t xfer;
820
821 sc_link = xs->sc_link;
822 flags = xs->xs_control;
823 sc = sc_link->adapter_softc;
824 dmat = sc->sc_dmat;
825 fromqueue = 0;
826 dontqueue = 0;
827
828 SC_DEBUG(sc_link, SDEV_DB2, ("dpt_scsi_cmd\n"));
829
830 /* Protect the queue */
831 s = splbio();
832
833 /*
834 * If we're running the queue from dpt_done_ccb(), we've been called
835 * with the first queue entry as our argument.
836 */
837 if (xs == TAILQ_FIRST(&sc->sc_queue)) {
838 TAILQ_REMOVE(&sc->sc_queue, xs, adapter_q);
839 fromqueue = 1;
840 } else {
841 /* Cmds must be no more than 12 bytes for us */
842 if (xs->cmdlen > 12) {
843 splx(s);
844 xs->error = XS_DRIVER_STUFFUP;
845 return (COMPLETE);
846 }
847
848 /* XXX we can't reset devices just yet */
849 if ((flags & XS_CTL_RESET) != 0) {
850 xs->error = XS_DRIVER_STUFFUP;
851 return (COMPLETE);
852 }
853
854 /* Polled requests can't be queued for later */
855 dontqueue = flags & XS_CTL_POLL;
856
857 /* If there are jobs in the queue, run them first */
858 if (TAILQ_FIRST(&sc->sc_queue) != NULL) {
859 /*
860 * If we can't queue we abort, since we must
861 * preserve the queue order.
862 */
863 if (dontqueue) {
864 splx(s);
865 xs->error = XS_DRIVER_STUFFUP;
866 return (TRY_AGAIN_LATER);
867 }
868
869 /* Swap with the first queue entry. */
870 TAILQ_INSERT_TAIL(&sc->sc_queue, xs, adapter_q);
871 xs = TAILQ_FIRST(&sc->sc_queue);
872 TAILQ_REMOVE(&sc->sc_queue, xs, adapter_q);
873 fromqueue = 1;
874 }
875 }
876
877 /* Get a CCB */
878 if ((ccb = dpt_alloc_ccb(sc, flags)) == NULL) {
879 /* If we can't queue, we lose */
880 if (dontqueue) {
881 splx(s);
882 xs->error = XS_DRIVER_STUFFUP;
883 return (TRY_AGAIN_LATER);
884 }
885
886 /*
887 * Stuff request into the queue, in front if we came off
888 * it in the first place.
889 */
890 if (fromqueue)
891 TAILQ_INSERT_HEAD(&sc->sc_queue, xs, adapter_q);
892 else
893 TAILQ_INSERT_TAIL(&sc->sc_queue, xs, adapter_q);
894 splx(s);
895 return (SUCCESSFULLY_QUEUED);
896 }
897
898 splx(s);
899
900 ccb->ccb_xs = xs;
901 ccb->ccb_timeout = xs->timeout;
902
903 cp = &ccb->ccb_eata_cp;
904 memcpy(&cp->cp_scsi_cmd, xs->cmd, xs->cmdlen);
905 cp->cp_ccbid = ccb->ccb_id;
906 cp->cp_id = sc_link->scsipi_scsi.target;
907 cp->cp_lun = sc_link->scsipi_scsi.lun;
908 cp->cp_channel = sc_link->scsipi_scsi.channel;
909 cp->cp_senselen = sizeof(ccb->ccb_sense);
910 cp->cp_stataddr = SWAP32(sc->sc_sppa);
911 cp->cp_dispri = 1;
912 cp->cp_identify = 1;
913 cp->cp_autosense = 1;
914 cp->cp_datain = ((flags & XS_CTL_DATA_IN) != 0);
915 cp->cp_dataout = ((flags & XS_CTL_DATA_OUT) != 0);
916 cp->cp_interpret = (sc->sc_hbaid[sc_link->scsipi_scsi.channel] ==
917 sc_link->scsipi_scsi.target);
918
919 /* Synchronous xfers musn't write-back through the cache */
920 if (xs->bp != NULL && (xs->bp->b_flags & (B_ASYNC | B_READ)) == 0)
921 cp->cp_nocache = 1;
922 else
923 cp->cp_nocache = 0;
924
925 cp->cp_senseaddr = SWAP32(sc->sc_dmamap_ccb->dm_segs[0].ds_addr +
926 CCB_OFF(sc, ccb) + offsetof(struct dpt_ccb, ccb_sense));
927
928 if (xs->datalen) {
929 xfer = ccb->ccb_dmamap_xfer;
930 #ifdef TFS
931 if ((flags & XS_CTL_DATA_UIO) != 0) {
932 error = bus_dmamap_load_uio(dmat, xfer,
933 (struct uio *)xs->data, (flags & XS_CTL_NOSLEEP) ?
934 BUS_DMA_NOWAIT : BUS_DMA_WAITOK);
935 } else
936 #endif /*TFS */
937 {
938 error = bus_dmamap_load(dmat, xfer, xs->data,
939 xs->datalen, NULL, (flags & XS_CTL_NOSLEEP) ?
940 BUS_DMA_NOWAIT : BUS_DMA_WAITOK);
941 }
942
943 if (error) {
944 printf("%s: dpt_scsi_cmd: ", sc->sc_dv.dv_xname);
945 if (error == EFBIG)
946 printf("more than %d dma segs\n", DPT_SG_SIZE);
947 else
948 printf("error %d loading dma map\n", error);
949
950 xs->error = XS_DRIVER_STUFFUP;
951 dpt_free_ccb(sc, ccb);
952 return (COMPLETE);
953 }
954
955 bus_dmamap_sync(dmat, xfer, 0, xfer->dm_mapsize,
956 (flags & XS_CTL_DATA_IN) ? BUS_DMASYNC_PREREAD :
957 BUS_DMASYNC_PREWRITE);
958
959 /* Don't bother using scatter/gather for just 1 segment */
960 if (xfer->dm_nsegs == 1) {
961 cp->cp_dataaddr = SWAP32(xfer->dm_segs[0].ds_addr);
962 cp->cp_datalen = SWAP32(xfer->dm_segs[0].ds_len);
963 cp->cp_scatter = 0;
964 } else {
965 /*
966 * Load the hardware scatter/gather map with the
967 * contents of the DMA map.
968 */
969 sg = ccb->ccb_sg;
970 for (i = 0; i < xfer->dm_nsegs; i++, sg++) {
971 sg->sg_addr = SWAP32(xfer->dm_segs[i].ds_addr);
972 sg->sg_len = SWAP32(xfer->dm_segs[i].ds_len);
973 }
974 cp->cp_dataaddr = SWAP32(CCB_OFF(sc, ccb) +
975 sc->sc_dmamap_ccb->dm_segs[0].ds_addr +
976 offsetof(struct dpt_ccb, ccb_sg));
977 cp->cp_datalen = SWAP32(i * sizeof(struct eata_sg));
978 cp->cp_scatter = 1;
979 }
980 } else {
981 cp->cp_dataaddr = 0;
982 cp->cp_datalen = 0;
983 cp->cp_scatter = 0;
984 }
985
986 /* Sync up CCB and status packet */
987 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_ccb, CCB_OFF(sc, ccb),
988 sizeof(struct dpt_ccb), BUS_DMASYNC_PREWRITE);
989 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_ccb, sc->sc_spoff,
990 sizeof(struct eata_sp), BUS_DMASYNC_PREREAD);
991
992 /*
993 * Start the command. If we are polling on completion, mark it
994 * private so that dpt_intr/dpt_done_ccb don't recycle the CCB
995 * without us noticing.
996 */
997 if (dontqueue != 0)
998 ccb->ccb_flg |= CCB_PRIVATE;
999
1000 if (dpt_cmd(sc, &ccb->ccb_eata_cp, ccb->ccb_ccbpa, CP_DMA_CMD, 0)) {
1001 printf("%s: dpt_cmd failed\n", sc->sc_dv.dv_xname);
1002 xs->error = XS_DRIVER_STUFFUP;
1003 dpt_free_ccb(sc, ccb);
1004 return (TRY_AGAIN_LATER);
1005 }
1006
1007 if (dontqueue == 0)
1008 return (SUCCESSFULLY_QUEUED);
1009
1010 /* Don't wait longer than this single command wants to wait */
1011 if (dpt_poll(sc, ccb)) {
1012 dpt_timeout(ccb);
1013 /* Wait for abort to complete */
1014 if (dpt_poll(sc, ccb))
1015 dpt_timeout(ccb);
1016 }
1017
1018 dpt_done_ccb(sc, ccb);
1019 return (COMPLETE);
1020 }
1021
1022 /*
1023 * Specified CCB has timed out, abort it.
1024 */
1025 void
1026 dpt_timeout(arg)
1027 void *arg;
1028 {
1029 struct scsipi_link *sc_link;
1030 struct scsipi_xfer *xs;
1031 struct dpt_softc *sc;
1032 struct dpt_ccb *ccb;
1033 int s;
1034
1035 ccb = arg;
1036 xs = ccb->ccb_xs;
1037 sc_link = xs->sc_link;
1038 sc = sc_link->adapter_softc;
1039
1040 scsi_print_addr(sc_link);
1041 printf("timed out (status:%02x aux status:%02x)",
1042 dpt_inb(sc, HA_STATUS), dpt_inb(sc, HA_AUX_STATUS));
1043
1044 s = splbio();
1045
1046 if ((ccb->ccb_flg & CCB_ABORT) != 0) {
1047 /* Abort timed out, reset the HBA */
1048 printf(" AGAIN, resetting HBA\n");
1049 dpt_outb(sc, HA_COMMAND, CP_RESET);
1050 DELAY(750000);
1051 } else {
1052 /* Abort the operation that has timed out */
1053 printf("\n");
1054 ccb->ccb_xs->error = XS_TIMEOUT;
1055 ccb->ccb_timeout = DPT_ABORT_TIMEOUT;
1056 ccb->ccb_flg |= CCB_ABORT;
1057 /* Start the abort */
1058 if (dpt_cmd(sc, &ccb->ccb_eata_cp, ccb->ccb_ccbpa,
1059 CP_IMMEDIATE, CPI_SPEC_ABORT))
1060 printf("%s: dpt_cmd failed\n", sc->sc_dv.dv_xname);
1061 }
1062
1063 splx(s);
1064 }
1065
1066 #ifdef DEBUG
1067 /*
1068 * Dump the contents of an EATA status packet.
1069 */
1070 void
1071 dpt_dump_sp(sp)
1072 struct eata_sp *sp;
1073 {
1074 int i;
1075
1076 printf("\thba_status\t%02x\n", sp->sp_hba_status);
1077 printf("\tscsi_status\t%02x\n", sp->sp_scsi_status);
1078 printf("\tinv_residue\t%d\n", sp->sp_inv_residue);
1079 printf("\tccbid\t\t%d\n", sp->sp_ccbid);
1080 printf("\tid_message\t%d\n", sp->sp_id_message);
1081 printf("\tque_message\t%d\n", sp->sp_que_message);
1082 printf("\ttag_message\t%d\n", sp->sp_tag_message);
1083 printf("\tmessages\t");
1084
1085 for (i = 0; i < 9; i++)
1086 printf("%d ", sp->sp_messages[i]);
1087
1088 printf("\n");
1089 }
1090 #endif /* DEBUG */
1091
1092 /*
1093 * Get inquiry data from the adapter.
1094 */
1095 void
1096 dpt_hba_inquire(sc, ei)
1097 struct dpt_softc *sc;
1098 struct eata_inquiry_data **ei;
1099 {
1100 struct dpt_ccb *ccb;
1101 struct eata_cp *cp;
1102 bus_dma_tag_t dmat;
1103
1104 *ei = (struct eata_inquiry_data *)sc->sc_scr;
1105 dmat = sc->sc_dmat;
1106
1107 /* Get a CCB and mark as private */
1108 if ((ccb = dpt_alloc_ccb(sc, 0)) == NULL)
1109 panic("%s: no CCB for inquiry", sc->sc_dv.dv_xname);
1110
1111 ccb->ccb_flg |= CCB_PRIVATE;
1112 ccb->ccb_timeout = 200;
1113
1114 /* Put all the arguments into the CCB */
1115 cp = &ccb->ccb_eata_cp;
1116 cp->cp_ccbid = ccb->ccb_id;
1117 cp->cp_id = sc->sc_hbaid[0];
1118 cp->cp_lun = 0;
1119 cp->cp_channel = 0;
1120 cp->cp_senselen = sizeof(ccb->ccb_sense);
1121 cp->cp_stataddr = SWAP32(sc->sc_sppa);
1122 cp->cp_dispri = 1;
1123 cp->cp_identify = 1;
1124 cp->cp_autosense = 0;
1125 cp->cp_interpret = 1;
1126 cp->cp_nocache = 0;
1127 cp->cp_datain = 1;
1128 cp->cp_dataout = 0;
1129 cp->cp_senseaddr = 0;
1130 cp->cp_dataaddr = SWAP32(sc->sc_scrpa);
1131 cp->cp_datalen = SWAP32(sizeof(struct eata_inquiry_data));
1132 cp->cp_scatter = 0;
1133
1134 /* Put together the SCSI inquiry command */
1135 memset(&cp->cp_scsi_cmd, 0, 12); /* XXX */
1136 cp->cp_scsi_cmd = INQUIRY;
1137 cp->cp_len = sizeof(struct eata_inquiry_data);
1138
1139 /* Sync up CCB, status packet and scratch area */
1140 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_ccb, CCB_OFF(sc, ccb),
1141 sizeof(struct dpt_ccb), BUS_DMASYNC_PREWRITE);
1142 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_ccb, sc->sc_spoff,
1143 sizeof(struct eata_sp), BUS_DMASYNC_PREREAD);
1144 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_ccb, sc->sc_scroff,
1145 sizeof(struct eata_inquiry_data), BUS_DMASYNC_PREREAD);
1146
1147 /* Start the command and poll on completion */
1148 if (dpt_cmd(sc, &ccb->ccb_eata_cp, ccb->ccb_ccbpa, CP_DMA_CMD, 0))
1149 panic("%s: dpt_cmd failed", sc->sc_dv.dv_xname);
1150
1151 if (dpt_poll(sc, ccb))
1152 panic("%s: inquiry timed out", sc->sc_dv.dv_xname);
1153
1154 if (ccb->ccb_hba_status != HA_NO_ERROR ||
1155 ccb->ccb_scsi_status != SCSI_OK)
1156 panic("%s: inquiry failed (hba:%02x scsi:%02x",
1157 sc->sc_dv.dv_xname, ccb->ccb_hba_status,
1158 ccb->ccb_scsi_status);
1159
1160 /* Sync up the DMA map and free CCB, returning */
1161 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_ccb, sc->sc_scroff,
1162 sizeof(struct eata_inquiry_data), BUS_DMASYNC_POSTREAD);
1163 dpt_free_ccb(sc, ccb);
1164 }
1165