2 * Mylex MultiMaster (Buslogic BT-*) SCSI Host Adapter
3 * in both 24-bit and 32-bit mode.
4 * 24-bit mode works for Adaptec AHA-154xx series too.
7 * allocate more Ccb's as needed, up to NMbox-1;
8 * add nmbox and nccb to Ctlr struct for the above;
9 * 64-bit LUN/explicit wide support necessary?
13 #include "../port/lib.h"
18 #include "../port/pci.h"
20 #include "../port/error.h"
22 #include "../port/sd.h"
24 #define K2BPA(va, tbdf) PADDR(va)
25 #define BPA2K(pa, tbdf) KADDR(pa)
27 extern SDifc sdmylexifc;
29 enum { /* registers */
30 Rcontrol = 0x00, /* WO: control register */
31 Rstatus = 0x00, /* RO: status register */
32 Rcpr = 0x01, /* WO: command/parameter register */
33 Rdatain = 0x01, /* RO: data-in register */
34 Rinterrupt = 0x02, /* RO: interrupt register */
38 Rsbus = 0x10, /* SCSI Bus Reset */
39 Rint = 0x20, /* Interrupt Reset */
40 Rsoft = 0x40, /* Soft Reset */
41 Rhard = 0x80, /* Hard Reset */
45 Cmdinv = 0x01, /* Command Invalid */
46 Dirrdy = 0x04, /* Data In Register Ready */
47 Cprbsy = 0x08, /* Command/Parameter Register Busy */
48 Hardy = 0x10, /* Host Adapter Ready */
49 Inreq = 0x20, /* Initialisation Required */
50 Dfail = 0x40, /* Diagnostic Failure */
51 Dact = 0x80, /* Diagnostic Active */
55 Cinitialise = 0x01, /* Initialise Mailbox */
56 Cstart = 0x02, /* Start Mailbox Command */
57 Cinquiry = 0x04, /* Adapter Inquiry */
58 Ceombri = 0x05, /* Enable OMBR Interrupt */
59 Cinquire = 0x0B, /* Inquire Configuration */
60 Cextbios = 0x28, /* AHA-1542: extended BIOS info. */
61 Cmbienable = 0x29, /* AHA-1542: Mailbox interface enable */
62 Ciem = 0x81, /* Initialise Extended Mailbox */
63 Ciesi = 0x8D, /* Inquire Extended Setup Information */
64 Cerrm = 0x8F, /* Enable strict round-robin mode */
65 Cwide = 0x96, /* Wide CCB */
68 enum { /* Rinterrupt */
69 Imbl = 0x01, /* Incoming Mailbox Loaded */
70 Mbor = 0x02, /* Mailbox Out Ready */
71 Cmdc = 0x04, /* Command Complete */
72 Rsts = 0x08, /* SCSI Reset State */
73 Intv = 0x80, /* Interrupt Valid */
76 typedef struct Mbox24 Mbox24;
78 uchar code; /* action/completion code */
79 uchar ccb[3]; /* CCB pointer (MSB, ..., LSB) */
82 typedef struct Mbox32 Mbox32;
84 uchar ccb[4]; /* CCB pointer (LSB, ..., MSB) */
85 uchar btstat; /* BT-7[45]7[SD] status */
86 uchar sdstat; /* SCSI device status */
88 uchar code; /* action/completion code */
91 enum { /* mailbox commands */
92 Mbfree = 0x00, /* Mailbox not in use */
94 Mbostart = 0x01, /* Start a mailbox command */
95 Mboabort = 0x02, /* Abort a mailbox command */
97 Mbiok = 0x01, /* CCB completed without error */
98 Mbiabort = 0x02, /* CCB aborted at request of host */
99 Mbinx = 0x03, /* Aborted CCB not found */
100 Mbierror = 0x04, /* CCB completed with error */
103 typedef struct Ccb24 Ccb24;
104 typedef struct Ccb32 Ccb32;
105 typedef union Ccb Ccb;
107 typedef struct Ccb24 {
108 uchar opcode; /* Operation code */
109 uchar datadir; /* Data direction control */
110 uchar cdblen; /* Length of CDB */
111 uchar senselen; /* Length of sense area */
112 uchar datalen[3]; /* Data length (MSB, ..., LSB) */
113 uchar dataptr[3]; /* Data pointer (MSB, ..., LSB) */
114 uchar linkptr[3]; /* Link pointer (MSB, ..., LSB) */
115 uchar linkid; /* command linking identifier */
116 uchar btstat; /* BT-* adapter status */
117 uchar sdstat; /* SCSI device status */
118 uchar reserved[2]; /* */
119 uchar cs[12+0xFF]; /* Command descriptor block + Sense */
121 void* data; /* buffer if address > 24-bits */
124 int done; /* command completed */
126 Ccb* ccb; /* link on free list */
130 typedef struct Ccb32 {
131 uchar opcode; /* Operation code */
132 uchar datadir; /* Data direction control */
133 uchar cdblen; /* Length of CDB */
134 uchar senselen; /* Length of sense area */
135 uchar datalen[4]; /* Data length (LSB, ..., MSB) */
136 uchar dataptr[4]; /* Data pointer (LSB, ..., MSB) */
138 uchar btstat; /* BT-* adapter status */
139 uchar sdstat; /* SCSI device status */
140 uchar targetid; /* Target ID */
141 uchar luntag; /* LUN & tag */
142 uchar cdb[12]; /* Command descriptor block */
143 uchar ccbctl; /* CCB control */
144 uchar linkid; /* command linking identifier */
145 uchar linkptr[4]; /* Link pointer (LSB, ..., MSB) */
146 uchar senseptr[4]; /* Sense pointer (LSB, ..., MSB) */
147 uchar sense[0xFF]; /* Sense bytes */
150 int done; /* command completed */
152 Ccb* ccb; /* link on free list */
161 OInitiator = 0x00, /* initiator CCB */
162 Ordl = 0x03, /* initiator CCB with
163 * residual data length returned
168 CCBdatain = 0x08, /* inbound, length is checked */
169 CCBdataout = 0x10, /* outbound, length is checked */
173 Eok = 0x00, /* normal completion with no errors */
177 TagEnable = 0x20, /* Tag enable */
178 SQTag = 0x00, /* Simple Queue Tag */
179 HQTag = 0x40, /* Head of Queue Tag */
180 OQTag = 0x80, /* Ordered Queue Tag */
183 enum { /* CCB control */
184 NoDisc = 0x08, /* No disconnect */
185 NoUnd = 0x10, /* No underrrun error report */
186 NoData = 0x20, /* No data transfer */
187 NoStat = 0x40, /* No CCB status if zero */
188 NoIntr = 0x80, /* No Interrupts */
191 typedef struct Ctlr Ctlr;
193 int port; /* I/O port */
194 int id; /* adapter SCSI id */
195 int bus; /* 24 or 32 -bit */
209 void* mb; /* mailbox out + mailbox in */
210 int mbox; /* current mailbox out index into mb */
211 int mbix; /* current mailbox in index into mb */
214 Ccb* ccb; /* list of free Ccb's */
215 Ccb** cache; /* last completed Ccb */
219 * The number of mailboxes should be a multiple of 8 (4 for Mbox32)
220 * to ensure the boundary between the out and in mailboxes doesn't
221 * straddle a cache-line boundary.
222 * The number of Ccb's should be less than the number of mailboxes to
223 * ensure no queueing is necessary on mailbox allocation.
226 NMbox = 8*8, /* number of Mbox's */
227 NCcb = NMbox-1, /* number of Ccb's */
230 #define PADDR24(a, n) ((PADDR(a)+(n)) <= (1<<24))
233 ccbfree(Ctlr* ctlr, Ccb* ccb)
235 lock(&ctlr->ccblock);
237 ((Ccb24*)ccb)->ccb = ctlr->ccb;
239 ((Ccb32*)ccb)->ccb = ctlr->ccb;
243 unlock(&ctlr->ccblock);
247 ccbavailable(void* a)
249 return ((Ctlr*)a)->ccb != nil;
258 lock(&ctlr->ccblock);
259 if((ccb = ctlr->ccb) != nil){
261 ctlr->ccb = ((Ccb24*)ccb)->ccb;
263 ctlr->ccb = ((Ccb32*)ccb)->ccb;
264 unlock(&ctlr->ccblock);
268 unlock(&ctlr->ccblock);
271 qunlock(&ctlr->ccbq);
274 sleep(&ctlr->ccbr, ccbavailable, ctlr);
275 qunlock(&ctlr->ccbq);
285 return ((Ccb24*)arg)->done;
295 uchar *data, lun, *sense;
296 int d, n, btstat, sdstat, target;
298 ctlr = r->unit->dev->ctlr;
299 target = r->unit->subno;
300 lun = (r->cmd[1]>>5) & 0x07;
303 * Ctlr->cache holds the last completed Ccb for this target if it
304 * returned 'check condition'.
305 * If this command is a request-sense and there is valid sense data
306 * from the last completed Ccb, return it immediately.
308 lock(&ctlr->cachelock);
309 if((ccb = ctlr->cache[target]) != nil){
310 ctlr->cache[target] = nil;
312 && ccb->sdstat == SDcheck && lun == ((ccb->cs[1]>>5) & 0x07)){
313 unlock(&ctlr->cachelock);
315 sense = &ccb->cs[ccb->cdblen];
319 memmove(r->data, sense, n);
322 ccbfree(ctlr, (Ccb*)ccb);
326 unlock(&ctlr->cachelock);
328 ccb = ccballoc(ctlr);
331 * Check if the transfer is to memory above the 24-bit limit the
332 * controller can address. If it is, try to allocate a temporary
333 * buffer as a staging area.
336 if(n && !PADDR24(r->data, n)){
337 data = mallocz(n, 0);
338 if(data == nil || !PADDR24(data, n)){
343 ccbfree(ctlr, (Ccb*)ccb);
347 memmove(data, r->data, n);
358 ccb->datadir = (target<<5)|lun;
360 ccb->datadir |= CCBdataout|CCBdatain;
362 ccb->datadir |= CCBdatain;
364 ccb->datadir |= CCBdataout;
366 ccb->cdblen = r->clen;
367 ccb->senselen = 0xFF;
369 ccb->datalen[0] = n>>16;
370 ccb->datalen[1] = n>>8;
376 ccb->dataptr[0] = p>>16;
377 ccb->dataptr[1] = p>>8;
380 ccb->linkptr[0] = ccb->linkptr[1] = ccb->linkptr[2] = 0;
382 ccb->btstat = ccb->sdstat = 0;
383 ccb->reserved[0] = ccb->reserved[1] = 0;
385 memmove(ccb->cs, r->cmd, r->clen);
388 * There's one more mbox than there there is
389 * ccb so there is always one free.
391 lock(&ctlr->mboxlock);
400 if(ctlr->mbox >= NMbox)
404 * This command does not require Hardy
405 * and doesn't generate a Cmdc interrupt.
408 outb(ctlr->port+Rcpr, Cstart);
409 unlock(&ctlr->mboxlock);
412 * Wait for the request to complete and return the status.
413 * Since the buffer is not reference counted cannot return
414 * until the DMA is done writing into the buffer so the caller
415 * cannot free the buffer prematurely.
419 sleep(ccb, done24, ccb);
423 * Save the status and patch up the number of
424 * bytes actually transferred.
425 * There's a firmware bug on some 956C controllers
426 * which causes the return count from a successful
427 * READ CAPACITY not be updated, so fix it here.
429 sdstat = ccb->sdstat;
430 btstat = ccb->btstat;
432 d = ccb->datalen[0]<<16;
433 d |= ccb->datalen[1]<<8;
434 d |= ccb->datalen[2];
435 if(ccb->cs[0] == 0x25 && sdstat == SDok)
441 * Tidy things up if a staging area was used for the data,
443 if(ccb->data != nil){
444 if(sdstat == SDok && btstat == 0 && !r->write)
445 memmove(ccb->data, data, n);
451 * If there was a check-condition, save the
452 * ccb for a possible request-sense command.
454 if(sdstat == SDcheck){
455 if(r->flags & SDnosense){
456 lock(&ctlr->cachelock);
457 if(ctlr->cache[target])
458 ccbfree(ctlr, ctlr->cache[target]);
459 ctlr->cache[target] = (Ccb*)ccb;
460 unlock(&ctlr->cachelock);
463 sense = &ccb->cs[ccb->cdblen];
465 if(n > sizeof(r->sense)-1)
466 n = sizeof(r->sense)-1;
467 memmove(r->sense, sense, n);
468 r->flags |= SDvalidsense;
470 ccbfree(ctlr, (Ccb*)ccb);
481 mylex24interrupt(Ureg*, void* arg)
487 int port, rinterrupt, rstatus;
493 * Save and clear the interrupt(s). The only
494 * interrupts expected are Cmdc, which is ignored,
495 * and Imbl which means something completed.
496 * There's one spurious interrupt left over from
497 * initialisation, ignore it.
499 rinterrupt = inb(port+Rinterrupt);
500 rstatus = inb(port+Rstatus);
501 outb(port+Rcontrol, Rint);
502 if((rinterrupt & ~(Cmdc|Imbl)) != Intv && ctlr->spurious++)
503 print("%s: interrupt 0x%2.2ux\n",
504 ctlr->sdev->name, rinterrupt);
505 if((rinterrupt & Cmdc) && (rstatus & Cmdinv))
506 print("%s: command invalid\n", ctlr->sdev->name);
509 * Look for something in the mail.
510 * If there is, save the status, free the mailbox
511 * and wakeup whoever.
514 for(mbox = &mb[ctlr->mbix]; mbox->code; mbox = &mb[ctlr->mbix]){
515 pa = (mbox->ccb[0]<<16)|(mbox->ccb[1]<<8)|mbox->ccb[2];
516 ccb = BPA2K(pa, BUSUNKNOWN);
522 if(ctlr->mbix >= NMbox+NMbox)
530 return ((Ccb32*)arg)->done;
541 int d, n, btstat, sdstat, target;
543 ctlr = r->unit->dev->ctlr;
544 target = r->unit->subno;
545 lun = (r->cmd[1]>>5) & 0x07;
548 * Ctlr->cache holds the last completed Ccb for this target if it
549 * returned 'check condition'.
550 * If this command is a request-sense and there is valid sense data
551 * from the last completed Ccb, return it immediately.
553 lock(&ctlr->cachelock);
554 if((ccb = ctlr->cache[target]) != nil){
555 ctlr->cache[target] = nil;
557 && ccb->sdstat == SDcheck && lun == (ccb->luntag & 0x07)){
558 unlock(&ctlr->cachelock);
563 memmove(r->data, ccb->sense, n);
566 ccbfree(ctlr, (Ccb*)ccb);
570 unlock(&ctlr->cachelock);
572 ccb = ccballoc(ctlr);
581 ccb->datadir = CCBdataout|CCBdatain;
583 ccb->datadir = CCBdatain;
585 ccb->datadir = CCBdataout;
587 ccb->cdblen = r->clen;
590 ccb->datalen[1] = n>>8;
591 ccb->datalen[2] = n>>16;
592 ccb->datalen[3] = n>>24;
598 ccb->dataptr[1] = p>>8;
599 ccb->dataptr[2] = p>>16;
600 ccb->dataptr[3] = p>>24;
602 ccb->targetid = target;
604 if(r->unit->inquiry[7] & 0x02)
606 ccb->datadir |= SQTag|TagEnable;
608 ccb->luntag |= SQTag|TagEnable;
609 memmove(ccb->cdb, r->cmd, r->clen);
610 ccb->btstat = ccb->sdstat = 0;
614 * There's one more mbox than there there is
615 * ccb so there is always one free.
617 lock(&ctlr->mboxlock);
627 if(ctlr->mbox >= NMbox)
631 * This command does not require Hardy
632 * and doesn't generate a Cmdc interrupt.
635 outb(ctlr->port+Rcpr, Cstart);
636 unlock(&ctlr->mboxlock);
639 * Wait for the request to complete and return the status.
640 * Since the buffer is not reference counted cannot return
641 * until the DMA is done writing into the buffer so the caller
642 * cannot free the buffer prematurely.
646 sleep(ccb, done32, ccb);
650 * Save the status and patch up the number of
651 * bytes actually transferred.
652 * There's a firmware bug on some 956C controllers
653 * which causes the return count from a successful
654 * READ CAPACITY not to be updated, so fix it here.
656 sdstat = ccb->sdstat;
657 btstat = ccb->btstat;
660 d |= (ccb->datalen[1]<<8);
661 d |= (ccb->datalen[2]<<16);
662 d |= (ccb->datalen[3]<<24);
663 if(ccb->cdb[0] == 0x25 && sdstat == SDok)
669 * If there was a check-condition, save the
670 * ccb for a possible request-sense command.
672 if(sdstat == SDcheck){
673 if(r->flags & SDnosense){
674 lock(&ctlr->cachelock);
675 if(ctlr->cache[target])
676 ccbfree(ctlr, ctlr->cache[target]);
677 ctlr->cache[target] = (Ccb*)ccb;
678 unlock(&ctlr->cachelock);
682 if(n > sizeof(r->sense)-1)
683 n = sizeof(r->sense)-1;
684 memmove(r->sense, ccb->sense, n);
685 r->flags |= SDvalidsense;
687 ccbfree(ctlr, (Ccb*)ccb);
698 mylex32interrupt(Ureg*, void* arg)
704 int port, rinterrupt, rstatus;
710 * Save and clear the interrupt(s). The only
711 * interrupts expected are Cmdc, which is ignored,
712 * and Imbl which means something completed.
713 * There's one spurious interrupt left over from
714 * initialisation, ignore it.
715 * In order to share PCI IRQs, just ignore spurious interrupts.
717 rinterrupt = inb(port+Rinterrupt);
718 rstatus = inb(port+Rstatus);
719 outb(port+Rcontrol, Rint);
720 if(0 && (rinterrupt & ~(Cmdc|Imbl)) != Intv && ctlr->spurious++)
721 print("%s: interrupt 0x%2.2ux\n",
722 ctlr->sdev->name, rinterrupt);
723 if((rinterrupt & Cmdc) && (rstatus & Cmdinv))
724 print("%s: command invalid\n", ctlr->sdev->name);
727 * Look for something in the mail.
728 * If there is, free the mailbox and wakeup whoever.
731 for(mbox = &mb[ctlr->mbix]; mbox->code; mbox = &mb[ctlr->mbix]){
732 pa = (mbox->ccb[3]<<24)
737 ccb = BPA2K(pa, ctlr->pcidev->tbdf);
739 ccb = BPA2K(pa, BUSUNKNOWN);
745 if(ctlr->mbix >= NMbox+NMbox)
756 subno = r->unit->subno;
757 ctlr = r->unit->dev->ctlr;
758 if(subno == ctlr->id || (!ctlr->wide && subno >= 8))
759 r->status = SDtimeout;
760 else if(ctlr->bus == 24)
761 r->status = mylex24rio(r);
763 r->status = mylex32rio(r);
768 * Issue a command to a controller. The command and its length is
769 * contained in cmd and cmdlen. If any data is to be
770 * returned, datalen should be non-zero, and the returned data
771 * will be placed in data.
772 * If Cmdc is set, bail out, the invalid command will be handled
773 * when the interrupt is processed.
776 issueio(int port, uchar* cmd, int cmdlen, uchar* data, int datalen)
780 if(cmd[0] != Cstart && cmd[0] != Ceombri){
781 while(!(inb(port+Rstatus) & Hardy))
784 outb(port+Rcpr, cmd[0]);
788 if(!(inb(port+Rstatus) & Cprbsy)){
789 outb(port+Rcpr, cmd[len]);
792 if(inb(port+Rinterrupt) & Cmdc)
798 while(len < datalen){
799 if(inb(port+Rstatus) & Dirrdy){
800 data[len] = inb(port+Rdatain);
803 if(inb(port+Rinterrupt) & Cmdc)
810 * Issue a command to a controller, wait for it to complete then
811 * try to reset the interrupt. Should only be called at initialisation.
814 issue(Ctlr* ctlr, uchar* cmd, int cmdlen, uchar* data, int datalen)
817 uchar rinterrupt, rstatus;
818 static Lock mylexissuelock;
822 ilock(&ctlr->issuelock);
823 issueio(port, cmd, cmdlen, data, datalen);
825 while(!((rinterrupt = inb(port+Rinterrupt)) & Cmdc))
828 rstatus = inb(port+Rstatus);
829 outb(port+Rcontrol, Rint);
830 iunlock(&ctlr->issuelock);
832 if((rinterrupt & Cmdc) && (rstatus & Cmdinv))
838 mylexprobe(int port, int irq)
842 uchar cmd[6], data[256];
843 int clen, dlen, timeo;
845 if(ioalloc(port, 0x3, 0, "mylex") < 0)
850 * Attempt to hard-reset the board and reset
851 * the SCSI bus. If the board state doesn't settle to
852 * idle with mailbox initialisation required, either
853 * it isn't a compatible board or it's broken.
854 * If the controller has SCAM set this can take a while.
856 if(getconf("*noscsireset") != nil)
857 outb(port+Rcontrol, Rhard);
859 outb(port+Rcontrol, Rhard|Rsbus);
860 for(timeo = 0; timeo < 100; timeo++){
861 if(inb(port+Rstatus) == (Inreq|Hardy))
865 if(inb(port+Rstatus) != (Inreq|Hardy)){
875 if((ctlr = malloc(sizeof(Ctlr))) == nil)
883 * Try to determine if this is a 32-bit MultiMaster controller
884 * by attempting to obtain the extended inquiry information;
885 * this command is not implemented on Adaptec 154xx
886 * controllers. If successful, the first byte of the returned
887 * data is the host adapter bus type, 'E' for 32-bit EISA,
894 if(issue(ctlr, cmd, clen, data, dlen)){
897 print("mylex ctlr @ port 0x%ux: 32-bit ", ctlr->port);
898 ctlr->wide = data[0x0D] & 0x01;
903 print("SCSI host adapter\n");
907 * Inconceivable though it may seem, a hard controller reset
908 * is necessary here to clear out the command queue. Every
909 * board seems to lock-up in a different way if you give an
910 * invalid command and then try to clear out the
911 * command/parameter and/or data-in register.
912 * Soft reset doesn't do the job either. Fortunately no
913 * serious initialisation has been done yet so there's nothing
916 outb(port+Rcontrol, Rhard);
917 for(timeo = 0; timeo < 100; timeo++){
918 if(inb(port+Rstatus) == (Inreq|Hardy))
922 if(inb(port+Rstatus) != (Inreq|Hardy))
927 * If the BIOS is enabled on the AHA-1542C/CF and BIOS options for
928 * support of drives > 1Gb, dynamic scanning of the SCSI bus or more
929 * than 2 drives under DOS 5.0 are enabled, the BIOS disables
930 * accepting Cmbinit to protect against running with drivers which
931 * don't support those options. In order to unlock the interface it
932 * is necessary to read a lock-code using Cextbios and write it back
933 * using Cmbienable; the lock-code is non-zero.
938 if(issue(ctlr, cmd, clen, data, dlen) == 0)
944 if(issue(ctlr, cmd, clen, data, dlen) == 0)
948 * Lock-code returned in data[1]. If it's non-zero write
949 * it back along with bit 0 of byte 0 cleared to enable
950 * mailbox initialisation.
957 if(issue(ctlr, cmd, clen, 0, 0) == 0)
963 * Get the id, DMA and IRQ info from the board. This will
964 * cause an interrupt which will hopefully not cause any
965 * trouble because the interrupt number isn't known yet.
966 * This is necessary as the DMA won't be set up if the
967 * board has the BIOS disabled.
969 * If the IRQ is already known, this must be a 32-bit PCI
970 * or EISA card, in which case the returned DMA and IRQ can
976 if(issue(ctlr, cmd, clen, data, dlen) == 0)
979 ctlr->id = data[2] & 0x07;
981 switch(data[0]){ /* DMA Arbitration Priority */
982 case 0x80: /* Channel 7 */
986 case 0x40: /* Channel 6 */
990 case 0x20: /* Channel 5 */
994 case 0x01: /* Channel 0 */
1004 switch(data[1]){ /* Interrupt Channel */
1028 if((sdev = malloc(sizeof(SDev))) == nil)
1030 sdev->ifc = &sdmylexifc;
1042 static int mylexport[8] = {
1043 0x330, 0x334, 0x230, 0x234, 0x130, 0x134, 0x000, 0x000,
1052 int cfg, ctlrno, i, x;
1053 SDev *sdev, *head, *tail;
1057 while(p = pcimatch(p, 0x104B, 0)){
1058 if((sdev = mylexprobe(p->mem[0].bar & ~3, p->intl)) == nil)
1071 if(strncmp(KADDR(0xFFFD9), "EISA", 4) == 0){
1072 for(cfg = 0x1000; cfg < MaxEISA*0x1000; cfg += 0x1000){
1074 for(i = 0; i < 4; i++)
1075 x |= inb(cfg+CfgEISA+i)<<(i*8);
1076 if(x != 0x0142B30A && x != 0x0242B30A)
1080 if((sdev = mylexprobe(mylexport[x & 0x07], -1)) == nil)
1091 for(ctlrno = 0; ctlrno < 4; ctlrno++){
1092 memset(&isa, 0, sizeof(isa));
1093 if(!isaconfig("scsi", ctlrno, &isa))
1095 if(strcmp(isa.type, "aha1542"))
1097 if((sdev = mylexprobe(isa.port, -1)) == nil)
1111 mylex24enable(Ctlr* ctlr)
1118 len = (sizeof(Mbox24)*NMbox*2)+(sizeof(Ccb24)*NCcb);
1119 v = xspanalloc(len, 32, 0);
1121 if(!PADDR24(ctlr, sizeof(Ctlr)) || !PADDR24(v, len))
1125 v += sizeof(Mbox24)*NMbox*2;
1128 for(ccbp = ccb; ccbp < &ccb[NCcb]; ccbp++){
1129 ccbp->ccb = ctlr->ccb;
1130 ctlr->ccb = (Ccb*)ccbp;
1134 * Initialise the software controller and
1135 * set the board scanning the mailboxes.
1139 cmd[0] = Cinitialise;
1141 p = K2BPA(ctlr->mb, BUSUNKNOWN);
1146 return issue(ctlr, cmd, 5, 0, 0);
1150 mylex32enable(Ctlr* ctlr)
1156 v = xspanalloc((sizeof(Mbox32)*NMbox*2)+(sizeof(Ccb32)*NCcb), 32, 0);
1159 v += sizeof(Mbox32)*NMbox*2;
1162 for(ccbp = ccb; ccbp < &ccb[NCcb]; ccbp++){
1164 * Fill in some stuff that doesn't change.
1166 ccbp->senselen = sizeof(ccbp->sense);
1167 p = PADDR(ccbp->sense);
1168 ccbp->senseptr[0] = p;
1169 ccbp->senseptr[1] = p>>8;
1170 ccbp->senseptr[2] = p>>16;
1171 ccbp->senseptr[3] = p>>24;
1173 ccbp->ccb = ctlr->ccb;
1174 ctlr->ccb = (Ccb*)ccbp;
1178 * Attempt wide mode setup.
1183 if(!issue(ctlr, cmd, 2, 0, 0)) {
1186 "mylex32enable: ctlr @ port 0x%ux: scsi wide-mode setup failed on wide host adapter",
1192 * Initialise the software controller and
1193 * set the board scanning the mailboxes.
1200 p = K2BPA(ctlr->mb, ctlr->tbdf);
1202 p = K2BPA(ctlr->mb, BUSUNKNOWN);
1208 return issue(ctlr, cmd, 6, 0, 0);
1212 mylexenable(SDev* sdev)
1216 void (*interrupt)(Ureg*, void*);
1220 if(ctlr->cache == nil){
1221 if((ctlr->cache = malloc(sdev->nunit*sizeof(Ccb*))) == nil)
1226 if(ctlr->bus == 32){
1228 tbdf = ctlr->pcidev->tbdf;
1229 pcisetbme(ctlr->pcidev);
1231 if(!mylex32enable(ctlr))
1233 interrupt = mylex32interrupt;
1235 else if(mylex24enable(ctlr))
1236 interrupt = mylex24interrupt;
1240 snprint(name, sizeof(name), "sd%c (%s)", sdev->idno, sdev->ifc->name);
1241 intrenable(ctlr->irq, interrupt, ctlr, tbdf, name);
1246 SDifc sdmylexifc = {
1251 mylexenable, /* enable */
1254 scsiverify, /* verify */
1255 scsionline, /* online */