1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72 #include <sys/cdefs.h>
73 #ifdef __NetBSD__
74 __KERNEL_RCSID(0, "$NetBSD: dpt.c,v 1.12 1999/10/23 16:26:33 ad Exp $");
75 #endif
76
77 #include <sys/param.h>
78 #include <sys/systm.h>
79 #include <sys/kernel.h>
80 #include <sys/device.h>
81 #include <sys/queue.h>
82 #include <sys/proc.h>
83 #include <sys/buf.h>
84
85 #include <machine/endian.h>
86 #ifdef __NetBSD__
87 #include <machine/bswap.h>
88 #endif
89 #include <machine/bus.h>
90
91 #ifdef __NetBSD__
92 #include <dev/scsipi/scsi_all.h>
93 #include <dev/scsipi/scsipi_all.h>
94 #include <dev/scsipi/scsiconf.h>
95 #endif
96 #ifdef __OpenBSD__
97 #include <scsi/scsi_all.h>
98 #include <scsi/scsiconf.h>
99 #endif
100
101 #include <dev/ic/dptreg.h>
102 #include <dev/ic/dptvar.h>
103
104 #ifdef __OpenBSD__
105 static void dpt_enqueue(struct dpt_softc *, struct scsi_xfer *, int);
106 static struct scsi_xfer *dpt_dequeue(struct dpt_softc *);
107
108 struct cfdriver dpt_cd = {
109 NULL, "dpt", DV_DULL
110 };
111 #endif
112
113
114 #ifdef __NetBSD__
115 static struct scsipi_device dpt_dev = {
116 #endif
117 #ifdef __OpenBSD__
118 static struct scsi_device dpt_dev = {
119 #endif
120 NULL,
121 NULL,
122 NULL,
123 NULL,
124 };
125
126 #ifndef offsetof
127 #define offsetof(type, member) (int)((&((type *)0)->member))
128 #endif
129
130 static char *dpt_cname[] = {
131 "PM3334", "SmartRAID IV",
132 "PM3332", "SmartRAID IV",
133 "PM2144", "SmartCache IV",
134 "PM2044", "SmartCache IV",
135 "PM2142", "SmartCache IV",
136 "PM2042", "SmartCache IV",
137 "PM2041", "SmartCache IV",
138 "PM3224", "SmartRAID III",
139 "PM3222", "SmartRAID III",
140 "PM3021", "SmartRAID III",
141 "PM2124", "SmartCache III",
142 "PM2024", "SmartCache III",
143 "PM2122", "SmartCache III",
144 "PM2022", "SmartCache III",
145 "PM2021", "SmartCache III",
146 "SK2012", "SmartCache Plus",
147 "SK2011", "SmartCache Plus",
148 NULL, "unknown adapter, please report using sendbug(1)",
149 };
150
151
152
153
154 int
155 dpt_intr(xxx_sc)
156 void *xxx_sc;
157 {
158 struct dpt_softc *sc;
159 struct dpt_ccb *ccb;
160 struct eata_sp *sp;
161 static int moretimo;
162 int more;
163
164 sc = xxx_sc;
165 sp = sc->sc_statpack;
166
167 if (!sp) {
168 #ifdef DEBUG
169 printf("%s: premature intr (st:%02x aux:%02x)\n",
170 sc->sc_dv.dv_xname, dpt_inb(sc, HA_STATUS),
171 dpt_inb(sc, HA_AUX_STATUS));
172 #else
173 (void) dpt_inb(sc, HA_STATUS);
174 #endif
175 return (0);
176 }
177
178 more = 0;
179
180 #ifdef DEBUG
181 if ((dpt_inb(sc, HA_AUX_STATUS) & HA_AUX_INTR) == 0)
182 printf("%s: spurious intr\n", sc->sc_dv.dv_xname);
183 #endif
184
185
186 if (moretimo < DPT_MORE_TIMEOUT / 100)
187 moretimo = 0;
188
189 for (;;) {
190
191
192
193
194
195
196
197 if ((dpt_inb(sc, HA_AUX_STATUS) & HA_AUX_INTR) == 0) {
198 if (more != 0 && moretimo++ < DPT_MORE_TIMEOUT / 100) {
199 DELAY(10);
200 continue;
201 }
202 break;
203 }
204
205 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_ccb, sc->sc_spoff,
206 sizeof(struct eata_sp), BUS_DMASYNC_POSTREAD);
207
208 if (!sp) {
209 more = dpt_inb(sc, HA_STATUS) & HA_ST_MORE;
210
211
212 if (moretimo < DPT_MORE_TIMEOUT / 100)
213 moretimo = 0;
214 continue;
215 }
216
217
218 if (sp->sp_ccbid == -1) {
219 DELAY(50);
220 #ifdef DIAGNOSTIC
221 printf("%s: slow reset of HA_AUX_STATUS?",
222 sc->sc_dv.dv_xname);
223 #endif
224 if ((dpt_inb(sc, HA_AUX_STATUS) & HA_AUX_INTR) == 0)
225 return (0);
226 #ifdef DIAGNOSTIC
227 printf("%s: was a slow reset of HA_AUX_STATUS",
228 sc->sc_dv.dv_xname);
229 #endif
230
231 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_ccb,
232 sc->sc_spoff, sizeof(struct eata_sp),
233 BUS_DMASYNC_POSTREAD);
234 }
235
236
237 if (sp->sp_ccbid >= 0 && sp->sp_ccbid < sc->sc_nccbs) {
238
239 ccb = sc->sc_ccbs + sp->sp_ccbid;
240
241 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_ccb,
242 CCB_OFF(sc, ccb), sizeof(struct dpt_ccb),
243 BUS_DMASYNC_POSTWRITE);
244
245 ccb->ccb_hba_status = sp->sp_hba_status & 0x7F;
246 ccb->ccb_scsi_status = sp->sp_scsi_status;
247
248
249
250
251
252 sp->sp_ccbid = -1;
253 ccb->ccb_flg |= CCB_INTR;
254 more = dpt_inb(sc, HA_STATUS) & HA_ST_MORE;
255 if ((ccb->ccb_flg & CCB_PRIVATE) == 0)
256 dpt_done_ccb(sc, ccb);
257 } else {
258 printf("%s: bogus status (returned CCB id %d)\n",
259 sc->sc_dv.dv_xname, sp->sp_ccbid);
260
261
262 sp->sp_ccbid = -1;
263 more = dpt_inb(sc, HA_STATUS) & HA_ST_MORE;
264 }
265
266
267 if (moretimo < DPT_MORE_TIMEOUT / 100)
268 moretimo = 0;
269 }
270
271 return (0);
272 }
273
274
275
276
277
278 void
279 dpt_init(sc, intrstr)
280 struct dpt_softc *sc;
281 const char *intrstr;
282 {
283 struct eata_inquiry_data *ei;
284 int i, j, error, rseg, mapsize;
285 bus_dma_segment_t seg;
286 struct eata_cfg *ec;
287 char model[16];
288
289 ec = &sc->sc_ec;
290
291
292 sc->sc_nccbs = min(betoh16(*(int16_t *)ec->ec_queuedepth),
293 DPT_MAX_CCBS);
294 sc->sc_spoff = sc->sc_nccbs * sizeof(struct dpt_ccb);
295 sc->sc_scroff = sc->sc_spoff + sizeof(struct eata_sp);
296 sc->sc_scrlen = 256;
297 mapsize = sc->sc_nccbs * sizeof(struct dpt_ccb) + sc->sc_scrlen +
298 sizeof(struct eata_sp);
299
300 if ((error = bus_dmamem_alloc(sc->sc_dmat, mapsize, NBPG, 0,
301 &seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) {
302 printf("%s: unable to allocate CCBs, error = %d\n",
303 sc->sc_dv.dv_xname, error);
304 return;
305 }
306
307 if ((error = bus_dmamem_map(sc->sc_dmat, &seg, rseg, mapsize,
308 (caddr_t *)&sc->sc_ccbs, BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) != 0) {
309 printf("%s: unable to map CCBs, error = %d\n",
310 sc->sc_dv.dv_xname, error);
311 return;
312 }
313
314 if ((error = bus_dmamap_create(sc->sc_dmat, mapsize, mapsize, 1, 0,
315 BUS_DMA_NOWAIT, &sc->sc_dmamap_ccb)) != 0) {
316 printf("%s: unable to create CCB DMA map, error = %d\n",
317 sc->sc_dv.dv_xname, error);
318 return;
319 }
320
321 if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap_ccb,
322 sc->sc_ccbs, mapsize, NULL, BUS_DMA_NOWAIT)) != 0) {
323 printf("%s: unable to load CCB DMA map, error = %d\n",
324 sc->sc_dv.dv_xname, error);
325 return;
326 }
327
328 sc->sc_statpack = (struct eata_sp *)((caddr_t)sc->sc_ccbs +
329 sc->sc_spoff);
330 sc->sc_sppa = sc->sc_dmamap_ccb->dm_segs[0].ds_addr + sc->sc_spoff;
331 sc->sc_scr = (caddr_t)sc->sc_ccbs + sc->sc_scroff;
332 sc->sc_scrpa = sc->sc_dmamap_ccb->dm_segs[0].ds_addr + sc->sc_scroff;
333 sc->sc_statpack->sp_ccbid = -1;
334
335
336 TAILQ_INIT(&sc->sc_free_ccb);
337 i = dpt_create_ccbs(sc, sc->sc_ccbs, sc->sc_nccbs);
338
339 if (i == 0) {
340 printf("%s: unable to create CCBs\n", sc->sc_dv.dv_xname);
341 return;
342 } else if (i != sc->sc_nccbs) {
343 printf("%s: %d/%d CCBs created!\n", sc->sc_dv.dv_xname, i,
344 sc->sc_nccbs);
345 sc->sc_nccbs = i;
346 }
347
348
349 sc->sc_sdh = shutdownhook_establish(dpt_shutdown, sc);
350
351
352 dpt_hba_inquire(sc, &ei);
353
354
355
356
357
358
359 for (i = 0; ei->ei_vendor[i] != ' ' && i < 8; i++)
360 ;
361 ei->ei_vendor[i] = '\0';
362
363 for (i = 0; ei->ei_model[i] != ' ' && i < 7; i++)
364 model[i] = ei->ei_model[i];
365 for (j = 0; ei->ei_suffix[j] != ' ' && j < 7; j++)
366 model[i++] = ei->ei_suffix[j];
367 model[i] = '\0';
368
369
370 for (i = 0; dpt_cname[i] != NULL; i += 2)
371 if (memcmp(ei->ei_model, dpt_cname[i], 6) == 0)
372 break;
373
374 printf("%s %s (%s)\n", ei->ei_vendor, dpt_cname[i + 1], model);
375
376 if (intrstr != NULL)
377 printf("%s: interrupting at %s\n", sc->sc_dv.dv_xname, intrstr);
378
379 printf("%s: %d queued commands, %d channel(s), adapter on ID(s)",
380 sc->sc_dv.dv_xname, sc->sc_nccbs, ec->ec_maxchannel + 1);
381
382 for (i = 0; i <= ec->ec_maxchannel; i++)
383 printf(" %d", ec->ec_hba[3 - i]);
384 printf("\n");
385
386
387 if (dpt_cmd(sc, NULL, 0, CP_IMMEDIATE, CPI_BUS_RESET))
388 panic("%s: dpt_cmd failed", sc->sc_dv.dv_xname);
389 DELAY(20000);
390
391
392 #ifdef __NetBSD__
393 sc->sc_adapter.scsipi_cmd = dpt_scsi_cmd;
394 sc->sc_adapter.scsipi_minphys = dpt_minphys;
395 #endif
396 #ifdef __OpenBSD__
397 sc->sc_adapter.scsi_cmd = dpt_scsi_cmd;
398 sc->sc_adapter.scsi_minphys = dpt_minphys;
399 #endif
400
401 for (i = 0; i <= ec->ec_maxchannel; i++) {
402 #ifdef __NetBSD__
403 struct scsipi_link *link;
404 #endif
405 #ifdef __OpenBSD__
406 struct scsi_link *link;
407 #endif
408 sc->sc_hbaid[i] = ec->ec_hba[3 - i];
409 link = &sc->sc_link[i];
410 #ifdef __NetBSD__
411 link->scsipi_scsi.scsibus = i;
412 link->scsipi_scsi.adapter_target = sc->sc_hbaid[i];
413 link->scsipi_scsi.max_lun = ec->ec_maxlun;
414 link->scsipi_scsi.max_target = ec->ec_maxtarget;
415 link->type = BUS_SCSI;
416 #endif
417 #ifdef __OpenBSD__
418 link->scsibus = i;
419 link->adapter_target = sc->sc_hbaid[i];
420 link->luns = ec->ec_maxlun + 1;
421 link->adapter_buswidth = ec->ec_maxtarget + 1;
422 #endif
423 link->device = &dpt_dev;
424 link->adapter = &sc->sc_adapter;
425 link->adapter_softc = sc;
426 link->openings = sc->sc_nccbs;
427 config_found(&sc->sc_dv, link, scsiprint);
428 }
429 }
430
431
432
433
434
435 void
436 dpt_shutdown(xxx_sc)
437 void *xxx_sc;
438 {
439 struct dpt_softc *sc;
440
441 sc = xxx_sc;
442 printf("shutting down %s...", sc->sc_dv.dv_xname);
443 dpt_cmd(sc, NULL, 0, CP_IMMEDIATE, CPI_POWEROFF_WARN);
444 DELAY(5000*1000);
445 printf(" done\n");
446 }
447
448
449
450
451 int
452 dpt_cmd(sc, cp, addr, eatacmd, icmd)
453 struct dpt_softc *sc;
454 struct eata_cp *cp;
455 u_int32_t addr;
456 int eatacmd, icmd;
457 {
458 int i;
459
460 for (i = 20000; i; i--) {
461 if ((dpt_inb(sc, HA_AUX_STATUS) & HA_AUX_BUSY) == 0)
462 break;
463 DELAY(50);
464 }
465
466
467 if (i == 0) {
468 printf("%s: HBA timeout on EATA command issue; aborting\n",
469 sc->sc_dv.dv_xname);
470 return (-1);
471 }
472
473 if (cp == NULL)
474 addr = 0;
475
476 dpt_outb(sc, HA_DMA_BASE + 0, (u_int32_t)addr);
477 dpt_outb(sc, HA_DMA_BASE + 1, (u_int32_t)addr >> 8);
478 dpt_outb(sc, HA_DMA_BASE + 2, (u_int32_t)addr >> 16);
479 dpt_outb(sc, HA_DMA_BASE + 3, (u_int32_t)addr >> 24);
480
481 if (eatacmd == CP_IMMEDIATE) {
482 if (cp == NULL) {
483
484 dpt_outb(sc, HA_ICMD_CODE2, 0);
485 dpt_outb(sc, HA_ICMD_CODE1, 0);
486 }
487 dpt_outb(sc, HA_ICMD, icmd);
488 }
489
490 dpt_outb(sc, HA_COMMAND, eatacmd);
491 return (0);
492 }
493
494
495
496
497 int
498 dpt_wait(sc, mask, state, ms)
499 struct dpt_softc *sc;
500 u_int8_t mask, state;
501 int ms;
502 {
503
504 for (ms *= 10; ms; ms--) {
505 if ((dpt_inb(sc, HA_STATUS) & mask) == state)
506 return (0);
507 DELAY(100);
508 }
509 return (-1);
510 }
511
512
513
514
515
516
517
518
519 int
520 dpt_poll(sc, ccb)
521 struct dpt_softc *sc;
522 struct dpt_ccb *ccb;
523 {
524 int i;
525
526 #ifdef DEBUG
527 if ((ccb->ccb_flg & CCB_PRIVATE) == 0)
528 panic("dpt_poll: called for non-CCB_PRIVATE request");
529 #endif
530
531 if ((ccb->ccb_flg & CCB_INTR) != 0)
532 return (0);
533
534 for (i = ccb->ccb_timeout * 20; i; i--) {
535 if ((dpt_inb(sc, HA_AUX_STATUS) & HA_AUX_INTR) != 0)
536 dpt_intr(sc);
537 if ((ccb->ccb_flg & CCB_INTR) != 0)
538 return (0);
539 DELAY(50);
540 }
541 return (-1);
542 }
543
544
545
546
547 int
548 dpt_readcfg(sc)
549 struct dpt_softc *sc;
550 {
551 struct eata_cfg *ec;
552 int i, j, stat;
553 u_int16_t *p;
554
555 ec = &sc->sc_ec;
556
557
558 dpt_outb(sc, HA_COMMAND, CP_RESET);
559 DELAY(750000);
560
561 for (i = 1000; i; i--) {
562 if ((dpt_inb(sc, HA_STATUS) & HA_ST_READY) != 0)
563 break;
564 DELAY(2000);
565 }
566
567 if (i == 0) {
568 printf("%s: HBA not ready after reset: %02x\n",
569 sc->sc_dv.dv_xname, dpt_inb(sc, HA_STATUS));
570 return (-1);
571 }
572
573 while((((stat = dpt_inb(sc, HA_STATUS))
574 != (HA_ST_READY|HA_ST_SEEK_COMPLETE))
575 && (stat != (HA_ST_READY|HA_ST_SEEK_COMPLETE|HA_ST_ERROR))
576 && (stat != (HA_ST_READY|HA_ST_SEEK_COMPLETE|HA_ST_ERROR|HA_ST_DRQ)))
577 || (dpt_wait(sc, HA_ST_BUSY, 0, 2000))) {
578
579 if((dpt_inb(sc, HA_ERROR) != 'D')
580 || (dpt_inb(sc, HA_ERROR + 1) != 'P')
581 || (dpt_inb(sc, HA_ERROR + 2) != 'T')) {
582 printf("%s: HBA not ready\n", sc->sc_dv.dv_xname);
583 return (-1);
584 }
585 }
586
587
588
589
590
591
592 dpt_outb(sc, HA_COMMAND, CP_PIO_GETCFG);
593 memset(ec, 0, sizeof(*ec));
594 i = ((int)&((struct eata_cfg *)0)->ec_cfglen +
595 sizeof(ec->ec_cfglen)) >> 1;
596 p = (u_int16_t *)ec;
597
598 if (dpt_wait(sc, 0xFF, HA_ST_DATA_RDY, 2000)) {
599 printf("%s: cfg data didn't appear (status:%02x)\n",
600 sc->sc_dv.dv_xname, dpt_inb(sc, HA_STATUS));
601 return (-1);
602 }
603
604
605 while (i--)
606 *p++ = dpt_inw(sc, HA_DATA);
607
608 if ((i = ec->ec_cfglen) > (sizeof(struct eata_cfg)
609 - (int)(&(((struct eata_cfg *)0L)->ec_cfglen))
610 - sizeof(ec->ec_cfglen)))
611 i = sizeof(struct eata_cfg)
612 - (int)(&(((struct eata_cfg *)0L)->ec_cfglen))
613 - sizeof(ec->ec_cfglen);
614
615 j = i + (int)(&(((struct eata_cfg *)0L)->ec_cfglen)) +
616 sizeof(ec->ec_cfglen);
617 i >>= 1;
618
619 while (i--)
620 *p++ = dpt_inw(sc, HA_DATA);
621
622
623 i = (512 - j + 1) >> 1;
624 while (i--)
625 dpt_inw(sc, HA_DATA);
626
627
628 if (p <= (u_short *)&ec->ec_hba[DPT_MAX_CHANNELS - 1])
629 ec->ec_hba[DPT_MAX_CHANNELS - 1] = 7;
630
631 if ((dpt_inb(sc, HA_STATUS) & HA_ST_ERROR) != 0) {
632 printf("%s: HBA error\n", sc->sc_dv.dv_xname);
633 return (-1);
634 }
635
636 if (!ec->ec_hbavalid) {
637 printf("%s: ec_hba field invalid\n", sc->sc_dv.dv_xname);
638 return (-1);
639 }
640
641 if (memcmp(ec->ec_eatasig, "EATA", 4) != 0) {
642 printf("%s: EATA signature mismatch\n", sc->sc_dv.dv_xname);
643 return (-1);
644 }
645
646 if (!ec->ec_dmasupported) {
647 printf("%s: DMA not supported\n", sc->sc_dv.dv_xname);
648 return (-1);
649 }
650
651 return (0);
652 }
653
654
655
656
657 void
658 dpt_minphys(bp)
659 struct buf *bp;
660 {
661
662 if (bp->b_bcount > DPT_MAX_XFER)
663 bp->b_bcount = DPT_MAX_XFER;
664 minphys(bp);
665 }
666
667
668
669
670 void
671 dpt_free_ccb(sc, ccb)
672 struct dpt_softc *sc;
673 struct dpt_ccb *ccb;
674 {
675 int s;
676
677 s = splbio();
678 ccb->ccb_flg = 0;
679 TAILQ_INSERT_HEAD(&sc->sc_free_ccb, ccb, ccb_chain);
680
681
682 if (TAILQ_NEXT(ccb, ccb_chain) == NULL)
683 wakeup(&sc->sc_free_ccb);
684 splx(s);
685 }
686
687
688
689
690 int
691 dpt_init_ccb(sc, ccb)
692 struct dpt_softc *sc;
693 struct dpt_ccb *ccb;
694 {
695 int error;
696
697
698 error = bus_dmamap_create(sc->sc_dmat, DPT_MAX_XFER, DPT_SG_SIZE,
699 DPT_MAX_XFER, 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
700 &ccb->ccb_dmamap_xfer);
701
702 if (error) {
703 printf("%s: can't create ccb dmamap (%d)\n",
704 sc->sc_dv.dv_xname, error);
705 return (error);
706 }
707
708 ccb->ccb_flg = 0;
709 ccb->ccb_ccbpa = sc->sc_dmamap_ccb->dm_segs[0].ds_addr +
710 CCB_OFF(sc, ccb);
711 return (0);
712 }
713
714
715
716
717 int
718 dpt_create_ccbs(sc, ccbstore, count)
719 struct dpt_softc *sc;
720 struct dpt_ccb *ccbstore;
721 int count;
722 {
723 struct dpt_ccb *ccb;
724 int i, error;
725
726 memset(ccbstore, 0, sizeof(struct dpt_ccb) * count);
727
728 for (i = 0, ccb = ccbstore; i < count; i++, ccb++) {
729 if ((error = dpt_init_ccb(sc, ccb)) != 0) {
730 printf("%s: unable to init ccb, error = %d\n",
731 sc->sc_dv.dv_xname, error);
732 break;
733 }
734 ccb->ccb_id = i;
735 TAILQ_INSERT_TAIL(&sc->sc_free_ccb, ccb, ccb_chain);
736 }
737
738 return (i);
739 }
740
741
742
743
744
745
746 struct dpt_ccb *
747 dpt_alloc_ccb(sc, flg)
748 struct dpt_softc *sc;
749 int flg;
750 {
751 struct dpt_ccb *ccb;
752 int s;
753
754 s = splbio();
755
756 for (;;) {
757 ccb = TAILQ_FIRST(&sc->sc_free_ccb);
758 if (ccb) {
759 TAILQ_REMOVE(&sc->sc_free_ccb, ccb, ccb_chain);
760 break;
761 }
762 #ifdef __NetBSD__
763 if ((flg & XS_CTL_NOSLEEP) != 0) {
764 #endif
765 #ifdef __OpenBSD__
766 if ((flg & SCSI_NOSLEEP) != 0) {
767 #endif
768 splx(s);
769 return (NULL);
770 }
771 tsleep(&sc->sc_free_ccb, PRIBIO, "dptccb", 0);
772 }
773
774 ccb->ccb_flg |= CCB_ALLOC;
775 splx(s);
776 return (ccb);
777 }
778
779
780
781
782
783
784 void
785 dpt_done_ccb(sc, ccb)
786 struct dpt_softc *sc;
787 struct dpt_ccb *ccb;
788 {
789 #ifdef __NetBSD__
790 struct scsipi_sense_data *s1, *s2;
791 struct scsipi_xfer *xs;
792 #endif
793 #ifdef __OpenBSD__
794 struct scsi_sense_data *s1, *s2;
795 struct scsi_xfer *xs;
796 #endif
797 bus_dma_tag_t dmat;
798
799 dmat = sc->sc_dmat;
800 xs = ccb->ccb_xs;
801
802 SC_DEBUG(xs->sc_link, SDEV_DB2, ("dpt_done_ccb\n"));
803
804
805
806
807
808 if (xs->datalen) {
809 bus_dmamap_sync(dmat, ccb->ccb_dmamap_xfer, 0,
810 ccb->ccb_dmamap_xfer->dm_mapsize,
811 (xs->flags & SCSI_DATA_IN) ? BUS_DMASYNC_POSTREAD :
812 BUS_DMASYNC_POSTWRITE);
813 bus_dmamap_unload(dmat, ccb->ccb_dmamap_xfer);
814 }
815
816
817
818
819
820 #ifdef DIAGNOSTIC
821 if ((ccb->ccb_flg & CCB_ALLOC) == 0) {
822 panic("%s: done ccb not allocated!", sc->sc_dv.dv_xname);
823 return;
824 }
825 #endif
826
827 if (xs->error == XS_NOERROR) {
828 if (ccb->ccb_hba_status != HA_NO_ERROR) {
829 switch (ccb->ccb_hba_status) {
830 case HA_ERROR_SEL_TO:
831 xs->error = XS_SELTIMEOUT;
832 break;
833 case HA_ERROR_RESET:
834 xs->error = XS_RESET;
835 break;
836 default:
837 printf("%s: HBA status %x\n",
838 sc->sc_dv.dv_xname, ccb->ccb_hba_status);
839 xs->error = XS_DRIVER_STUFFUP;
840 }
841 } else if (ccb->ccb_scsi_status != SCSI_OK) {
842 switch (ccb->ccb_scsi_status) {
843 case SCSI_CHECK:
844 s1 = &ccb->ccb_sense;
845 #ifdef __NetBSD__
846 s2 = &xs->sense.scsi_sense;
847 #endif
848 #ifdef __OpenBSD__
849 s2 = &xs->sense;
850 #endif
851 *s2 = *s1;
852 xs->error = XS_SENSE;
853 break;
854 case SCSI_BUSY:
855 xs->error = XS_BUSY;
856 break;
857 default:
858 printf("%s: SCSI status %x\n",
859 sc->sc_dv.dv_xname, ccb->ccb_scsi_status);
860 xs->error = XS_DRIVER_STUFFUP;
861 }
862 } else
863 xs->resid = 0;
864
865 xs->status = ccb->ccb_scsi_status;
866 }
867
868
869 dpt_free_ccb(sc, ccb);
870 #ifdef __NetBSD__
871 xs->xs_status |= XS_STS_DONE;
872 scsipi_done(xs);
873 #endif
874 #ifdef __OpenBSD__
875 xs->flags |= ITSDONE;
876 scsi_done(xs);
877 #endif
878
879
880
881
882
883
884
885 #ifdef __NetBSD__
886 if ((xs = TAILQ_FIRST(&sc->sc_queue)) != NULL)
887 #endif
888 #ifdef __OpenBSD__
889 if ((xs = LIST_FIRST(&sc->sc_queue)) != NULL)
890 #endif
891 dpt_scsi_cmd(xs);
892 }
893
894 #ifdef __OpenBSD__
895
896
897
898
899
900 static void
901 dpt_enqueue(sc, xs, infront)
902 struct dpt_softc *sc;
903 struct scsi_xfer *xs;
904 int infront;
905 {
906
907 if (infront || LIST_EMPTY(&sc->sc_queue)) {
908 if (LIST_EMPTY(&sc->sc_queue))
909 sc->sc_queuelast = xs;
910 LIST_INSERT_HEAD(&sc->sc_queue, xs, free_list);
911 return;
912 }
913 LIST_INSERT_AFTER(sc->sc_queuelast, xs, free_list);
914 sc->sc_queuelast = xs;
915 }
916
917
918
919
920 static struct scsi_xfer *
921 dpt_dequeue(sc)
922 struct dpt_softc *sc;
923 {
924 struct scsi_xfer *xs;
925
926 xs = LIST_FIRST(&sc->sc_queue);
927 LIST_REMOVE(xs, free_list);
928
929 if (LIST_EMPTY(&sc->sc_queue))
930 sc->sc_queuelast = NULL;
931
932 return (xs);
933 }
934 #endif
935
936
937
938
939 int
940 dpt_scsi_cmd(xs)
941 #ifdef __NetBSD__
942 struct scsipi_xfer *xs;
943 #endif
944 #ifdef __OpenBSD__
945 struct scsi_xfer *xs;
946 #endif
947 {
948 int error, i, flags, s, fromqueue, dontqueue;
949 #ifdef __NetBSD__
950 struct scsipi_link *sc_link;
951 #endif
952 #ifdef __OpenBSD__
953 struct scsi_link *sc_link;
954 #endif
955 struct dpt_softc *sc;
956 struct dpt_ccb *ccb;
957 struct eata_sg *sg;
958 struct eata_cp *cp;
959 bus_dma_tag_t dmat;
960 bus_dmamap_t xfer;
961
962 sc_link = xs->sc_link;
963 #ifdef __NetBSD__
964 flags = xs->xs_control;
965 #endif
966 #ifdef __OpenBSD__
967 flags = xs->flags;
968 #endif
969 sc = sc_link->adapter_softc;
970 dmat = sc->sc_dmat;
971 fromqueue = 0;
972 dontqueue = 0;
973
974 SC_DEBUG(sc_link, SDEV_DB2, ("dpt_scsi_cmd\n"));
975
976
977 s = splbio();
978
979
980
981
982
983 #ifdef __NetBSD__
984 if (xs == TAILQ_FIRST(&sc->sc_queue)) {
985 TAILQ_REMOVE(&sc->sc_queue, xs, adapter_q);
986 #endif
987 #ifdef __OpenBSD__
988 if (xs == LIST_FIRST(&sc->sc_queue)) {
989 xs = dpt_dequeue(sc);
990 #endif
991 fromqueue = 1;
992 } else {
993
994 if (xs->cmdlen > 12) {
995 splx(s);
996 xs->error = XS_DRIVER_STUFFUP;
997 return (COMPLETE);
998 }
999
1000
1001 #ifdef __NetBSD__
1002 if ((flags & XS_CTL_RESET) != 0) {
1003 #endif
1004 #ifdef __OpenBSD__
1005 if ((xs->flags & SCSI_RESET) != 0) {
1006 #endif
1007 splx(s);
1008 xs->error = XS_DRIVER_STUFFUP;
1009 return (COMPLETE);
1010 }
1011
1012
1013 #ifdef __NetBSD__
1014 dontqueue = flags & XS_CTL_POLL;
1015 #endif
1016 #ifdef __OpenBSD__
1017 dontqueue = xs->flags & SCSI_POLL;
1018 #endif
1019
1020
1021 #ifdef __NetBSD__
1022 if (TAILQ_FIRST(&sc->sc_queue) != NULL) {
1023 #endif
1024 #ifdef __OpenBSD__
1025 if (!LIST_EMPTY(&sc->sc_queue)) {
1026 #endif
1027
1028
1029
1030
1031 if (dontqueue) {
1032 splx(s);
1033 return (TRY_AGAIN_LATER);
1034 }
1035
1036
1037 #ifdef __NetBSD__
1038 TAILQ_INSERT_TAIL(&sc->sc_queue, xs, adapter_q);
1039 xs = TAILQ_FIRST(&sc->sc_queue);
1040 TAILQ_REMOVE(&sc->sc_queue, xs, adapter_q);
1041 #endif
1042 #ifdef __OpenBSD__
1043 dpt_enqueue(sc, xs, 0);
1044 xs = dpt_dequeue(sc);
1045 #endif
1046 fromqueue = 1;
1047 }
1048 }
1049
1050
1051 #ifdef __NetBSD__
1052 if ((ccb = dpt_alloc_ccb(sc, flags)) == NULL) {
1053 #endif
1054 #ifdef __OpenBSD__
1055 if ((ccb = dpt_alloc_ccb(sc, xs->flags)) == NULL) {
1056 #endif
1057
1058 if (dontqueue) {
1059 splx(s);
1060 return (TRY_AGAIN_LATER);
1061 }
1062
1063
1064
1065
1066
1067 #ifdef __NetBSD__
1068 if (fromqueue)
1069 TAILQ_INSERT_HEAD(&sc->sc_queue, xs, adapter_q);
1070 else
1071 TAILQ_INSERT_TAIL(&sc->sc_queue, xs, adapter_q);
1072 #endif
1073 #ifdef __OpenBSD__
1074 dpt_enqueue(sc, xs, fromqueue);
1075 #endif
1076 splx(s);
1077 return (SUCCESSFULLY_QUEUED);
1078 }
1079
1080 splx(s);
1081
1082 ccb->ccb_xs = xs;
1083 ccb->ccb_timeout = xs->timeout;
1084
1085 cp = &ccb->ccb_eata_cp;
1086 #ifdef __NetBSD__
1087 memcpy(&cp->cp_scsi_cmd, xs->cmd, xs->cmdlen);
1088 #endif
1089 #ifdef __OpenBSD__
1090 bcopy(xs->cmd, &cp->cp_scsi_cmd, xs->cmdlen);
1091 #endif
1092 cp->cp_ccbid = ccb->ccb_id;
1093 #ifdef __NetBSD__
1094 cp->cp_id = sc_link->scsipi_scsi.target;
1095 cp->cp_lun = sc_link->scsipi_scsi.lun;
1096 cp->cp_channel = sc_link->scsipi_scsi.channel;
1097 #endif
1098 #ifdef __OpenBSD__
1099 cp->cp_id = sc_link->target;
1100 cp->cp_lun = sc_link->lun;
1101 cp->cp_channel = sc_link->scsibus;
1102 #endif
1103 cp->cp_senselen = sizeof(ccb->ccb_sense);
1104 cp->cp_stataddr = htobe32(sc->sc_sppa);
1105 cp->cp_dispri = 1;
1106 cp->cp_identify = 1;
1107 cp->cp_autosense = 1;
1108 #ifdef __NetBSD__
1109 cp->cp_datain = ((flags & XS_CTL_DATA_IN) != 0);
1110 cp->cp_dataout = ((flags & XS_CTL_DATA_OUT) != 0);
1111 cp->cp_interpret = (sc->sc_hbaid[sc_link->scsipi_scsi.channel] ==
1112 sc_link->scsipi_scsi.target);
1113 #endif
1114 #ifdef __OpenBSD__
1115 cp->cp_datain = ((xs->flags & SCSI_DATA_IN) != 0);
1116 cp->cp_dataout = ((xs->flags & SCSI_DATA_OUT) != 0);
1117 cp->cp_interpret = (sc->sc_hbaid[sc_link->scsibus] == sc_link->target);
1118 #endif
1119
1120
1121 if (xs->bp != NULL && (xs->bp->b_flags & (B_ASYNC | B_READ)) == 0)
1122 cp->cp_nocache = 1;
1123 else
1124 cp->cp_nocache = 0;
1125
1126 cp->cp_senseaddr = htobe32(sc->sc_dmamap_ccb->dm_segs[0].ds_addr +
1127 CCB_OFF(sc, ccb) + offsetof(struct dpt_ccb, ccb_sense));
1128
1129 if (xs->datalen) {
1130 xfer = ccb->ccb_dmamap_xfer;
1131 #ifdef TFS
1132 #ifdef __NetBSD__
1133 if ((flags & XS_CTL_DATA_UIO) != 0) {
1134 error = bus_dmamap_load_uio(dmat, xfer,
1135 (struct uio *)xs->data, (flags & XS_CTL_NOSLEEP) ?
1136 BUS_DMA_NOWAIT : BUS_DMA_WAITOK);
1137 #endif
1138 #ifdef __OpenBSD__
1139 if ((xs->flags & SCSI_DATA_UIO) != 0) {
1140 error = bus_dmamap_load_uio(dmat, xfer,
1141 (xs->flags & SCSI_NOSLEEP) ?
1142 BUS_DMA_NOWAIT : BUS_DMA_WAITOK);
1143 #endif
1144 } else
1145 #endif
1146 {
1147 #ifdef __NetBSD__
1148 error = bus_dmamap_load(dmat, xfer, xs->data,
1149 xs->datalen, NULL, (flags & XS_CTL_NOSLEEP) ?
1150 BUS_DMA_NOWAIT : BUS_DMA_WAITOK);
1151 #endif
1152 #ifdef __OpenBSD__
1153 error = bus_dmamap_load(dmat, xfer, xs->data,
1154 xs->datalen, NULL, (xs->flags & SCSI_NOSLEEP) ?
1155 BUS_DMA_NOWAIT : BUS_DMA_WAITOK);
1156 #endif
1157 }
1158
1159 if (error) {
1160 printf("%s: dpt_scsi_cmd: ", sc->sc_dv.dv_xname);
1161 if (error == EFBIG)
1162 printf("more than %d dma segs\n", DPT_SG_SIZE);
1163 else
1164 printf("error %d loading dma map\n", error);
1165
1166 xs->error = XS_DRIVER_STUFFUP;
1167 dpt_free_ccb(sc, ccb);
1168 return (COMPLETE);
1169 }
1170
1171 bus_dmamap_sync(dmat, xfer, 0, xfer->dm_mapsize,
1172 (flags & SCSI_DATA_IN) ? BUS_DMASYNC_PREREAD :
1173 BUS_DMASYNC_PREWRITE);
1174
1175
1176 if (xfer->dm_nsegs == 1) {
1177 cp->cp_dataaddr = htobe32(xfer->dm_segs[0].ds_addr);
1178 cp->cp_datalen = htobe32(xfer->dm_segs[0].ds_len);
1179 cp->cp_scatter = 0;
1180 } else {
1181
1182
1183
1184
1185 sg = ccb->ccb_sg;
1186 for (i = 0; i < xfer->dm_nsegs; i++, sg++) {
1187 sg->sg_addr =
1188 htobe32(xfer->dm_segs[i].ds_addr);
1189 sg->sg_len =
1190 htobe32(xfer->dm_segs[i].ds_len);
1191 }
1192 cp->cp_dataaddr = htobe32(CCB_OFF(sc, ccb) +
1193 sc->sc_dmamap_ccb->dm_segs[0].ds_addr +
1194 offsetof(struct dpt_ccb, ccb_sg));
1195 cp->cp_datalen = htobe32(i * sizeof(struct eata_sg));
1196 cp->cp_scatter = 1;
1197 }
1198 } else {
1199 cp->cp_dataaddr = 0;
1200 cp->cp_datalen = 0;
1201 cp->cp_scatter = 0;
1202 }
1203
1204
1205 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_ccb, CCB_OFF(sc, ccb),
1206 sizeof(struct dpt_ccb), BUS_DMASYNC_PREWRITE);
1207 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_ccb, sc->sc_spoff,
1208 sizeof(struct eata_sp), BUS_DMASYNC_PREREAD);
1209
1210
1211
1212
1213
1214
1215 if (dontqueue != 0)
1216 ccb->ccb_flg |= CCB_PRIVATE;
1217
1218 if (dpt_cmd(sc, &ccb->ccb_eata_cp, ccb->ccb_ccbpa, CP_DMA_CMD, 0)) {
1219 printf("%s: dpt_cmd failed\n", sc->sc_dv.dv_xname);
1220 dpt_free_ccb(sc, ccb);
1221 return (TRY_AGAIN_LATER);
1222 }
1223
1224 if (dontqueue == 0)
1225 return (SUCCESSFULLY_QUEUED);
1226
1227
1228 if (dpt_poll(sc, ccb)) {
1229 dpt_timeout(ccb);
1230
1231 if (dpt_poll(sc, ccb))
1232 dpt_timeout(ccb);
1233 }
1234
1235 dpt_done_ccb(sc, ccb);
1236 return (COMPLETE);
1237 }
1238
1239
1240
1241
1242 void
1243 dpt_timeout(arg)
1244 void *arg;
1245 {
1246 #ifdef __NetBSD__
1247 struct scsipi_link *sc_link;
1248 struct scsipi_xfer *xs;
1249 #endif
1250 #ifdef __OpenBSD__
1251 struct scsi_link *sc_link;
1252 struct scsi_xfer *xs;
1253 #endif
1254 struct dpt_softc *sc;
1255 struct dpt_ccb *ccb;
1256 int s;
1257
1258 ccb = arg;
1259 xs = ccb->ccb_xs;
1260 sc_link = xs->sc_link;
1261 sc = sc_link->adapter_softc;
1262
1263 #ifdef __NetBSD__
1264 scsi_print_addr(sc_link);
1265 #endif
1266 #ifdef __OpenBSD__
1267 sc_print_addr(sc_link);
1268 #endif
1269 printf("timed out (status:%02x aux status:%02x)",
1270 dpt_inb(sc, HA_STATUS), dpt_inb(sc, HA_AUX_STATUS));
1271
1272 s = splbio();
1273
1274 if ((ccb->ccb_flg & CCB_ABORT) != 0) {
1275
1276 printf(" AGAIN, resetting HBA\n");
1277 dpt_outb(sc, HA_COMMAND, CP_RESET);
1278 DELAY(750000);
1279 } else {
1280
1281 printf("\n");
1282 ccb->ccb_xs->error = XS_TIMEOUT;
1283 ccb->ccb_timeout = DPT_ABORT_TIMEOUT;
1284 ccb->ccb_flg |= CCB_ABORT;
1285
1286 if (dpt_cmd(sc, &ccb->ccb_eata_cp, ccb->ccb_ccbpa,
1287 CP_IMMEDIATE, CPI_SPEC_ABORT))
1288 printf("%s: dpt_cmd failed\n", sc->sc_dv.dv_xname);
1289 }
1290
1291 splx(s);
1292 }
1293
1294 #ifdef DEBUG
1295
1296
1297
1298 void
1299 dpt_dump_sp(sp)
1300 struct eata_sp *sp;
1301 {
1302 int i;
1303
1304 printf("\thba_status\t%02x\n", sp->sp_hba_status);
1305 printf("\tscsi_status\t%02x\n", sp->sp_scsi_status);
1306 printf("\tinv_residue\t%d\n", sp->sp_inv_residue);
1307 printf("\tccbid\t\t%d\n", sp->sp_ccbid);
1308 printf("\tid_message\t%d\n", sp->sp_id_message);
1309 printf("\tque_message\t%d\n", sp->sp_que_message);
1310 printf("\ttag_message\t%d\n", sp->sp_tag_message);
1311 printf("\tmessages\t");
1312
1313 for (i = 0; i < 9; i++)
1314 printf("%d ", sp->sp_messages[i]);
1315
1316 printf("\n");
1317 }
1318 #endif
1319
1320
1321
1322
1323 void
1324 dpt_hba_inquire(sc, ei)
1325 struct dpt_softc *sc;
1326 struct eata_inquiry_data **ei;
1327 {
1328 struct dpt_ccb *ccb;
1329 struct eata_cp *cp;
1330 bus_dma_tag_t dmat;
1331
1332 *ei = (struct eata_inquiry_data *)sc->sc_scr;
1333 dmat = sc->sc_dmat;
1334
1335
1336 if ((ccb = dpt_alloc_ccb(sc, 0)) == NULL)
1337 panic("%s: no CCB for inquiry", sc->sc_dv.dv_xname);
1338
1339 ccb->ccb_flg |= CCB_PRIVATE;
1340 ccb->ccb_timeout = 200;
1341
1342
1343 cp = &ccb->ccb_eata_cp;
1344 cp->cp_ccbid = ccb->ccb_id;
1345 cp->cp_id = sc->sc_hbaid[0];
1346 cp->cp_lun = 0;
1347 cp->cp_channel = 0;
1348 cp->cp_senselen = sizeof(ccb->ccb_sense);
1349 cp->cp_stataddr = htobe32(sc->sc_sppa);
1350 cp->cp_dispri = 1;
1351 cp->cp_identify = 1;
1352 cp->cp_autosense = 0;
1353 cp->cp_interpret = 1;
1354 cp->cp_nocache = 0;
1355 cp->cp_datain = 1;
1356 cp->cp_dataout = 0;
1357 cp->cp_senseaddr = 0;
1358 cp->cp_dataaddr = htobe32(sc->sc_scrpa);
1359 cp->cp_datalen = htobe32(sizeof(struct eata_inquiry_data));
1360 cp->cp_scatter = 0;
1361
1362
1363 memset(&cp->cp_scsi_cmd, 0, 12);
1364 cp->cp_scsi_cmd = INQUIRY;
1365 cp->cp_len = sizeof(struct eata_inquiry_data);
1366
1367
1368 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_ccb, CCB_OFF(sc, ccb),
1369 sizeof(struct dpt_ccb), BUS_DMASYNC_PREWRITE);
1370 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_ccb, sc->sc_spoff,
1371 sizeof(struct eata_sp), BUS_DMASYNC_PREREAD);
1372 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_ccb, sc->sc_scroff,
1373 sizeof(struct eata_inquiry_data), BUS_DMASYNC_PREREAD);
1374
1375
1376 if (dpt_cmd(sc, &ccb->ccb_eata_cp, ccb->ccb_ccbpa, CP_DMA_CMD, 0))
1377 panic("%s: dpt_cmd failed", sc->sc_dv.dv_xname);
1378
1379 if (dpt_poll(sc, ccb))
1380 panic("%s: inquiry timed out", sc->sc_dv.dv_xname);
1381
1382 if (ccb->ccb_hba_status != HA_NO_ERROR ||
1383 ccb->ccb_scsi_status != SCSI_OK)
1384 panic("%s: inquiry failed (hba:%02x scsi:%02x",
1385 sc->sc_dv.dv_xname, ccb->ccb_hba_status,
1386 ccb->ccb_scsi_status);
1387
1388
1389 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_ccb, sc->sc_scroff,
1390 sizeof(struct eata_inquiry_data), BUS_DMASYNC_POSTREAD);
1391 dpt_free_ccb(sc, ccb);
1392 }