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