12 extern SDifc sdataifc;
15 DbgCONFIG = 0x0001, /* detected drive config info */
16 DbgIDENTIFY = 0x0002, /* detected drive identify info */
17 DbgSTATE = 0x0004, /* dump state on panic */
18 DbgPROBE = 0x0008, /* trace device probing */
19 DbgDEBUG = 0x0080, /* the current problem... */
20 DbgINL = 0x0100, /* That Inil20+ message we hate */
21 Dbg48BIT = 0x0200, /* 48-bit LBA */
22 DbgBsy = 0x0400, /* interrupt but Bsy (shared IRQ) */
24 #define DEBUG (DbgDEBUG|DbgCONFIG)
26 enum { /* I/O ports */
28 Error = 1, /* (read) */
29 Features = 1, /* (write) */
30 Count = 2, /* sector count<7-0>, sector count<15-8> */
31 Ir = 2, /* interrupt reason (PACKET) */
32 Sector = 3, /* sector number */
33 Lbalo = 3, /* LBA<7-0>, LBA<31-24> */
34 Cyllo = 4, /* cylinder low */
35 Bytelo = 4, /* byte count low (PACKET) */
36 Lbamid = 4, /* LBA<15-8>, LBA<39-32> */
37 Cylhi = 5, /* cylinder high */
38 Bytehi = 5, /* byte count hi (PACKET) */
39 Lbahi = 5, /* LBA<23-16>, LBA<47-40> */
40 Dh = 6, /* Device/Head, LBA<32-14> */
41 Status = 7, /* (read) */
42 Command = 7, /* (write) */
44 As = 2, /* Alternate Status (read) */
45 Dc = 2, /* Device Control (write) */
49 Med = 0x01, /* Media error */
50 Ili = 0x01, /* command set specific (PACKET) */
51 Nm = 0x02, /* No Media */
52 Eom = 0x02, /* command set specific (PACKET) */
53 Abrt = 0x04, /* Aborted command */
54 Mcr = 0x08, /* Media Change Request */
55 Idnf = 0x10, /* no user-accessible address */
56 Mc = 0x20, /* Media Change */
57 Unc = 0x40, /* Uncorrectable data error */
58 Wp = 0x40, /* Write Protect */
59 Icrc = 0x80, /* Interface CRC error */
63 Dma = 0x01, /* data transfer via DMA (PACKET) */
64 Ovl = 0x02, /* command overlapped (PACKET) */
67 enum { /* Interrupt Reason */
68 Cd = 0x01, /* Command/Data */
69 Io = 0x02, /* I/O direction */
70 Rel = 0x04, /* Bus Release */
73 enum { /* Device/Head */
74 Dev0 = 0xA0, /* Master */
75 Dev1 = 0xB0, /* Slave */
76 Lba = 0x40, /* LBA mode */
79 enum { /* Status, Alternate Status */
80 Err = 0x01, /* Error */
81 Chk = 0x01, /* Check error (PACKET) */
82 Drq = 0x08, /* Data Request */
83 Dsc = 0x10, /* Device Seek Complete */
84 Serv = 0x10, /* Service */
85 Df = 0x20, /* Device Fault */
86 Dmrd = 0x20, /* DMA ready (PACKET) */
87 Drdy = 0x40, /* Device Ready */
88 Bsy = 0x80, /* Busy */
92 Cnop = 0x00, /* NOP */
93 Cdr = 0x08, /* Device Reset */
94 Crs = 0x20, /* Read Sectors */
95 Crs48 = 0x24, /* Read Sectors Ext */
96 Crd48 = 0x25, /* Read w/ DMA Ext */
97 Crdq48 = 0x26, /* Read w/ DMA Queued Ext */
98 Crsm48 = 0x29, /* Read Multiple Ext */
99 Cws = 0x30, /* Write Sectors */
100 Cws48 = 0x34, /* Write Sectors Ext */
101 Cwd48 = 0x35, /* Write w/ DMA Ext */
102 Cwdq48 = 0x36, /* Write w/ DMA Queued Ext */
103 Cwsm48 = 0x39, /* Write Multiple Ext */
104 Cedd = 0x90, /* Execute Device Diagnostics */
105 Cpkt = 0xA0, /* Packet */
106 Cidpkt = 0xA1, /* Identify Packet Device */
107 Crsm = 0xC4, /* Read Multiple */
108 Cwsm = 0xC5, /* Write Multiple */
109 Csm = 0xC6, /* Set Multiple */
110 Crdq = 0xC7, /* Read DMA queued */
111 Crd = 0xC8, /* Read DMA */
112 Cwd = 0xCA, /* Write DMA */
113 Cwdq = 0xCC, /* Write DMA queued */
114 Cstandby = 0xE2, /* Standby */
115 Cid = 0xEC, /* Identify Device */
116 Csf = 0xEF, /* Set Features */
119 enum { /* Device Control */
120 Nien = 0x02, /* (not) Interrupt Enable */
121 Srst = 0x04, /* Software Reset */
124 enum { /* PCI Configuration Registers */
125 Bmiba = 0x20, /* Bus Master Interface Base Address */
126 Idetim = 0x40, /* IE Timing */
127 Sidetim = 0x44, /* Slave IE Timing */
128 Udmactl = 0x48, /* Ultra DMA/33 Control */
129 Udmatim = 0x4A, /* Ultra DMA/33 Timing */
132 enum { /* Bus Master IDE I/O Ports */
133 Bmicx = 0, /* Command */
134 Bmisx = 2, /* Status */
135 Bmidtpx = 4, /* Descriptor Table Pointer */
139 Ssbm = 0x01, /* Start/Stop Bus Master */
140 Rwcon = 0x08, /* Read/Write Control */
144 Bmidea = 0x01, /* Bus Master IDE Active */
145 Idedmae = 0x02, /* IDE DMA Error (R/WC) */
146 Ideints = 0x04, /* IDE Interrupt Status (R/WC) */
147 Dma0cap = 0x20, /* Drive 0 DMA Capable */
148 Dma1cap = 0x40, /* Drive 0 DMA Capable */
150 enum { /* Physical Region Descriptor */
151 PrdEOT = 0x80000000, /* Bus Master IDE Active */
154 enum { /* offsets into the identify info. */
155 Iconfig = 0, /* general configuration */
156 Ilcyl = 1, /* logical cylinders */
157 Ilhead = 3, /* logical heads */
158 Ilsec = 6, /* logical sectors per logical track */
159 Iserial = 10, /* serial number */
160 Ifirmware = 23, /* firmware revision */
161 Imodel = 27, /* model number */
162 Imaxrwm = 47, /* max. read/write multiple sectors */
163 Icapabilities = 49, /* capabilities */
164 Istandby = 50, /* device specific standby timer */
165 Ipiomode = 51, /* PIO data transfer mode number */
167 Iccyl = 54, /* cylinders if (valid&0x01) */
168 Ichead = 55, /* heads if (valid&0x01) */
169 Icsec = 56, /* sectors if (valid&0x01) */
170 Iccap = 57, /* capacity if (valid&0x01) */
171 Irwm = 59, /* read/write multiple */
172 Ilba = 60, /* LBA size */
173 Imwdma = 63, /* multiword DMA mode */
174 Iapiomode = 64, /* advanced PIO modes supported */
175 Iminmwdma = 65, /* min. multiword DMA cycle time */
176 Irecmwdma = 66, /* rec. multiword DMA cycle time */
177 Iminpio = 67, /* min. PIO cycle w/o flow control */
178 Iminiordy = 68, /* min. PIO cycle with IORDY */
179 Ipcktbr = 71, /* time from PACKET to bus release */
180 Iserbsy = 72, /* time from SERVICE to !Bsy */
181 Iqdepth = 75, /* max. queue depth */
182 Imajor = 80, /* major version number */
183 Iminor = 81, /* minor version number */
184 Icsfs = 82, /* command set/feature supported */
185 Icsfe = 85, /* command set/feature enabled */
186 Iudma = 88, /* ultra DMA mode */
187 Ierase = 89, /* time for security erase */
188 Ieerase = 90, /* time for enhanced security erase */
189 Ipower = 91, /* current advanced power management */
190 Ilba48 = 100, /* 48-bit LBA size (64 bits in 100-103) */
191 Irmsn = 127, /* removable status notification */
192 Isecstat = 128, /* security status */
195 typedef struct Ctlr Ctlr;
196 typedef struct Drive Drive;
199 ulong pa; /* Physical Base Address */
204 Nprd = SDmaxio/(64*1024)+2,
207 typedef struct Ctlr {
214 void (*ienable)(Ctlr*);
219 Prd* prdt; /* physical region descriptor table */
221 // QLock; /* current command */
223 int command; /* last command issued (debugging) */
227 Lock; /* register access */
230 typedef struct Drive {
235 int c; /* cylinder */
238 vlong sectors; /* total */
239 int secsize; /* sector size */
241 // int dma; /* DMA R/W possible */
243 // int rwm; /* read/write multiple possible */
246 int pkt; /* PACKET device, length of pktcmd */
248 // int pktdma; /* this PACKET command using dma */
253 // QLock; /* drive access */
254 int command; /* current command */
259 int count; /* sectors */
260 int block; /* R/W bytes per block */
263 int flags; /* internal flags */
266 enum { /* internal flags */
267 Lba48 = 0x1, /* LBA48 mode */
268 Lba48always = 0x2, /* ... */
272 pc87415ienable(Ctlr* ctlr)
281 x = pcicfgr32(p, 0x40);
282 if(ctlr->cmdport == p->mem[0].bar)
286 pcicfgw32(p, 0x40, x);
290 atadebug(int cmdport, int ctlport, char* fmt, ...)
296 if(!(DEBUG & DbgPROBE)){
297 USED(cmdport, ctlport, fmt);
302 n = vseprint(buf, buf+sizeof(buf), fmt, arg) - buf;
308 n += snprint(buf+n, PRINTSIZE-n, " ataregs 0x%uX:",
310 for(i = Features; i < Command; i++)
311 n += snprint(buf+n, PRINTSIZE-n, " 0x%2.2uX",
314 n += snprint(buf+n, PRINTSIZE-n, " 0x%2.2uX",
316 n += snprint(buf+n, PRINTSIZE-n, "\n");
324 ataready(int cmdport, int ctlport, int dev, int reset, int ready, int micro)
328 atadebug(cmdport, ctlport, "ataready: dev %uX reset %uX ready %uX",
333 * Wait for the controller to become not busy and
334 * possibly for a status bit to become true (usually
335 * Drdy). Must change to the appropriate device
336 * register set if necessary before testing for ready.
337 * Always run through the loop at least once so it
338 * can be used as a test for !Bsy.
340 as = inb(ctlport+As);
345 outb(cmdport+Dh, dev);
348 else if(ready == 0 || (as & ready)){
349 atadebug(0, 0, "ataready: %d 0x%2.2uX\n", micro, as);
354 atadebug(0, 0, "ataready: %d 0x%2.2uX\n", micro, as);
359 atadebug(cmdport, ctlport, "ataready: timeout");
365 atacsfenabled(Drive* drive, vlong csf)
369 for(i = 0; i < 3; i++){
370 x = (csf>>(16*i)) & 0xFFFF;
373 cmdset = drive->info[Icsfe+i];
374 if(cmdset == 0 || cmdset == 0xFFFF)
384 atasf(int cmdport, int ctlport, int dev, uchar* command)
388 if(ataready(cmdport, ctlport, dev, Bsy|Drq, Drdy, 108*1000) < 0)
391 for(i = Features; i < Dh; i++)
392 outb(cmdport+i, command[i]);
393 outb(cmdport+Command, Csf);
395 as = ataready(cmdport, ctlport, 0, Bsy, Drdy|Df|Err, 109*1000);
396 if(as < 0 || (as & (Df|Err)))
403 ataidentify(int cmdport, int ctlport, int dev, int pkt, void* info)
405 int as, command, drdy;
415 as = ataready(cmdport, ctlport, dev, Bsy|Drq, drdy, 103*1000);
418 outb(cmdport+Command, command);
421 as = ataready(cmdport, ctlport, 0, Bsy, Drq|Err, 400*1000);
427 memset(info, 0, 512);
428 inss(cmdport+Data, info, 256);
431 if(DEBUG & DbgIDENTIFY){
436 for(i = 0; i < 256; i++){
439 print(" %4.4uX ", *sp);
449 atadrive(int cmdport, int ctlport, int dev)
456 atadebug(0, 0, "identify: port 0x%uX dev 0x%2.2uX\n", cmdport, dev);
459 as = ataidentify(cmdport, ctlport, dev, pkt, buf);
469 if((drive = malloc(sizeof(Drive))) == nil)
472 memmove(drive->info, buf, sizeof(drive->info));
473 drive->sense[0] = 0x70;
474 drive->sense[7] = sizeof(drive->sense)-7;
476 drive->inquiry[2] = 2;
477 drive->inquiry[3] = 2;
478 drive->inquiry[4] = sizeof(drive->inquiry)-4;
479 p = &drive->inquiry[8];
480 sp = &drive->info[Imodel];
481 for(i = 0; i < 20; i++){
486 drive->secsize = 512;
489 * Beware the CompactFlash Association feature set.
490 * Now, why this value in Iconfig just walks all over the bit
491 * definitions used in the other parts of the ATA/ATAPI standards
492 * is a mystery and a sign of true stupidity on someone's part.
493 * Anyway, the standard says if this value is 0x848A then it's
494 * CompactFlash and it's NOT a packet device.
496 iconfig = drive->info[Iconfig];
497 if(iconfig != 0x848A && (iconfig & 0xC000) == 0x8000){
504 if(drive->info[Ivalid] & 0x0001){
505 drive->c = drive->info[Iccyl];
506 drive->h = drive->info[Ichead];
507 drive->s = drive->info[Icsec];
510 drive->c = drive->info[Ilcyl];
511 drive->h = drive->info[Ilhead];
512 drive->s = drive->info[Ilsec];
514 if(drive->info[Icapabilities] & 0x0200){
515 if(drive->info[Icsfs+1] & 0x0400){
516 drive->sectors = drive->info[Ilba48]
517 |(drive->info[Ilba48+1]<<16)
518 |((vlong)drive->info[Ilba48+2]<<32);
519 drive->flags |= Lba48;
522 drive->sectors = (drive->info[Ilba+1]<<16)
528 drive->sectors = drive->c*drive->h*drive->s;
529 // atarwmmode(drive, cmdport, ctlport, dev);
531 // atadmamode(drive);
533 if(DEBUG & DbgCONFIG){
534 print("dev %2.2uX port %uX config %4.4uX capabilities %4.4uX",
535 dev, cmdport, iconfig, drive->info[Icapabilities]);
536 print(" mwdma %4.4uX", drive->info[Imwdma]);
537 if(drive->info[Ivalid] & 0x04)
538 print(" udma %4.4uX", drive->info[Iudma]);
539 // print(" dma %8.8uX rwm %ud", drive->dma, drive->rwm);
540 if(drive->flags&Lba48)
541 print("\tLLBA sectors %lld", drive->sectors);
552 * Srst is a big stick and may cause problems if further
553 * commands are tried before the drives become ready again.
554 * Also, there will be problems here if overlapped commands
555 * are ever supported.
558 outb(ctlport+Dc, Srst);
565 ataprobe(int cmdport, int ctlport, int irq)
570 int dev, error, rhi, rlo;
572 // if(ioalloc(cmdport, 8, 0, "atacmd") < 0)
574 // if(ioalloc(ctlport+As, 1, 0, "atactl") < 0){
580 * Try to detect a floating bus.
581 * Bsy should be cleared. If not, see if the cylinder registers
582 * are read/write capable.
583 * If the master fails, try the slave to catch slave-only
585 * There's no need to restore the tested registers as they will
586 * be reset on any detected drives by the Cedd command.
587 * All this indicates is that there is at least one drive on the
588 * controller; when the non-existent drive is selected in a
589 * single-drive configuration the registers of the existing drive
590 * are often seen, only command execution fails.
593 if(inb(ctlport+As) & Bsy){
594 outb(cmdport+Dh, dev);
597 atadebug(cmdport, ctlport, "ataprobe bsy");
598 outb(cmdport+Cyllo, 0xAA);
599 outb(cmdport+Cylhi, 0x55);
600 outb(cmdport+Sector, 0xFF);
601 rlo = inb(cmdport+Cyllo);
602 rhi = inb(cmdport+Cylhi);
603 if(rlo != 0xAA && (rlo == 0xFF || rhi != 0x55)){
607 // iofree(ctlport+As);
611 if(ataready(cmdport, ctlport, dev, Bsy, 0, 20*1000) < 0)
617 * Disable interrupts on any detected controllers.
619 outb(ctlport+Dc, Nien);
621 if(ataready(cmdport, ctlport, dev, Bsy|Drq, 0, 105*1000) < 0){
623 * There's something there, but it didn't come up clean,
624 * so try hitting it with a big stick. The timing here is
625 * wrong but this is a last-ditch effort and it sometimes
626 * gets some marginal hardware back online.
629 if(ataready(cmdport, ctlport, dev, Bsy|Drq, 0, 106*1000) < 0)
634 * Can only get here if controller is not busy.
635 * If there are drives Bsy will be set within 400nS,
636 * must wait 2mS before testing Status.
637 * Wait for the command to complete (6 seconds max).
639 outb(cmdport+Command, Cedd);
641 if(ataready(cmdport, ctlport, dev, Bsy|Drq, 0, 6*1000*1000) < 0)
645 * If bit 0 of the error register is set then the selected drive
646 * exists. This is enough to detect single-drive configurations.
647 * However, if the master exists there is no way short of executing
648 * a command to determine if a slave is present.
649 * It appears possible to get here testing Dev0 although it doesn't
650 * exist and the EDD won't take, so try again with Dev1.
652 error = inb(cmdport+Error);
653 atadebug(cmdport, ctlport, "ataprobe: dev %uX", dev);
654 if((error & ~0x80) != 0x01){
662 * At least one drive is known to exist, try to
663 * identify it. If that fails, don't bother checking
665 * If the one drive found is Dev0 and the EDD command
666 * didn't indicate Dev1 doesn't exist, check for it.
668 if((drive = atadrive(cmdport, ctlport, dev)) == nil)
670 if((ctlr = malloc(sizeof(Ctlr))) == nil){
674 if((sdev = malloc(sizeof(SDev))) == nil){
681 ctlr->drive[0] = drive;
684 * Always leave Dh pointing to a valid drive,
685 * otherwise a subsequent call to ataready on
686 * this controller may try to test a bogus Status.
687 * Ataprobe is the only place possibly invalid
688 * drives should be selected.
690 drive = atadrive(cmdport, ctlport, Dev1);
693 ctlr->drive[1] = drive;
696 outb(cmdport+Dh, Dev0);
702 ctlr->drive[1] = drive;
704 ctlr->cmdport = cmdport;
705 ctlr->ctlport = ctlport;
707 ctlr->tbdf = BUSUNKNOWN;
708 ctlr->command = Cedd; /* debugging */
710 sdev->ifc = &sdataifc;
719 atasetsense(Drive* drive, int status, int key, int asc, int ascq)
721 drive->sense[2] = key;
722 drive->sense[12] = asc;
723 drive->sense[13] = ascq;
729 atamodesense(Drive* drive, uchar* cmd)
734 * Fake a vendor-specific request with page code 0,
735 * return the drive info.
737 if((cmd[2] & 0x3F) != 0 && (cmd[2] & 0x3F) != 0x3F)
738 return atasetsense(drive, SDcheck, 0x05, 0x24, 0);
739 len = (cmd[7]<<8)|cmd[8];
742 if(len < 8+sizeof(drive->info))
743 return atasetsense(drive, SDcheck, 0x05, 0x1A, 0);
744 if(drive->data == nil || drive->dlen < len)
745 return atasetsense(drive, SDcheck, 0x05, 0x20, 1);
746 memset(drive->data, 0, 8);
747 drive->data[0] = sizeof(drive->info)>>8;
748 drive->data[1] = sizeof(drive->info);
749 memmove(drive->data+8, drive->info, sizeof(drive->info));
750 drive->data += 8+sizeof(drive->info);
756 atanop(Drive* drive, int subcommand)
759 int as, cmdport, ctlport, timeo;
762 * Attempt to abort a command by using NOP.
763 * In response, the drive is supposed to set Abrt
764 * in the Error register, set (Drdy|Err) in Status
765 * and clear Bsy when done. However, some drives
766 * (e.g. ATAPI Zip) just go Bsy then clear Status
767 * when done, hence the timeout loop only on Bsy
768 * and the forced setting of drive->error.
771 cmdport = ctlr->cmdport;
772 outb(cmdport+Features, subcommand);
773 outb(cmdport+Dh, drive->dev);
774 ctlr->command = Cnop; /* debugging */
775 outb(cmdport+Command, Cnop);
778 ctlport = ctlr->ctlport;
779 for(timeo = 0; timeo < 1000; timeo++){
780 as = inb(ctlport+As);
785 drive->error |= Abrt;
789 ataabort(Drive* drive, int dolock)
792 * If NOP is available (packet commands) use it otherwise
793 * must try a software reset.
797 if(atacsfenabled(drive, 0x0000000000004000LL))
800 atasrst(drive->ctlr->ctlport);
801 drive->error |= Abrt;
804 iunlock(drive->ctlr);
808 atapktiodone(void* arg)
810 return ((Ctlr*)arg)->done;
814 atapktinterrupt(Drive* drive)
820 cmdport = ctlr->cmdport;
821 switch(inb(cmdport+Ir) & (/*Rel|*/Io|Cd)){
823 outss(cmdport+Data, drive->pktcmd, drive->pkt/2);
827 len = (inb(cmdport+Bytehi)<<8)|inb(cmdport+Bytelo);
828 if(drive->data+len > drive->limit){
832 outss(cmdport+Data, drive->data, len/2);
837 len = (inb(cmdport+Bytehi)<<8)|inb(cmdport+Bytelo);
838 if(drive->data+len > drive->limit){
842 inss(cmdport+Data, drive->data, len/2);
848 // atadmainterrupt(drive, drive->dlen);
856 atapktio(Drive* drive, uchar* cmd, int clen)
859 int as, cmdport, ctlport, len, r;
861 if(cmd[0] == 0x5A && (cmd[2] & 0x3F) == 0)
862 return atamodesense(drive, cmd);
866 drive->command = Cpkt;
867 memmove(drive->pktcmd, cmd, clen);
868 memset(drive->pktcmd+clen, 0, drive->pkt-clen);
869 drive->limit = drive->data+drive->dlen;
872 cmdport = ctlr->cmdport;
873 ctlport = ctlr->ctlport;
877 as = ataready(cmdport, ctlport, drive->dev, Bsy|Drq, Drdy, 107*1000);
878 if(as < 0 || (as&Chk)){
884 // if(drive->dlen && drive->dmactl && !atadmasetup(drive, drive->dlen))
885 // drive->pktdma = Dma;
887 // drive->pktdma = 0;
889 outb(cmdport+Features, 0/*drive->pktdma*/);
890 outb(cmdport+Count, 0);
891 outb(cmdport+Sector, 0);
892 len = 16*drive->secsize;
893 outb(cmdport+Bytelo, len);
894 outb(cmdport+Bytehi, len>>8);
895 outb(cmdport+Dh, drive->dev);
897 ctlr->curdrive = drive;
898 ctlr->command = Cpkt; /* debugging */
900 // atadmastart(ctlr, drive->write);
901 outb(cmdport+Command, Cpkt);
903 if((drive->info[Iconfig] & 0x0060) != 0x0020){
905 as = ataready(cmdport, ctlport, 0, Bsy, Drq|Chk, 4*1000);
906 if(as < 0 || (as & (Bsy|Chk))){
907 drive->status = as<0 ? 0 : as;
908 ctlr->curdrive = nil;
912 atapktinterrupt(drive);
916 sleep(ctlr, atapktiodone, ctlr);
920 if(drive->status & Chk)
927 atageniodone(void* arg)
929 return ((Ctlr*)arg)->done;
932 static uchar cmd48[256] = {
944 atageniostart(Drive* drive, vlong lba)
948 int as, c, cmdport, ctlport, h, len, s, use48;
951 if((drive->flags&Lba48always) || (lba>>28) || drive->count > 256){
952 if(!(drive->flags & Lba48))
956 }else if(drive->dev & Lba){
957 c = (lba>>8) & 0xFFFF;
958 h = (lba>>24) & 0x0F;
962 if (drive->s == 0 || drive->h == 0)
963 panic("atageniostart: zero s or h");
964 c = lba/(drive->s*drive->h);
965 h = ((lba/drive->s) % drive->h);
966 s = (lba % drive->s) + 1;
970 cmdport = ctlr->cmdport;
971 ctlport = ctlr->ctlport;
972 if(ataready(cmdport, ctlport, drive->dev, Bsy|Drq, Drdy, 101*1000) < 0)
977 drive->block = drive->secsize;
979 drive->command = Cws;
981 drive->command = Crs;
983 drive->limit = drive->data + drive->count*drive->secsize;
984 cmd = drive->command;
986 outb(cmdport+Count, (drive->count>>8) & 0xFF);
987 outb(cmdport+Count, drive->count & 0XFF);
988 outb(cmdport+Lbalo, (lba>>24) & 0xFF);
989 outb(cmdport+Lbalo, lba & 0xFF);
990 outb(cmdport+Lbamid, (lba>>32) & 0xFF);
991 outb(cmdport+Lbamid, (lba>>8) & 0xFF);
992 outb(cmdport+Lbahi, (lba>>40) & 0xFF);
993 outb(cmdport+Lbahi, (lba>>16) & 0xFF);
994 outb(cmdport+Dh, drive->dev|Lba);
998 print("using 48-bit commands\n");
1000 outb(cmdport+Count, drive->count);
1001 outb(cmdport+Sector, s);
1002 outb(cmdport+Cyllo, c);
1003 outb(cmdport+Cylhi, c>>8);
1004 outb(cmdport+Dh, drive->dev|h);
1007 ctlr->curdrive = drive;
1008 ctlr->command = drive->command; /* debugging */
1009 outb(cmdport+Command, cmd);
1011 switch(drive->command){
1015 as = ataready(cmdport, ctlport, 0, Bsy, Drq|Err, 1000);
1016 if(as < 0 || (as & Err)){
1021 if(drive->data+len > drive->limit)
1022 len = drive->limit-drive->data;
1023 outss(cmdport+Data, drive->data, len/2);
1028 // atadmastart(ctlr, drive->write);
1037 atagenioretry(Drive* drive)
1039 return atasetsense(drive, SDcheck, 4, 8, drive->error);
1043 atagenio(Drive* drive, uchar* cmd, int)
1051 * Map SCSI commands into ATA commands for discs.
1052 * Fail any command with a LUN except INQUIRY which
1053 * will return 'logical unit not supported'.
1055 if((cmd[1]>>5) && cmd[0] != 0x12)
1056 return atasetsense(drive, SDcheck, 0x05, 0x25, 0);
1060 return atasetsense(drive, SDcheck, 0x05, 0x20, 0);
1062 case 0x00: /* test unit ready */
1065 case 0x03: /* request sense */
1066 if(cmd[4] < sizeof(drive->sense))
1069 len = sizeof(drive->sense);
1070 if(drive->data && drive->dlen >= len){
1071 memmove(drive->data, drive->sense, len);
1076 case 0x12: /* inquiry */
1077 if(cmd[4] < sizeof(drive->inquiry))
1080 len = sizeof(drive->inquiry);
1081 if(drive->data && drive->dlen >= len){
1082 memmove(drive->data, drive->inquiry, len);
1087 case 0x1B: /* start/stop unit */
1089 * NOP for now, can use the power management feature
1094 case 0x25: /* read capacity */
1095 if((cmd[1] & 0x01) || cmd[2] || cmd[3])
1096 return atasetsense(drive, SDcheck, 0x05, 0x24, 0);
1097 if(drive->data == nil || drive->dlen < 8)
1098 return atasetsense(drive, SDcheck, 0x05, 0x20, 1);
1100 * Read capacity returns the LBA of the last sector.
1102 len = drive->sectors-1;
1108 len = drive->secsize;
1116 case 0x9E: /* long read capacity */
1117 if((cmd[1] & 0x01) || cmd[2] || cmd[3])
1118 return atasetsense(drive, SDcheck, 0x05, 0x24, 0);
1119 if(drive->data == nil || drive->dlen < 8)
1120 return atasetsense(drive, SDcheck, 0x05, 0x20, 1);
1122 * Read capacity returns the LBA of the last sector.
1124 len = drive->sectors-1;
1134 len = drive->secsize;
1142 case 0x28: /* read */
1143 case 0x2A: /* write */
1147 return atamodesense(drive, cmd);
1151 lba = (cmd[2]<<24)|(cmd[3]<<16)|(cmd[4]<<8)|cmd[5];
1152 count = (cmd[7]<<8)|cmd[8];
1153 if(drive->data == nil)
1155 if (drive->secsize == 0)
1156 panic("atagenio: zero sector size");
1157 if(drive->dlen < count*drive->secsize)
1158 count = drive->dlen/drive->secsize;
1161 max = (drive->flags&Lba48) ? 65536 : 256;
1165 drive->count = count;
1166 if(atageniostart(drive, lba)){
1171 return atagenioretry(drive);
1174 tsleep(ctlr, atageniodone, ctlr, 10*1000);
1177 * What should the above timeout be? In
1178 * standby and sleep modes it could take as
1179 * long as 30 seconds for a drive to respond.
1180 * Very hard to get out of this cleanly.
1182 // atadumpstate(drive, cmd, lba, count);
1184 return atagenioretry(drive);
1187 if(drive->status & Err){
1189 return atasetsense(drive, SDcheck, 4, 8, drive->error);
1191 count -= drive->count;
1192 lba += drive->count;
1205 uchar cmd10[10], *cmdp, *p;
1206 int clen, reqstatus, status;
1209 if((ctlr = unit->dev->ctlr) == nil || ctlr->drive[unit->subno] == nil){
1210 r->status = SDtimeout;
1213 drive = ctlr->drive[unit->subno];
1216 * Most SCSI commands can be passed unchanged except for
1217 * the padding on the end. The few which require munging
1218 * are not used internally. Mode select/sense(6) could be
1219 * converted to the 10-byte form but it's not worth the
1220 * effort. Read/write(6) are easy.
1223 case 0x08: /* read */
1224 case 0x0A: /* write */
1226 memset(cmdp, 0, sizeof(cmd10));
1227 cmdp[0] = r->cmd[0]|0x20;
1228 cmdp[1] = r->cmd[1] & 0xE0;
1229 cmdp[5] = r->cmd[3];
1230 cmdp[4] = r->cmd[2];
1231 cmdp[3] = r->cmd[1] & 0x0F;
1232 cmdp[8] = r->cmd[4];
1233 clen = sizeof(cmd10);
1243 drive->write = r->write;
1244 drive->data = r->data;
1245 drive->dlen = r->dlen;
1250 status = atapktio(drive, cmdp, clen);
1252 status = atagenio(drive, cmdp, clen);
1254 atasetsense(drive, SDok, 0, 0, 0);
1257 r->rlen = drive->data - p;
1262 else if(status == SDcheck && !(r->flags & SDnosense)){
1264 memset(cmd10, 0, sizeof(cmd10));
1266 cmd10[1] = r->lun<<5;
1267 cmd10[4] = sizeof(r->sense)-1;
1268 drive->data = r->sense;
1269 drive->dlen = sizeof(r->sense)-1;
1273 reqstatus = atapktio(drive, cmd10, 6);
1275 reqstatus = atagenio(drive, cmd10, 6);
1276 if(reqstatus == SDok){
1277 r->flags |= SDvalidsense;
1278 atasetsense(drive, SDok, 0, 0, 0);
1287 * Fix up any results.
1288 * Many ATAPI CD-ROMs ignore the LUN field completely and
1289 * return valid INQUIRY data. Patch the response to indicate
1290 * 'logical unit not supported' if the LUN is non-zero.
1293 case 0x12: /* inquiry */
1294 if((p = r->data) == nil)
1296 if((cmdp[1]>>5) && (!drive->pkt || (p[0] & 0x1F) == 0x05))
1307 atainterrupt(Ureg*, void* arg)
1311 int cmdport, len, status;
1316 if(inb(ctlr->ctlport+As) & Bsy){
1322 cmdport = ctlr->cmdport;
1323 status = inb(cmdport+Status);
1324 if((drive = ctlr->curdrive) == nil){
1326 if((DEBUG & DbgINL) && ctlr->command != Cedd)
1327 print("Inil%2.2uX+", ctlr->command);
1332 drive->error = inb(cmdport+Error);
1333 else switch(drive->command){
1335 drive->error = Abrt;
1340 if(!(status & Drq)){
1341 drive->error = Abrt;
1345 if(drive->data+len > drive->limit)
1346 len = drive->limit-drive->data;
1347 inss(cmdport+Data, drive->data, len/2);
1349 if(drive->data >= drive->limit)
1356 if(drive->data+len > drive->limit)
1357 len = drive->limit-drive->data;
1359 if(drive->data >= drive->limit){
1363 if(!(status & Drq)){
1364 drive->error = Abrt;
1368 if(drive->data+len > drive->limit)
1369 len = drive->limit-drive->data;
1370 outss(cmdport+Data, drive->data, len/2);
1374 atapktinterrupt(drive);
1379 // atadmainterrupt(drive, drive->count*drive->secsize);
1390 ctlr->curdrive = nil;
1391 drive->status = status;
1401 int channel, ispc87415, pi, r;
1402 SDev *legacy[2], *sdev, *head, *tail;
1404 legacy[0] = legacy[1] = head = tail = nil;
1406 /* native access to disks seems to interfere with bios loading */
1410 if(sdev = ataprobe(0x1F0, 0x3F4, IrqATA0)){
1414 if(sdev = ataprobe(0x170, 0x374, IrqATA1)){
1424 while(p = pcimatch(p, 0, 0)){
1426 * Look for devices with the correct class and sub-class
1427 * code and known device and vendor ID; add native-mode
1428 * channels to the list to be probed, save info for the
1429 * compatibility mode channels.
1430 * Note that the legacy devices should not be considered
1431 * PCI devices by the interrupt controller.
1432 * For both native and legacy, save info for busmastering
1434 * Promise Ultra ATA/66 (PDC20262) appears to
1435 * 1) give a sub-class of 'other mass storage controller'
1436 * instead of 'IDE controller', regardless of whether it's
1437 * the only controller or not;
1438 * 2) put 0 in the programming interface byte (probably
1439 * as a consequence of 1) above).
1440 * Sub-class code 0x04 is 'RAID controller', e.g. VIA VT8237.
1444 if(p->ccru != 0x01 && p->ccru != 0x04 && p->ccru != 0x80)
1449 switch((p->did<<16)|p->vid){
1453 case (0x0002<<16)|0x100B: /* NS PC87415 */
1455 * Disable interrupts on both channels until
1456 * after they are probed for drives.
1457 * This must be called before interrupts are
1458 * enabled because the IRQ may be shared.
1461 pcicfgw32(p, 0x40, 0x00000300);
1463 case (0x1000<<16)|0x1042: /* PC-Tech RZ1000 */
1465 * Turn off prefetch. Overkill, but cheap.
1467 r = pcicfgr32(p, 0x40);
1469 pcicfgw32(p, 0x40, r);
1471 case (0x4D38<<16)|0x105A: /* Promise PDC20262 */
1472 case (0x4D30<<16)|0x105A: /* Promise PDC202xx */
1473 case (0x4D68<<16)|0x105A: /* Promise PDC20268 */
1474 case (0x4D69<<16)|0x105A: /* Promise Ultra/133 TX2 */
1475 case (0x3373<<16)|0x105A: /* Promise 20378 RAID */
1476 case (0x3149<<16)|0x1106: /* VIA VT8237 SATA/RAID */
1477 case (0x0680<<16)|0x1095: /* SiI 0680/680A PATA133 ATAPI/RAID */
1478 case (0x3112<<16)|0x1095: /* SiL 3112 SATA (DMA busted?) */
1479 case (0x3114<<16)|0x1095: /* SiL 3114 SATA/RAID */
1482 case (0x0004<<16)|0x1103: /* HighPoint HPT-370 */
1485 * Turn off fast interrupt prediction.
1487 if((r = pcicfgr8(p, 0x51)) & 0x80)
1488 pcicfgw8(p, 0x51, r & ~0x80);
1489 if((r = pcicfgr8(p, 0x55)) & 0x80)
1490 pcicfgw8(p, 0x55, r & ~0x80);
1492 case (0x0640<<16)|0x1095: /* CMD 640B */
1494 * Bugfix code here...
1497 case (0x7441<<16)|0x1022: /* AMD 768 */
1500 * 0x41 prefetch, postwrite;
1501 * 0x43 FIFO configuration 1/2 and 1/2;
1502 * 0x44 status register read retry;
1503 * 0x46 DMA read and end of sector flush.
1505 r = pcicfgr8(p, 0x41);
1506 pcicfgw8(p, 0x41, r|0xF0);
1507 r = pcicfgr8(p, 0x43);
1508 pcicfgw8(p, 0x43, (r & 0x90)|0x2A);
1509 r = pcicfgr8(p, 0x44);
1510 pcicfgw8(p, 0x44, r|0x08);
1511 r = pcicfgr8(p, 0x46);
1512 pcicfgw8(p, 0x46, (r & 0x0C)|0xF0);
1514 case (0x7469<<16)|0x1022: /* AMD 3111 */
1515 case (0x4376<<16)|0x1002: /* ATI SB400 PATA */
1516 case (0x4379<<16)|0x1002: /* ATI SB400 SATA */
1517 case (0x437a<<16)|0x1002: /* ATI SB400 SATA */
1519 * This can probably be lumped in with the 768 above.
1522 case (0x209A<<16)|0x1022: /* AMD CS5536 */
1523 case (0x01BC<<16)|0x10DE: /* nVidia nForce1 */
1524 case (0x0065<<16)|0x10DE: /* nVidia nForce2 */
1525 case (0x0085<<16)|0x10DE: /* nVidia nForce2 MCP */
1526 case (0x00E3<<16)|0x10DE: /* nVidia nForce2 250 SATA */
1527 case (0x00D5<<16)|0x10DE: /* nVidia nForce3 */
1528 case (0x00E5<<16)|0x10DE: /* nVidia nForce3 Pro */
1529 case (0x00EE<<16)|0x10DE: /* nVidia nForce3 250 SATA */
1530 case (0x0035<<16)|0x10DE: /* nVidia nForce3 MCP */
1531 case (0x0053<<16)|0x10DE: /* nVidia nForce4 */
1532 case (0x0054<<16)|0x10DE: /* nVidia nForce4 SATA */
1533 case (0x0055<<16)|0x10DE: /* nVidia nForce4 SATA */
1535 * Ditto, although it may have a different base
1536 * address for the registers (0x50?).
1539 case (0x0646<<16)|0x1095: /* CMD 646 */
1540 case (0x0571<<16)|0x1106: /* VIA 82C686 */
1541 case (0x0211<<16)|0x1166: /* ServerWorks IB6566 */
1542 case (0x2363<<16)|0x197b: /* JMicron SATA */
1543 case (0x1230<<16)|0x8086: /* 82371FB (PIIX) */
1544 case (0x7010<<16)|0x8086: /* 82371SB (PIIX3) */
1545 case (0x7111<<16)|0x8086: /* 82371[AE]B (PIIX4[E]) */
1546 case (0x2411<<16)|0x8086: /* 82801AA (ICH) */
1547 case (0x2421<<16)|0x8086: /* 82801AB (ICH0) */
1548 case (0x244A<<16)|0x8086: /* 82801BA (ICH2, Mobile) */
1549 case (0x244B<<16)|0x8086: /* 82801BA (ICH2, High-End) */
1550 case (0x248A<<16)|0x8086: /* 82801CA (ICH3, Mobile) */
1551 case (0x248B<<16)|0x8086: /* 82801CA (ICH3, High-End) */
1552 case (0x24CA<<16)|0x8086: /* 82801DBM (ICH4, Mobile) */
1553 case (0x24CB<<16)|0x8086: /* 82801DB (ICH4, High-End) */
1554 case (0x24DB<<16)|0x8086: /* 82801EB (ICH5) */
1555 case (0x25A3<<16)|0x8086: /* 6300ESB (E7210) */
1556 case (0x266F<<16)|0x8086: /* 82801FB (ICH6) */
1557 case (0x27DF<<16)|0x8086: /* 82801G SATA (ICH7) */
1558 case (0x27C0<<16)|0x8086: /* 82801GB SATA AHCI (ICH7) */
1559 // case (0x27C4<<16)|0x8086: /* 82801GBM SATA (ICH7) */
1560 case (0x27C5<<16)|0x8086: /* 82801GBM SATA AHCI (ICH7) */
1561 case (0x2920<<16)|0x8086: /* 82801(IB)/IR/IH/IO SATA IDE (ICH9) */
1562 case (0x3a20<<16)|0x8086: /* 82801JI (ICH10) */
1563 case (0x3a26<<16)|0x8086: /* 82801JI (ICH10) */
1567 for(channel = 0; channel < 2; channel++){
1568 if(pi & (1<<(2*channel))){
1569 sdev = ataprobe(p->mem[0+2*channel].bar & ~0x01,
1570 p->mem[1+2*channel].bar & ~0x01,
1577 ctlr->ienable = pc87415ienable;
1584 ctlr->tbdf = p->tbdf;
1586 else if((sdev = legacy[channel]) == nil)
1599 atalegacy(int port, int irq)
1601 return ataprobe(port, port+0x204, irq);
1611 * Legacy controllers are always 'C' and 'D' and if
1612 * they exist and have drives will be first in the list.
1613 * If there are no active legacy controllers, native
1614 * controllers start at 'C'.
1619 if(ctlr->cmdport == 0x1F0 || ctlr->cmdport == 0x170)
1624 if(sdev->ifc == &sdataifc){
1626 if(ctlr->cmdport == 0x1F0)
1628 else if(ctlr->cmdport == 0x170)
1634 // snprint(sdev->name, NAMELEN, "sd%c", sdev->idno);
1643 ataenable(SDev* sdev)
1649 setvec(ctlr->irq+VectorPIC, atainterrupt, ctlr);
1650 outb(ctlr->ctlport+Dc, 0);
1652 ctlr->ienable(ctlr);
1661 atalegacy, /* legacy */
1663 ataenable, /* enable */
1666 scsiverify, /* verify */
1667 scsionline, /* online */