1 /*
2 * ATA (IDE) disk.
3 */
4
5 #include "u.h"
6 #include "../port/lib.h"
7 #include "mem.h"
8 #include "dat.h"
9 #include "fns.h"
10 #include "io.h"
11 #include "ureg.h"
12 #include "../port/error.h"
13
14 #include "../port/sd.h"
15
16 extern SDifc sdataifc;
17
18 enum {
19 DbgCONFIG = 0x0001, /* detected drive config info */
20 DbgIDENTIFY = 0x0002, /* detected drive identify info */
21 DbgSTATE = 0x0004, /* dump state on panic */
22 DbgPROBE = 0x0008, /* trace device probing */
23 DbgDEBUG = 0x0080, /* the current problem... */
24 DbgINL = 0x0100, /* That Inil20+ message we hate */
25 Dbg48BIT = 0x0200, /* 48-bit LBA */
26 DbgBsy = 0x0400, /* interrupt but Bsy (shared IRQ) */
27 };
28 #define DEBUG (DbgDEBUG|DbgSTATE)
29
30 enum { /* I/O ports */
31 Data = 0,
32 Error = 1, /* (read) */
33 Features = 1, /* (write) */
34 Count = 2, /* sector count<7-0>, sector count<15-8> */
35 Ir = 2, /* interrupt reason (PACKET) */
36 Sector = 3, /* sector number */
37 Lbalo = 3, /* LBA<7-0>, LBA<31-24> */
38 Cyllo = 4, /* cylinder low */
39 Bytelo = 4, /* byte count low (PACKET) */
40 Lbamid = 4, /* LBA<15-8>, LBA<39-32> */
41 Cylhi = 5, /* cylinder high */
42 Bytehi = 5, /* byte count hi (PACKET) */
43 Lbahi = 5, /* LBA<23-16>, LBA<47-40> */
44 Dh = 6, /* Device/Head, LBA<27-24> */
45 Status = 7, /* (read) */
46 Command = 7, /* (write) */
47
48 As = 2, /* Alternate Status (read) */
49 Dc = 2, /* Device Control (write) */
50 };
51
52 enum { /* Error */
53 Med = 0x01, /* Media error */
54 Ili = 0x01, /* command set specific (PACKET) */
55 Nm = 0x02, /* No Media */
56 Eom = 0x02, /* command set specific (PACKET) */
57 Abrt = 0x04, /* Aborted command */
58 Mcr = 0x08, /* Media Change Request */
59 Idnf = 0x10, /* no user-accessible address */
60 Mc = 0x20, /* Media Change */
61 Unc = 0x40, /* Uncorrectable data error */
62 Wp = 0x40, /* Write Protect */
63 Icrc = 0x80, /* Interface CRC error */
64 };
65
66 enum { /* Features */
67 Dma = 0x01, /* data transfer via DMA (PACKET) */
68 Ovl = 0x02, /* command overlapped (PACKET) */
69 };
70
71 enum { /* Interrupt Reason */
72 Cd = 0x01, /* Command/Data */
73 Io = 0x02, /* I/O direction: read */
74 Rel = 0x04, /* Bus Release */
75 };
76
77 enum { /* Device/Head */
78 Dev0 = 0xA0, /* Master */
79 Dev1 = 0xB0, /* Slave */
80 Lba = 0x40, /* LBA mode */
81 };
82
83 enum { /* Status, Alternate Status */
84 Err = 0x01, /* Error */
85 Chk = 0x01, /* Check error (PACKET) */
86 Drq = 0x08, /* Data Request */
87 Dsc = 0x10, /* Device Seek Complete */
88 Serv = 0x10, /* Service */
89 Df = 0x20, /* Device Fault */
90 Dmrd = 0x20, /* DMA ready (PACKET) */
91 Drdy = 0x40, /* Device Ready */
92 Bsy = 0x80, /* Busy */
93 };
94
95 enum { /* Command */
96 Cnop = 0x00, /* NOP */
97 Cdr = 0x08, /* Device Reset */
98 Crs = 0x20, /* Read Sectors */
99 Crs48 = 0x24, /* Read Sectors Ext */
100 Crd48 = 0x25, /* Read w/ DMA Ext */
101 Crdq48 = 0x26, /* Read w/ DMA Queued Ext */
102 Crsm48 = 0x29, /* Read Multiple Ext */
103 Cws = 0x30, /* Write Sectors */
104 Cws48 = 0x34, /* Write Sectors Ext */
105 Cwd48 = 0x35, /* Write w/ DMA Ext */
106 Cwdq48 = 0x36, /* Write w/ DMA Queued Ext */
107 Cwsm48 = 0x39, /* Write Multiple Ext */
108 Cedd = 0x90, /* Execute Device Diagnostics */
109 Cpkt = 0xA0, /* Packet */
110 Cidpkt = 0xA1, /* Identify Packet Device */
111 Crsm = 0xC4, /* Read Multiple */
112 Cwsm = 0xC5, /* Write Multiple */
113 Csm = 0xC6, /* Set Multiple */
114 Crdq = 0xC7, /* Read DMA queued */
115 Crd = 0xC8, /* Read DMA */
116 Cwd = 0xCA, /* Write DMA */
117 Cwdq = 0xCC, /* Write DMA queued */
118 Cstandby = 0xE2, /* Standby */
119 Cid = 0xEC, /* Identify Device */
120 Csf = 0xEF, /* Set Features */
121 };
122
123 enum { /* Device Control */
124 Nien = 0x02, /* (not) Interrupt Enable */
125 Srst = 0x04, /* Software Reset */
126 Hob = 0x80, /* High Order Bit [sic] */
127 };
128
129 enum { /* PCI Configuration Registers */
130 Bmiba = 0x20, /* Bus Master Interface Base Address */
131 Idetim = 0x40, /* IE Timing */
132 Sidetim = 0x44, /* Slave IE Timing */
133 Udmactl = 0x48, /* Ultra DMA/33 Control */
134 Udmatim = 0x4A, /* Ultra DMA/33 Timing */
135 };
136
137 enum { /* Bus Master IDE I/O Ports */
138 Bmicx = 0, /* Command */
139 Bmisx = 2, /* Status */
140 Bmidtpx = 4, /* Descriptor Table Pointer */
141 };
142
143 enum { /* Bmicx */
144 Ssbm = 0x01, /* Start/Stop Bus Master */
145 Rwcon = 0x08, /* Read/Write Control */
146 };
147
148 enum { /* Bmisx */
149 Bmidea = 0x01, /* Bus Master IDE Active */
150 Idedmae = 0x02, /* IDE DMA Error (R/WC) */
151 Ideints = 0x04, /* IDE Interrupt Status (R/WC) */
152 Dma0cap = 0x20, /* Drive 0 DMA Capable */
153 Dma1cap = 0x40, /* Drive 0 DMA Capable */
154 };
155 enum { /* Physical Region Descriptor */
156 PrdEOT = 0x80000000, /* End of Transfer */
157 };
158
159 enum { /* offsets into the identify info. */
160 Iconfig = 0, /* general configuration */
161 Ilcyl = 1, /* logical cylinders */
162 Ilhead = 3, /* logical heads */
163 Ilsec = 6, /* logical sectors per logical track */
164 Iserial = 10, /* serial number */
165 Ifirmware = 23, /* firmware revision */
166 Imodel = 27, /* model number */
167 Imaxrwm = 47, /* max. read/write multiple sectors */
168 Icapabilities = 49, /* capabilities */
169 Istandby = 50, /* device specific standby timer */
170 Ipiomode = 51, /* PIO data transfer mode number */
171 Ivalid = 53,
172 Iccyl = 54, /* cylinders if (valid&0x01) */
173 Ichead = 55, /* heads if (valid&0x01) */
174 Icsec = 56, /* sectors if (valid&0x01) */
175 Iccap = 57, /* capacity if (valid&0x01) */
176 Irwm = 59, /* read/write multiple */
177 Ilba = 60, /* LBA size */
178 Imwdma = 63, /* multiword DMA mode */
179 Iapiomode = 64, /* advanced PIO modes supported */
180 Iminmwdma = 65, /* min. multiword DMA cycle time */
181 Irecmwdma = 66, /* rec. multiword DMA cycle time */
182 Iminpio = 67, /* min. PIO cycle w/o flow control */
183 Iminiordy = 68, /* min. PIO cycle with IORDY */
184 Ipcktbr = 71, /* time from PACKET to bus release */
185 Iserbsy = 72, /* time from SERVICE to !Bsy */
186 Iqdepth = 75, /* max. queue depth */
187 Imajor = 80, /* major version number */
188 Iminor = 81, /* minor version number */
189 Icsfs = 82, /* command set/feature supported */
190 Icsfe = 85, /* command set/feature enabled */
191 Iudma = 88, /* ultra DMA mode */
192 Ierase = 89, /* time for security erase */
193 Ieerase = 90, /* time for enhanced security erase */
194 Ipower = 91, /* current advanced power management */
195 Ilba48 = 100, /* 48-bit LBA size (64 bits in 100-103) */
196 Irmsn = 127, /* removable status notification */
197 Isecstat = 128, /* security status */
198 Icfapwr = 160, /* CFA power mode */
199 Imediaserial = 176, /* current media serial number */
200 Icksum = 255, /* checksum */
201 };
202
203 enum { /* bit masks for config identify info */
204 Mpktsz = 0x0003, /* packet command size */
205 Mincomplete = 0x0004, /* incomplete information */
206 Mdrq = 0x0060, /* DRQ type */
207 Mrmdev = 0x0080, /* device is removable */
208 Mtype = 0x1F00, /* device type */
209 Mproto = 0x8000, /* command protocol */
210 };
211
212 enum { /* bit masks for capabilities identify info */
213 Mdma = 0x0100, /* DMA supported */
214 Mlba = 0x0200, /* LBA supported */
215 Mnoiordy = 0x0400, /* IORDY may be disabled */
216 Miordy = 0x0800, /* IORDY supported */
217 Msoftrst = 0x1000, /* needs soft reset when Bsy */
218 Mstdby = 0x2000, /* standby supported */
219 Mqueueing = 0x4000, /* queueing overlap supported */
220 Midma = 0x8000, /* interleaved DMA supported */
221 };
222
223 enum { /* bit masks for supported/enabled features */
224 Msmart = 0x0001,
225 Msecurity = 0x0002,
226 Mrmmedia = 0x0004,
227 Mpwrmgmt = 0x0008,
228 Mpkt = 0x0010,
229 Mwcache = 0x0020,
230 Mlookahead = 0x0040,
231 Mrelirq = 0x0080,
232 Msvcirq = 0x0100,
233 Mreset = 0x0200,
234 Mprotected = 0x0400,
235 Mwbuf = 0x1000,
236 Mrbuf = 0x2000,
237 Mnop = 0x4000,
238 Mmicrocode = 0x0001,
239 Mqueued = 0x0002,
240 Mcfa = 0x0004,
241 Mapm = 0x0008,
242 Mnotify = 0x0010,
243 Mstandby = 0x0020,
244 Mspinup = 0x0040,
245 Mmaxsec = 0x0100,
246 Mautoacoustic = 0x0200,
247 Maddr48 = 0x0400,
248 Mdevconfov = 0x0800,
249 Mflush = 0x1000,
250 Mflush48 = 0x2000,
251 Msmarterror = 0x0001,
252 Msmartselftest = 0x0002,
253 Mmserial = 0x0004,
254 Mmpassthru = 0x0008,
255 Mlogging = 0x0020,
256 };
257
258 typedef struct Ctlr Ctlr;
259 typedef struct Drive Drive;
260
261 typedef struct Prd { /* Physical Region Descriptor */
262 ulong pa; /* Physical Base Address */
263 int count;
264 } Prd;
265
266 enum {
267 BMspan = 64*1024, /* must be power of 2 <= 64*1024 */
268
269 Nprd = SDmaxio/BMspan+2,
270 };
271
272 typedef struct Ctlr {
273 int cmdport;
274 int ctlport;
275 int irq;
276 int subirq;
277 int tbdf;
278 int bmiba; /* bus master interface base address */
279 int maxio; /* sector count transfer maximum */
280 int span; /* don't span this boundary with dma */
281
282 Pcidev* pcidev;
283 void (*ienable)(Ctlr*);
284 void (*idisable)(Ctlr*);
285 SDev* sdev;
286
287 Drive* drive[2];
288
289 Prd* prdt; /* physical region descriptor table */
290 void (*irqack)(Ctlr*); /* call to extinguish ICH intrs */
291
292 QLock; /* current command */
293 Drive* curdrive;
294 int command; /* last command issued (debugging) */
295 Rendez;
296 int done;
297
298 /* interrupt counts */
299 ulong intnil; /* no drive */
300 ulong intbusy; /* controller still busy */
301 ulong intok; /* normal */
302
303 Lock; /* register access */
304 } Ctlr;
305
306 typedef struct Drive {
307 Ctlr* ctlr;
308
309 int dev;
310 ushort info[256];
311 int c; /* cylinder */
312 int h; /* head */
313 int s; /* sector */
314 vlong sectors; /* total */
315 int secsize; /* sector size */
316
317 int dma; /* DMA R/W possible */
318 int dmactl;
319 int rwm; /* read/write multiple possible */
320 int rwmctl;
321
322 int pkt; /* PACKET device, length of pktcmd */
323 uchar pktcmd[16];
324 int pktdma; /* this PACKET command using dma */
325
326 uchar sense[18];
327 uchar inquiry[48];
328
329 QLock; /* drive access */
330 int command; /* current command */
331 int write;
332 uchar* data;
333 int dlen;
334 uchar* limit;
335 int count; /* sectors */
336 int block; /* R/W bytes per block */
337 int status;
338 int error;
339 int flags; /* internal flags */
340
341 /* interrupt counts */
342 ulong intcmd; /* commands */
343 ulong intrd; /* reads */
344 ulong intwr; /* writes */
345 } Drive;
346
347 enum { /* internal flags */
348 Lba48 = 0x1, /* LBA48 mode */
349 Lba48always = 0x2, /* ... */
350 };
351 enum {
352 Last28 = (1<<28) - 1 - 1, /* all-ones mask is not addressible */
353 };
354
355 static void
atadumpstate(Drive * drive,uchar * cmd,vlong lba,int count)356 atadumpstate(Drive* drive, uchar* cmd, vlong lba, int count)
357 {
358 Prd *prd;
359 Pcidev *p;
360 Ctlr *ctlr;
361 int i, bmiba;
362
363 if(!(DEBUG & DbgSTATE)){
364 USED(drive, cmd, lba, count);
365 return;
366 }
367
368 ctlr = drive->ctlr;
369 print("sdata: command %2.2uX\n", ctlr->command);
370 print("data %8.8p limit %8.8p dlen %d status %uX error %uX\n",
371 drive->data, drive->limit, drive->dlen,
372 drive->status, drive->error);
373 if(cmd != nil){
374 print("lba %d -> %lld, count %d -> %d (%d)\n",
375 (cmd[2]<<24)|(cmd[3]<<16)|(cmd[4]<<8)|cmd[5], lba,
376 (cmd[7]<<8)|cmd[8], count, drive->count);
377 }
378 if(!(inb(ctlr->ctlport+As) & Bsy)){
379 for(i = 1; i < 7; i++)
380 print(" 0x%2.2uX", inb(ctlr->cmdport+i));
381 print(" 0x%2.2uX\n", inb(ctlr->ctlport+As));
382 }
383 if(drive->command == Cwd || drive->command == Crd){
384 bmiba = ctlr->bmiba;
385 prd = ctlr->prdt;
386 print("bmicx %2.2uX bmisx %2.2uX prdt %8.8p\n",
387 inb(bmiba+Bmicx), inb(bmiba+Bmisx), prd);
388 for(;;){
389 print("pa 0x%8.8luX count %8.8uX\n",
390 prd->pa, prd->count);
391 if(prd->count & PrdEOT)
392 break;
393 prd++;
394 }
395 }
396 if(ctlr->pcidev && ctlr->pcidev->vid == 0x8086){
397 p = ctlr->pcidev;
398 print("0x40: %4.4uX 0x42: %4.4uX",
399 pcicfgr16(p, 0x40), pcicfgr16(p, 0x42));
400 print("0x48: %2.2uX\n", pcicfgr8(p, 0x48));
401 print("0x4A: %4.4uX\n", pcicfgr16(p, 0x4A));
402 }
403 }
404
405 static int
atadebug(int cmdport,int ctlport,char * fmt,...)406 atadebug(int cmdport, int ctlport, char* fmt, ...)
407 {
408 int i, n;
409 va_list arg;
410 char buf[PRINTSIZE];
411
412 if(!(DEBUG & DbgPROBE)){
413 USED(cmdport, ctlport, fmt);
414 return 0;
415 }
416
417 va_start(arg, fmt);
418 n = vseprint(buf, buf+sizeof(buf), fmt, arg) - buf;
419 va_end(arg);
420
421 if(cmdport){
422 if(buf[n-1] == '\n')
423 n--;
424 n += snprint(buf+n, PRINTSIZE-n, " ataregs 0x%uX:",
425 cmdport);
426 for(i = Features; i < Command; i++)
427 n += snprint(buf+n, PRINTSIZE-n, " 0x%2.2uX",
428 inb(cmdport+i));
429 if(ctlport)
430 n += snprint(buf+n, PRINTSIZE-n, " 0x%2.2uX",
431 inb(ctlport+As));
432 n += snprint(buf+n, PRINTSIZE-n, "\n");
433 }
434 putstrn(buf, n);
435
436 return n;
437 }
438
439 static int
ataready(int cmdport,int ctlport,int dev,int reset,int ready,int micro)440 ataready(int cmdport, int ctlport, int dev, int reset, int ready, int micro)
441 {
442 int as;
443
444 atadebug(cmdport, ctlport, "ataready: dev %uX reset %uX ready %uX",
445 dev, reset, ready);
446
447 for(;;){
448 /*
449 * Wait for the controller to become not busy and
450 * possibly for a status bit to become true (usually
451 * Drdy). Must change to the appropriate device
452 * register set if necessary before testing for ready.
453 * Always run through the loop at least once so it
454 * can be used as a test for !Bsy.
455 */
456 as = inb(ctlport+As);
457 if(as & reset){
458 /* nothing to do */
459 }
460 else if(dev){
461 outb(cmdport+Dh, dev);
462 dev = 0;
463 }
464 else if(ready == 0 || (as & ready)){
465 atadebug(0, 0, "ataready: %d 0x%2.2uX\n", micro, as);
466 return as;
467 }
468
469 if(micro-- <= 0){
470 atadebug(0, 0, "ataready: %d 0x%2.2uX\n", micro, as);
471 break;
472 }
473 microdelay(1);
474 }
475 atadebug(cmdport, ctlport, "ataready: timeout");
476
477 return -1;
478 }
479
480 static int
atadone(void * arg)481 atadone(void* arg)
482 {
483 return ((Ctlr*)arg)->done;
484 }
485
486 static int
atarwmmode(Drive * drive,int cmdport,int ctlport,int dev)487 atarwmmode(Drive* drive, int cmdport, int ctlport, int dev)
488 {
489 int as, maxrwm, rwm;
490 uchar dummy;
491
492 maxrwm = (drive->info[Imaxrwm] & 0xFF);
493 if(maxrwm == 0)
494 return 0;
495
496 /*
497 * Sometimes drives come up with the current count set
498 * to 0; if so, set a suitable value, otherwise believe
499 * the value in Irwm if the 0x100 bit is set.
500 */
501 if(drive->info[Irwm] & 0x100)
502 rwm = (drive->info[Irwm] & 0xFF);
503 else
504 rwm = 0;
505 if(rwm == 0)
506 rwm = maxrwm;
507 if(rwm > 16)
508 rwm = 16;
509 if(ataready(cmdport, ctlport, dev, Bsy|Drq, Drdy, 102*1000) < 0)
510 return 0;
511 outb(cmdport+Count, rwm);
512 outb(cmdport+Command, Csm);
513 microdelay(1);
514 as = ataready(cmdport, ctlport, 0, Bsy, Drdy|Df|Err, 1000);
515 dummy = inb(cmdport+Status);
516 USED(dummy);
517 if(as < 0 || (as & (Df|Err)))
518 return 0;
519
520 drive->rwm = rwm;
521
522 return rwm;
523 }
524
525 static int
atadmamode(Drive * drive)526 atadmamode(Drive* drive)
527 {
528 int dma;
529
530 /*
531 * Check if any DMA mode enabled.
532 * Assumes the BIOS has picked and enabled the best.
533 * This is completely passive at the moment, no attempt is
534 * made to ensure the hardware is correctly set up.
535 */
536 dma = drive->info[Imwdma] & 0x0707;
537 drive->dma = (dma>>8) & dma;
538 if(drive->dma == 0 && (drive->info[Ivalid] & 0x04)){
539 dma = drive->info[Iudma] & 0x7F7F;
540 drive->dma = (dma>>8) & dma;
541 if(drive->dma)
542 drive->dma |= 'U'<<16;
543 }
544
545 return dma;
546 }
547
548 static int
ataidentify(int cmdport,int ctlport,int dev,int pkt,void * info)549 ataidentify(int cmdport, int ctlport, int dev, int pkt, void* info)
550 {
551 int as, command, drdy;
552 uchar dummy;
553
554 if(pkt){
555 command = Cidpkt;
556 drdy = 0;
557 }
558 else{
559 command = Cid;
560 drdy = Drdy;
561 }
562 as = ataready(cmdport, ctlport, dev, Bsy|Drq, drdy, 103*1000);
563 if(as < 0)
564 return as;
565 outb(cmdport+Command, command);
566 microdelay(1);
567
568 as = ataready(cmdport, ctlport, 0, Bsy, Drq|Err, 400*1000);
569 if(as < 0)
570 return -1;
571 if(as & Err)
572 return as;
573
574 memset(info, 0, 512);
575 inss(cmdport+Data, info, 256);
576 dummy = inb(cmdport+Status);
577 USED(dummy);
578
579 if(DEBUG & DbgIDENTIFY){
580 int i;
581 ushort *sp;
582
583 sp = (ushort*)info;
584 for(i = 0; i < 256; i++){
585 if(i && (i%16) == 0)
586 print("\n");
587 print(" %4.4uX", *sp);
588 sp++;
589 }
590 print("\n");
591 }
592
593 return 0;
594 }
595
596 static Drive*
atadrive(int cmdport,int ctlport,int dev)597 atadrive(int cmdport, int ctlport, int dev)
598 {
599 Drive *drive;
600 int as, i, pkt;
601 uchar buf[512], *p;
602 ushort iconfig, *sp;
603
604 atadebug(0, 0, "identify: port 0x%uX dev 0x%2.2uX\n", cmdport, dev);
605 pkt = 1;
606 retry:
607 as = ataidentify(cmdport, ctlport, dev, pkt, buf);
608 if(as < 0)
609 return nil;
610 if(as & Err){
611 if(pkt == 0)
612 return nil;
613 pkt = 0;
614 goto retry;
615 }
616
617 if((drive = malloc(sizeof(Drive))) == nil)
618 return nil;
619 drive->dev = dev;
620 memmove(drive->info, buf, sizeof(drive->info));
621 drive->sense[0] = 0x70;
622 drive->sense[7] = sizeof(drive->sense)-7;
623
624 drive->inquiry[2] = 2;
625 drive->inquiry[3] = 2;
626 drive->inquiry[4] = sizeof(drive->inquiry)-4;
627 p = &drive->inquiry[8];
628 sp = &drive->info[Imodel];
629 for(i = 0; i < 20; i++){
630 *p++ = *sp>>8;
631 *p++ = *sp++;
632 }
633
634 drive->secsize = 512;
635
636 /*
637 * Beware the CompactFlash Association feature set.
638 * Now, why this value in Iconfig just walks all over the bit
639 * definitions used in the other parts of the ATA/ATAPI standards
640 * is a mystery and a sign of true stupidity on someone's part.
641 * Anyway, the standard says if this value is 0x848A then it's
642 * CompactFlash and it's NOT a packet device.
643 */
644 iconfig = drive->info[Iconfig];
645 if(iconfig != 0x848A && (iconfig & 0xC000) == 0x8000){
646 if(iconfig & 0x01)
647 drive->pkt = 16;
648 else
649 drive->pkt = 12;
650 }
651 else{
652 if(drive->info[Ivalid] & 0x0001){
653 drive->c = drive->info[Iccyl];
654 drive->h = drive->info[Ichead];
655 drive->s = drive->info[Icsec];
656 }
657 else{
658 drive->c = drive->info[Ilcyl];
659 drive->h = drive->info[Ilhead];
660 drive->s = drive->info[Ilsec];
661 }
662 if(drive->info[Icapabilities] & Mlba){
663 if(drive->info[Icsfs+1] & Maddr48){
664 drive->sectors = drive->info[Ilba48]
665 | (drive->info[Ilba48+1]<<16)
666 | ((vlong)drive->info[Ilba48+2]<<32);
667 drive->flags |= Lba48;
668 }
669 else{
670 drive->sectors = (drive->info[Ilba+1]<<16)
671 |drive->info[Ilba];
672 }
673 drive->dev |= Lba;
674 }
675 else
676 drive->sectors = drive->c*drive->h*drive->s;
677 atarwmmode(drive, cmdport, ctlport, dev);
678 }
679 atadmamode(drive);
680
681 if(DEBUG & DbgCONFIG){
682 print("dev %2.2uX port %uX config %4.4uX capabilities %4.4uX",
683 dev, cmdport, iconfig, drive->info[Icapabilities]);
684 print(" mwdma %4.4uX", drive->info[Imwdma]);
685 if(drive->info[Ivalid] & 0x04)
686 print(" udma %4.4uX", drive->info[Iudma]);
687 print(" dma %8.8uX rwm %ud", drive->dma, drive->rwm);
688 if(drive->flags&Lba48)
689 print("\tLLBA sectors %lld", drive->sectors);
690 print("\n");
691 }
692
693 return drive;
694 }
695
696 static void
atasrst(int ctlport)697 atasrst(int ctlport)
698 {
699 /*
700 * Srst is a big stick and may cause problems if further
701 * commands are tried before the drives become ready again.
702 * Also, there will be problems here if overlapped commands
703 * are ever supported.
704 */
705 microdelay(5);
706 outb(ctlport+Dc, Srst);
707 microdelay(5);
708 outb(ctlport+Dc, 0);
709 microdelay(2*1000);
710 }
711
712 static SDev*
ataprobe(int cmdport,int ctlport,int irq,int subirq)713 ataprobe(int cmdport, int ctlport, int irq, int subirq)
714 {
715 Ctlr* ctlr;
716 SDev *sdev;
717 Drive *drive;
718 int dev, error, rhi, rlo;
719 static int nonlegacy = 'C';
720
721 if(cmdport == 0) {
722 print("ataprobe: cmdport is 0\n");
723 return nil;
724 }
725
726 /*
727 * Try to detect a floating bus.
728 * Bsy should be cleared. If not, see if the cylinder registers
729 * are read/write capable.
730 * If the master fails, try the slave to catch slave-only
731 * configurations.
732 * There's no need to restore the tested registers as they will
733 * be reset on any detected drives by the Cedd command.
734 * All this indicates is that there is at least one drive on the
735 * controller; when the non-existent drive is selected in a
736 * single-drive configuration the registers of the existing drive
737 * are often seen, only command execution fails.
738 */
739 dev = Dev0;
740 if(inb(ctlport+As) & Bsy){
741 outb(cmdport+Dh, dev);
742 microdelay(1);
743 trydev1:
744 atadebug(cmdport, ctlport, "ataprobe bsy");
745 outb(cmdport+Cyllo, 0xAA);
746 outb(cmdport+Cylhi, 0x55);
747 outb(cmdport+Sector, 0xFF);
748 rlo = inb(cmdport+Cyllo);
749 rhi = inb(cmdport+Cylhi);
750 if(rlo != 0xAA && (rlo == 0xFF || rhi != 0x55)){
751 if(dev == Dev1){
752 release:
753 return nil;
754 }
755 dev = Dev1;
756 if(ataready(cmdport, ctlport, dev, Bsy, 0, 20*1000) < 0)
757 goto trydev1;
758 }
759 }
760
761 /*
762 * Disable interrupts on any detected controllers.
763 */
764 outb(ctlport+Dc, Nien);
765 tryedd1:
766 if(ataready(cmdport, ctlport, dev, Bsy|Drq, 0, 105*1000) < 0){
767 /*
768 * There's something there, but it didn't come up clean,
769 * so try hitting it with a big stick. The timing here is
770 * wrong but this is a last-ditch effort and it sometimes
771 * gets some marginal hardware back online.
772 */
773 atasrst(ctlport);
774 if(ataready(cmdport, ctlport, dev, Bsy|Drq, 0, 106*1000) < 0)
775 goto release;
776 }
777
778 /*
779 * Can only get here if controller is not busy.
780 * If there are drives Bsy will be set within 400nS,
781 * must wait 2mS before testing Status.
782 * Wait for the command to complete (6 seconds max).
783 */
784 outb(cmdport+Command, Cedd);
785 delay(2);
786 if(ataready(cmdport, ctlport, dev, Bsy|Drq, 0, 6*1000*1000) < 0)
787 goto release;
788
789 /*
790 * If bit 0 of the error register is set then the selected drive
791 * exists. This is enough to detect single-drive configurations.
792 * However, if the master exists there is no way short of executing
793 * a command to determine if a slave is present.
794 * It appears possible to get here testing Dev0 although it doesn't
795 * exist and the EDD won't take, so try again with Dev1.
796 */
797 error = inb(cmdport+Error);
798 atadebug(cmdport, ctlport, "ataprobe: dev %uX", dev);
799 if((error & ~0x80) != 0x01){
800 if(dev == Dev1)
801 goto release;
802 dev = Dev1;
803 goto tryedd1;
804 }
805
806 /*
807 * At least one drive is known to exist, try to
808 * identify it. If that fails, don't bother checking
809 * any further.
810 * If the one drive found is Dev0 and the EDD command
811 * didn't indicate Dev1 doesn't exist, check for it.
812 */
813 if((drive = atadrive(cmdport, ctlport, dev)) == nil)
814 goto release;
815 if((ctlr = malloc(sizeof(Ctlr))) == nil){
816 free(drive);
817 goto release;
818 }
819 memset(ctlr, 0, sizeof(Ctlr));
820 if((sdev = malloc(sizeof(SDev))) == nil){
821 free(ctlr);
822 free(drive);
823 goto release;
824 }
825 memset(sdev, 0, sizeof(SDev));
826 drive->ctlr = ctlr;
827 if(dev == Dev0){
828 ctlr->drive[0] = drive;
829 if(!(error & 0x80)){
830 /*
831 * Always leave Dh pointing to a valid drive,
832 * otherwise a subsequent call to ataready on
833 * this controller may try to test a bogus Status.
834 * Ataprobe is the only place possibly invalid
835 * drives should be selected.
836 */
837 drive = atadrive(cmdport, ctlport, Dev1);
838 if(drive != nil){
839 drive->ctlr = ctlr;
840 ctlr->drive[1] = drive;
841 }
842 else{
843 outb(cmdport+Dh, Dev0);
844 microdelay(1);
845 }
846 }
847 }
848 else
849 ctlr->drive[1] = drive;
850
851 ctlr->cmdport = cmdport;
852 ctlr->ctlport = ctlport;
853 ctlr->irq = irq;
854 ctlr->subirq = subirq;
855 ctlr->tbdf = BUSUNKNOWN;
856 ctlr->command = Cedd; /* debugging */
857
858 switch(cmdport){
859 default:
860 sdev->idno = nonlegacy;
861 break;
862 case 0x1F0:
863 sdev->idno = 'C';
864 nonlegacy = 'E';
865 break;
866 case 0x170:
867 sdev->idno = 'D';
868 nonlegacy = 'E';
869 break;
870 }
871 sdev->ifc = &sdataifc;
872 sdev->ctlr = ctlr;
873 sdev->nunit = 2;
874 ctlr->sdev = sdev;
875
876 return sdev;
877 }
878
879 static void
ataclear(SDev * sdev)880 ataclear(SDev *sdev)
881 {
882 Ctlr* ctlr;
883
884 ctlr = sdev->ctlr;
885 if (ctlr->drive[0])
886 free(ctlr->drive[0]);
887 if (ctlr->drive[1])
888 free(ctlr->drive[1]);
889 if (sdev->name)
890 free(sdev->name);
891 if (sdev->unitflg)
892 free(sdev->unitflg);
893 if (sdev->unit)
894 free(sdev->unit);
895 free(ctlr);
896 free(sdev);
897 }
898
899 static char *
atastat(SDev * sdev,char * p,char * e)900 atastat(SDev *sdev, char *p, char *e)
901 {
902 Ctlr *ctlr = sdev->ctlr;
903
904 return seprint(p, e, "%s ata port %X ctl %X irq %d.%d "
905 "intr-ok %lud intr-busy %lud intr-nil-drive %lud\n",
906 sdev->name, ctlr->cmdport, ctlr->ctlport, ctlr->irq, ctlr->subirq,
907 ctlr->intok, ctlr->intbusy, ctlr->intnil);
908 }
909
910 /*
911 * These are duplicated with sdsetsense, etc., in devsd.c, but
912 * those assume that the disk is not SCSI while in fact here
913 * ata drives are not SCSI but ATAPI ones kind of are.
914 */
915 static int
atasetsense(Drive * drive,int status,int key,int asc,int ascq)916 atasetsense(Drive* drive, int status, int key, int asc, int ascq)
917 {
918 drive->sense[2] = key;
919 drive->sense[12] = asc;
920 drive->sense[13] = ascq;
921
922 return status;
923 }
924
925 static int
atamodesense(Drive * drive,uchar * cmd)926 atamodesense(Drive* drive, uchar* cmd)
927 {
928 int len;
929
930 /*
931 * Fake a vendor-specific request with page code 0,
932 * return the drive info.
933 */
934 if((cmd[2] & 0x3F) != 0 && (cmd[2] & 0x3F) != 0x3F)
935 return atasetsense(drive, SDcheck, 0x05, 0x24, 0);
936 len = (cmd[7]<<8)|cmd[8];
937 if(len == 0)
938 return SDok;
939 if(len < 8+sizeof(drive->info))
940 return atasetsense(drive, SDcheck, 0x05, 0x1A, 0);
941 if(drive->data == nil || drive->dlen < len)
942 return atasetsense(drive, SDcheck, 0x05, 0x20, 1);
943 memset(drive->data, 0, 8);
944 drive->data[0] = sizeof(drive->info)>>8;
945 drive->data[1] = sizeof(drive->info);
946 memmove(drive->data+8, drive->info, sizeof(drive->info));
947 drive->data += 8+sizeof(drive->info);
948
949 return SDok;
950 }
951
952 static int
atastandby(Drive * drive,int period)953 atastandby(Drive* drive, int period)
954 {
955 Ctlr* ctlr;
956 int cmdport, done;
957
958 ctlr = drive->ctlr;
959 drive->command = Cstandby;
960 qlock(ctlr);
961
962 cmdport = ctlr->cmdport;
963 ilock(ctlr);
964 outb(cmdport+Count, period);
965 outb(cmdport+Dh, drive->dev);
966 ctlr->done = 0;
967 ctlr->curdrive = drive;
968 ctlr->command = Cstandby; /* debugging */
969 outb(cmdport+Command, Cstandby);
970 iunlock(ctlr);
971
972 while(waserror())
973 ;
974 tsleep(ctlr, atadone, ctlr, 60*1000);
975 poperror();
976
977 done = ctlr->done;
978 qunlock(ctlr);
979
980 if(!done || (drive->status & Err))
981 return atasetsense(drive, SDcheck, 4, 8, drive->error);
982 return SDok;
983 }
984
985 static void
atanop(Drive * drive,int subcommand)986 atanop(Drive* drive, int subcommand)
987 {
988 Ctlr* ctlr;
989 int as, cmdport, ctlport, timeo;
990
991 /*
992 * Attempt to abort a command by using NOP.
993 * In response, the drive is supposed to set Abrt
994 * in the Error register, set (Drdy|Err) in Status
995 * and clear Bsy when done. However, some drives
996 * (e.g. ATAPI Zip) just go Bsy then clear Status
997 * when done, hence the timeout loop only on Bsy
998 * and the forced setting of drive->error.
999 */
1000 ctlr = drive->ctlr;
1001 cmdport = ctlr->cmdport;
1002 outb(cmdport+Features, subcommand);
1003 outb(cmdport+Dh, drive->dev);
1004 ctlr->command = Cnop; /* debugging */
1005 outb(cmdport+Command, Cnop);
1006
1007 microdelay(1);
1008 ctlport = ctlr->ctlport;
1009 for(timeo = 0; timeo < 1000; timeo++){
1010 as = inb(ctlport+As);
1011 if(!(as & Bsy))
1012 break;
1013 microdelay(1);
1014 }
1015 drive->error |= Abrt;
1016 }
1017
1018 static void
ataabort(Drive * drive,int dolock)1019 ataabort(Drive* drive, int dolock)
1020 {
1021 /*
1022 * If NOP is available (packet commands) use it otherwise
1023 * must try a software reset.
1024 */
1025 if(dolock)
1026 ilock(drive->ctlr);
1027 if(drive->info[Icsfs] & Mnop)
1028 atanop(drive, 0);
1029 else{
1030 atasrst(drive->ctlr->ctlport);
1031 drive->error |= Abrt;
1032 }
1033 if(dolock)
1034 iunlock(drive->ctlr);
1035 }
1036
1037 static int
atadmasetup(Drive * drive,int len)1038 atadmasetup(Drive* drive, int len)
1039 {
1040 Prd *prd;
1041 ulong pa;
1042 Ctlr *ctlr;
1043 int bmiba, bmisx, count, i, span;
1044
1045 ctlr = drive->ctlr;
1046 pa = PCIWADDR(drive->data);
1047 if(pa & 0x03)
1048 return -1;
1049
1050 /*
1051 * Sometimes drives identify themselves as being DMA capable
1052 * although they are not on a busmastering controller.
1053 */
1054 prd = ctlr->prdt;
1055 if(prd == nil){
1056 drive->dmactl = 0;
1057 print("disabling dma: not on a busmastering controller\n");
1058 return -1;
1059 }
1060
1061 for(i = 0; len && i < Nprd; i++){
1062 prd->pa = pa;
1063 span = ROUNDUP(pa, ctlr->span);
1064 if(span == pa)
1065 span += ctlr->span;
1066 count = span - pa;
1067 if(count >= len){
1068 prd->count = PrdEOT|len;
1069 break;
1070 }
1071 prd->count = count;
1072 len -= count;
1073 pa += count;
1074 prd++;
1075 }
1076 if(i == Nprd)
1077 (prd-1)->count |= PrdEOT;
1078 dcflush(ctlr->prdt, i*sizeof(Prd));
1079
1080 bmiba = ctlr->bmiba;
1081 outl(bmiba+Bmidtpx, PCIWADDR(ctlr->prdt));
1082 if(drive->write)
1083 outb(ctlr->bmiba+Bmicx, 0);
1084 else
1085 outb(ctlr->bmiba+Bmicx, Rwcon);
1086 bmisx = inb(bmiba+Bmisx);
1087 outb(bmiba+Bmisx, bmisx|Ideints|Idedmae);
1088
1089 return 0;
1090 }
1091
1092 static void
atadmastart(Ctlr * ctlr,int write)1093 atadmastart(Ctlr* ctlr, int write)
1094 {
1095 if(write)
1096 outb(ctlr->bmiba+Bmicx, Ssbm);
1097 else
1098 outb(ctlr->bmiba+Bmicx, Rwcon|Ssbm);
1099 }
1100
1101 static int
atadmastop(Ctlr * ctlr)1102 atadmastop(Ctlr* ctlr)
1103 {
1104 int bmiba;
1105
1106 bmiba = ctlr->bmiba;
1107 outb(bmiba+Bmicx, inb(bmiba+Bmicx) & ~Ssbm);
1108
1109 return inb(bmiba+Bmisx);
1110 }
1111
1112 static void
atadmainterrupt(Drive * drive,int count)1113 atadmainterrupt(Drive* drive, int count)
1114 {
1115 Ctlr* ctlr;
1116 int bmiba, bmisx;
1117
1118 ctlr = drive->ctlr;
1119 bmiba = ctlr->bmiba;
1120 bmisx = inb(bmiba+Bmisx);
1121 switch(bmisx & (Ideints|Idedmae|Bmidea)){
1122 case Bmidea:
1123 /*
1124 * Data transfer still in progress, nothing to do
1125 * (this should never happen).
1126 */
1127 return;
1128
1129 case Ideints:
1130 case Ideints|Bmidea:
1131 /*
1132 * Normal termination, tidy up.
1133 */
1134 drive->data += count;
1135 break;
1136
1137 default:
1138 /*
1139 * What's left are error conditions (memory transfer
1140 * problem) and the device is not done but the PRD is
1141 * exhausted. For both cases must somehow tell the
1142 * drive to abort.
1143 */
1144 ataabort(drive, 0);
1145 break;
1146 }
1147 atadmastop(ctlr);
1148 ctlr->done = 1;
1149 }
1150
1151 static void
atapktinterrupt(Drive * drive)1152 atapktinterrupt(Drive* drive)
1153 {
1154 Ctlr* ctlr;
1155 int cmdport, len, sts;
1156
1157 ctlr = drive->ctlr;
1158 cmdport = ctlr->cmdport;
1159 sts = inb(cmdport+Ir) & (/*Rel|*/ Io|Cd);
1160 /* a default case is impossible since all cases are enumerated */
1161 switch(sts){
1162 case Cd: /* write cmd */
1163 outss(cmdport+Data, drive->pktcmd, drive->pkt/2);
1164 break;
1165
1166 case 0: /* write data */
1167 len = (inb(cmdport+Bytehi)<<8)|inb(cmdport+Bytelo);
1168 if(drive->data+len > drive->limit){
1169 atanop(drive, 0);
1170 break;
1171 }
1172 outss(cmdport+Data, drive->data, len/2);
1173 drive->data += len;
1174 break;
1175
1176 case Io: /* read data */
1177 len = (inb(cmdport+Bytehi)<<8)|inb(cmdport+Bytelo);
1178 if(drive->data+len > drive->limit){
1179 atanop(drive, 0);
1180 break;
1181 }
1182 inss(cmdport+Data, drive->data, len/2);
1183 drive->data += len;
1184 break;
1185
1186 case Io|Cd: /* read cmd */
1187 if(drive->pktdma)
1188 atadmainterrupt(drive, drive->dlen);
1189 else
1190 ctlr->done = 1;
1191 break;
1192 }
1193 if(sts & Cd)
1194 drive->intcmd++;
1195 if(sts & Io)
1196 drive->intrd++;
1197 else
1198 drive->intwr++;
1199 }
1200
1201 static int
atapktio(Drive * drive,uchar * cmd,int clen)1202 atapktio(Drive* drive, uchar* cmd, int clen)
1203 {
1204 Ctlr *ctlr;
1205 int as, cmdport, ctlport, len, r, timeo;
1206
1207 if(cmd[0] == 0x5A && (cmd[2] & 0x3F) == 0)
1208 return atamodesense(drive, cmd);
1209
1210 r = SDok;
1211
1212 drive->command = Cpkt;
1213 memmove(drive->pktcmd, cmd, clen);
1214 memset(drive->pktcmd+clen, 0, drive->pkt-clen);
1215 drive->limit = drive->data+drive->dlen;
1216
1217 ctlr = drive->ctlr;
1218 cmdport = ctlr->cmdport;
1219 ctlport = ctlr->ctlport;
1220
1221 qlock(ctlr);
1222
1223 as = ataready(cmdport, ctlport, drive->dev, Bsy|Drq, Drdy, 107*1000);
1224 /* used to test as&Chk as failure too, but some CD readers use that for media change */
1225 if(as < 0){
1226 qunlock(ctlr);
1227 return -1;
1228 }
1229
1230 ilock(ctlr);
1231 if(drive->dlen && drive->dmactl && !atadmasetup(drive, drive->dlen))
1232 drive->pktdma = Dma;
1233 else
1234 drive->pktdma = 0;
1235
1236 outb(cmdport+Features, drive->pktdma);
1237 outb(cmdport+Count, 0);
1238 outb(cmdport+Sector, 0);
1239 len = 16*drive->secsize;
1240 outb(cmdport+Bytelo, len);
1241 outb(cmdport+Bytehi, len>>8);
1242 outb(cmdport+Dh, drive->dev);
1243 ctlr->done = 0;
1244 ctlr->curdrive = drive;
1245 ctlr->command = Cpkt; /* debugging */
1246 if(drive->pktdma)
1247 atadmastart(ctlr, drive->write);
1248 outb(cmdport+Command, Cpkt);
1249
1250 if((drive->info[Iconfig] & Mdrq) != 0x0020){
1251 microdelay(1);
1252 as = ataready(cmdport, ctlport, 0, Bsy, Drq|Chk, 4*1000);
1253 if(as < 0 || (as & (Bsy|Chk))){
1254 drive->status = as<0 ? 0 : as;
1255 ctlr->curdrive = nil;
1256 ctlr->done = 1;
1257 r = SDtimeout;
1258 }else
1259 atapktinterrupt(drive);
1260 }
1261 iunlock(ctlr);
1262
1263 while(waserror())
1264 ;
1265 if(!drive->pktdma)
1266 sleep(ctlr, atadone, ctlr);
1267 else for(timeo = 0; !ctlr->done; timeo++){
1268 tsleep(ctlr, atadone, ctlr, 1000);
1269 if(ctlr->done)
1270 break;
1271 ilock(ctlr);
1272 atadmainterrupt(drive, 0);
1273 if(!drive->error && timeo > 20){
1274 ataabort(drive, 0);
1275 atadmastop(ctlr);
1276 drive->dmactl = 0;
1277 drive->error |= Abrt;
1278 }
1279 if(drive->error){
1280 drive->status |= Chk;
1281 ctlr->curdrive = nil;
1282 }
1283 iunlock(ctlr);
1284 }
1285 poperror();
1286
1287 qunlock(ctlr);
1288
1289 if(drive->status & Chk)
1290 r = SDcheck;
1291
1292 return r;
1293 }
1294
1295 static uchar cmd48[256] = {
1296 [Crs] Crs48,
1297 [Crd] Crd48,
1298 [Crdq] Crdq48,
1299 [Crsm] Crsm48,
1300 [Cws] Cws48,
1301 [Cwd] Cwd48,
1302 [Cwdq] Cwdq48,
1303 [Cwsm] Cwsm48,
1304 };
1305
1306 static int
atageniostart(Drive * drive,uvlong lba)1307 atageniostart(Drive* drive, uvlong lba)
1308 {
1309 Ctlr *ctlr;
1310 uchar cmd;
1311 int as, c, cmdport, ctlport, h, len, s, use48;
1312
1313 use48 = 0;
1314 if((drive->flags&Lba48always) || lba > Last28 || drive->count > 256){
1315 if(!(drive->flags & Lba48))
1316 return -1;
1317 use48 = 1;
1318 c = h = s = 0;
1319 }
1320 else if(drive->dev & Lba){
1321 c = (lba>>8) & 0xFFFF;
1322 h = (lba>>24) & 0x0F;
1323 s = lba & 0xFF;
1324 }
1325 else{
1326 c = lba/(drive->s*drive->h);
1327 h = ((lba/drive->s) % drive->h);
1328 s = (lba % drive->s) + 1;
1329 }
1330
1331 ctlr = drive->ctlr;
1332 cmdport = ctlr->cmdport;
1333 ctlport = ctlr->ctlport;
1334 if(ataready(cmdport, ctlport, drive->dev, Bsy|Drq, Drdy, 101*1000) < 0)
1335 return -1;
1336
1337 ilock(ctlr);
1338 if(drive->dmactl && !atadmasetup(drive, drive->count*drive->secsize)){
1339 if(drive->write)
1340 drive->command = Cwd;
1341 else
1342 drive->command = Crd;
1343 }
1344 else if(drive->rwmctl){
1345 drive->block = drive->rwm*drive->secsize;
1346 if(drive->write)
1347 drive->command = Cwsm;
1348 else
1349 drive->command = Crsm;
1350 }
1351 else{
1352 drive->block = drive->secsize;
1353 if(drive->write)
1354 drive->command = Cws;
1355 else
1356 drive->command = Crs;
1357 }
1358 drive->limit = drive->data + drive->count*drive->secsize;
1359 cmd = drive->command;
1360 if(use48){
1361 outb(cmdport+Count, drive->count>>8);
1362 outb(cmdport+Count, drive->count);
1363 outb(cmdport+Lbalo, lba>>24);
1364 outb(cmdport+Lbalo, lba);
1365 outb(cmdport+Lbamid, lba>>32);
1366 outb(cmdport+Lbamid, lba>>8);
1367 outb(cmdport+Lbahi, lba>>40);
1368 outb(cmdport+Lbahi, lba>>16);
1369 outb(cmdport+Dh, drive->dev|Lba);
1370 cmd = cmd48[cmd];
1371
1372 if(DEBUG & Dbg48BIT)
1373 print("using 48-bit commands\n");
1374 }
1375 else{
1376 outb(cmdport+Count, drive->count);
1377 outb(cmdport+Sector, s);
1378 outb(cmdport+Cyllo, c);
1379 outb(cmdport+Cylhi, c>>8);
1380 outb(cmdport+Dh, drive->dev|h);
1381 }
1382 ctlr->done = 0;
1383 ctlr->curdrive = drive;
1384 ctlr->command = drive->command; /* debugging */
1385 outb(cmdport+Command, cmd);
1386
1387 switch(drive->command){
1388 case Cws:
1389 case Cwsm:
1390 microdelay(1);
1391 /* 10*1000 for flash ide drives - maybe detect them? */
1392 as = ataready(cmdport, ctlport, 0, Bsy, Drq|Err, 10*1000);
1393 if(as < 0 || (as & Err)){
1394 iunlock(ctlr);
1395 return -1;
1396 }
1397 len = drive->block;
1398 if(drive->data+len > drive->limit)
1399 len = drive->limit-drive->data;
1400 outss(cmdport+Data, drive->data, len/2);
1401 break;
1402
1403 case Crd:
1404 dcinvalid(drive->data, drive->count*drive->secsize);
1405 atadmastart(ctlr, drive->write);
1406 break;
1407
1408 case Cwd:
1409 dcflush(drive->data, drive->count*drive->secsize);
1410 atadmastart(ctlr, drive->write);
1411 break;
1412 }
1413 iunlock(ctlr);
1414
1415 return 0;
1416 }
1417
1418 static int
atagenioretry(Drive * drive)1419 atagenioretry(Drive* drive)
1420 {
1421 if(drive->dmactl){
1422 drive->dmactl = 0;
1423 print("atagenioretry: disabling dma\n");
1424 }
1425 else if(drive->rwmctl)
1426 drive->rwmctl = 0;
1427 else
1428 return atasetsense(drive, SDcheck, 4, 8, drive->error);
1429
1430 return SDretry;
1431 }
1432
1433 static int
atagenio(Drive * drive,uchar * cmd,int clen)1434 atagenio(Drive* drive, uchar* cmd, int clen)
1435 {
1436 uchar *p;
1437 Ctlr *ctlr;
1438 vlong lba, len;
1439 int count, maxio;
1440
1441 /*
1442 * Map SCSI commands into ATA commands for discs.
1443 * Fail any command with a LUN except INQUIRY which
1444 * will return 'logical unit not supported'.
1445 */
1446 if((cmd[1]>>5) && cmd[0] != 0x12)
1447 return atasetsense(drive, SDcheck, 0x05, 0x25, 0);
1448
1449 switch(cmd[0]){
1450 default:
1451 return atasetsense(drive, SDcheck, 0x05, 0x20, 0);
1452
1453 case 0x00: /* test unit ready */
1454 return SDok;
1455
1456 case 0x03: /* request sense */
1457 if(cmd[4] < sizeof(drive->sense))
1458 len = cmd[4];
1459 else
1460 len = sizeof(drive->sense);
1461 if(drive->data && drive->dlen >= len){
1462 memmove(drive->data, drive->sense, len);
1463 drive->data += len;
1464 }
1465 return SDok;
1466
1467 case 0x12: /* inquiry */
1468 if(cmd[4] < sizeof(drive->inquiry))
1469 len = cmd[4];
1470 else
1471 len = sizeof(drive->inquiry);
1472 if(drive->data && drive->dlen >= len){
1473 memmove(drive->data, drive->inquiry, len);
1474 drive->data += len;
1475 }
1476 return SDok;
1477
1478 case 0x1B: /* start/stop unit */
1479 /*
1480 * NOP for now, can use the power management feature
1481 * set later.
1482 */
1483 return SDok;
1484
1485 case 0x25: /* read capacity */
1486 if((cmd[1] & 0x01) || cmd[2] || cmd[3])
1487 return atasetsense(drive, SDcheck, 0x05, 0x24, 0);
1488 if(drive->data == nil || drive->dlen < 8)
1489 return atasetsense(drive, SDcheck, 0x05, 0x20, 1);
1490 /*
1491 * Read capacity returns the LBA of the last sector.
1492 */
1493 len = drive->sectors-1;
1494 p = drive->data;
1495 *p++ = len>>24;
1496 *p++ = len>>16;
1497 *p++ = len>>8;
1498 *p++ = len;
1499 len = drive->secsize;
1500 *p++ = len>>24;
1501 *p++ = len>>16;
1502 *p++ = len>>8;
1503 *p = len;
1504 drive->data += 8;
1505 return SDok;
1506
1507 case 0x9E: /* long read capacity */
1508 if((cmd[1] & 0x01) || cmd[2] || cmd[3])
1509 return atasetsense(drive, SDcheck, 0x05, 0x24, 0);
1510 if(drive->data == nil || drive->dlen < 8)
1511 return atasetsense(drive, SDcheck, 0x05, 0x20, 1);
1512 /*
1513 * Read capacity returns the LBA of the last sector.
1514 */
1515 len = drive->sectors-1;
1516 p = drive->data;
1517 *p++ = len>>56;
1518 *p++ = len>>48;
1519 *p++ = len>>40;
1520 *p++ = len>>32;
1521 *p++ = len>>24;
1522 *p++ = len>>16;
1523 *p++ = len>>8;
1524 *p++ = len;
1525 len = drive->secsize;
1526 *p++ = len>>24;
1527 *p++ = len>>16;
1528 *p++ = len>>8;
1529 *p = len;
1530 drive->data += 12;
1531 return SDok;
1532
1533 case 0x28: /* read (10) */
1534 case 0x88: /* long read (16) */
1535 case 0x2a: /* write (10) */
1536 case 0x8a: /* long write (16) */
1537 case 0x2e: /* write and verify (10) */
1538 break;
1539
1540 case 0x5A:
1541 return atamodesense(drive, cmd);
1542 }
1543
1544 ctlr = drive->ctlr;
1545 if(clen == 16){
1546 /* ata commands only go to 48-bit lba */
1547 if(cmd[2] || cmd[3])
1548 return atasetsense(drive, SDcheck, 3, 0xc, 2);
1549 lba = (uvlong)cmd[4]<<40 | (uvlong)cmd[5]<<32;
1550 lba |= cmd[6]<<24 | cmd[7]<<16 | cmd[8]<<8 | cmd[9];
1551 count = cmd[10]<<24 | cmd[11]<<16 | cmd[12]<<8 | cmd[13];
1552 }else{
1553 lba = cmd[2]<<24 | cmd[3]<<16 | cmd[4]<<8 | cmd[5];
1554 count = cmd[7]<<8 | cmd[8];
1555 }
1556 if(drive->data == nil)
1557 return SDok;
1558 if(drive->dlen < count*drive->secsize)
1559 count = drive->dlen/drive->secsize;
1560 qlock(ctlr);
1561 if(ctlr->maxio)
1562 maxio = ctlr->maxio;
1563 else if(drive->flags & Lba48)
1564 maxio = 65536;
1565 else
1566 maxio = 256;
1567 while(count){
1568 if(count > maxio)
1569 drive->count = maxio;
1570 else
1571 drive->count = count;
1572 if(atageniostart(drive, lba)){
1573 ilock(ctlr);
1574 atanop(drive, 0);
1575 iunlock(ctlr);
1576 qunlock(ctlr);
1577 return atagenioretry(drive);
1578 }
1579
1580 while(waserror())
1581 ;
1582 tsleep(ctlr, atadone, ctlr, 60*1000);
1583 poperror();
1584 if(!ctlr->done){
1585 /*
1586 * What should the above timeout be? In
1587 * standby and sleep modes it could take as
1588 * long as 30 seconds for a drive to respond.
1589 * Very hard to get out of this cleanly.
1590 */
1591 atadumpstate(drive, cmd, lba, count);
1592 ataabort(drive, 1);
1593 qunlock(ctlr);
1594 return atagenioretry(drive);
1595 }
1596
1597 if(drive->status & Err){
1598 qunlock(ctlr);
1599 return atasetsense(drive, SDcheck, 4, 8, drive->error);
1600 }
1601 count -= drive->count;
1602 lba += drive->count;
1603 }
1604 qunlock(ctlr);
1605
1606 return SDok;
1607 }
1608
1609 static int
atario(SDreq * r)1610 atario(SDreq* r)
1611 {
1612 Ctlr *ctlr;
1613 Drive *drive;
1614 SDunit *unit;
1615 uchar cmd10[10], *cmdp, *p;
1616 int clen, reqstatus, status;
1617
1618 unit = r->unit;
1619 if((ctlr = unit->dev->ctlr) == nil || ctlr->drive[unit->subno] == nil){
1620 r->status = SDtimeout;
1621 return SDtimeout;
1622 }
1623 drive = ctlr->drive[unit->subno];
1624
1625 /*
1626 * Most SCSI commands can be passed unchanged except for
1627 * the padding on the end. The few which require munging
1628 * are not used internally. Mode select/sense(6) could be
1629 * converted to the 10-byte form but it's not worth the
1630 * effort. Read/write(6) are easy.
1631 */
1632 switch(r->cmd[0]){
1633 case 0x08: /* read */
1634 case 0x0A: /* write */
1635 cmdp = cmd10;
1636 memset(cmdp, 0, sizeof(cmd10));
1637 cmdp[0] = r->cmd[0]|0x20;
1638 cmdp[1] = r->cmd[1] & 0xE0;
1639 cmdp[5] = r->cmd[3];
1640 cmdp[4] = r->cmd[2];
1641 cmdp[3] = r->cmd[1] & 0x0F;
1642 cmdp[8] = r->cmd[4];
1643 clen = sizeof(cmd10);
1644 break;
1645
1646 default:
1647 cmdp = r->cmd;
1648 clen = r->clen;
1649 break;
1650 }
1651
1652 qlock(drive);
1653 retry:
1654 drive->write = r->write;
1655 drive->data = r->data;
1656 drive->dlen = r->dlen;
1657
1658 drive->status = 0;
1659 drive->error = 0;
1660 if(drive->pkt)
1661 status = atapktio(drive, cmdp, clen);
1662 else
1663 status = atagenio(drive, cmdp, clen);
1664 if(status == SDretry){
1665 if(DbgDEBUG)
1666 print("%s: retry: dma %8.8uX rwm %4.4uX\n",
1667 unit->name, drive->dmactl, drive->rwmctl);
1668 goto retry;
1669 }
1670 if(status == SDok){
1671 atasetsense(drive, SDok, 0, 0, 0);
1672 if(drive->data){
1673 p = r->data;
1674 r->rlen = drive->data - p;
1675 }
1676 else
1677 r->rlen = 0;
1678 }
1679 else if(status == SDcheck && !(r->flags & SDnosense)){
1680 drive->write = 0;
1681 memset(cmd10, 0, sizeof(cmd10));
1682 cmd10[0] = 0x03;
1683 cmd10[1] = r->lun<<5;
1684 cmd10[4] = sizeof(r->sense)-1;
1685 drive->data = r->sense;
1686 drive->dlen = sizeof(r->sense)-1;
1687 drive->status = 0;
1688 drive->error = 0;
1689 if(drive->pkt)
1690 reqstatus = atapktio(drive, cmd10, 6);
1691 else
1692 reqstatus = atagenio(drive, cmd10, 6);
1693 if(reqstatus == SDok){
1694 r->flags |= SDvalidsense;
1695 atasetsense(drive, SDok, 0, 0, 0);
1696 }
1697 }
1698 qunlock(drive);
1699 r->status = status;
1700 if(status != SDok)
1701 return status;
1702
1703 /*
1704 * Fix up any results.
1705 * Many ATAPI CD-ROMs ignore the LUN field completely and
1706 * return valid INQUIRY data. Patch the response to indicate
1707 * 'logical unit not supported' if the LUN is non-zero.
1708 */
1709 switch(cmdp[0]){
1710 case 0x12: /* inquiry */
1711 if((p = r->data) == nil)
1712 break;
1713 if((cmdp[1]>>5) && (!drive->pkt || (p[0] & 0x1F) == 0x05))
1714 p[0] = 0x7F;
1715 /*FALLTHROUGH*/
1716 default:
1717 break;
1718 }
1719
1720 return SDok;
1721 }
1722
1723 /* interrupt ack hack for intel ich controllers */
1724 static void
ichirqack(Ctlr * ctlr)1725 ichirqack(Ctlr *ctlr)
1726 {
1727 int bmiba;
1728
1729 bmiba = ctlr->bmiba;
1730 if(bmiba)
1731 outb(bmiba+Bmisx, inb(bmiba+Bmisx));
1732 }
1733
1734 static void
atainterrupt(Ureg *,void * arg)1735 atainterrupt(Ureg*, void* arg)
1736 {
1737 Ctlr *ctlr;
1738 Drive *drive;
1739 int cmdport, len, status;
1740
1741 ctlr = arg;
1742
1743 ilock(ctlr);
1744 if(inb(ctlr->ctlport+As) & Bsy){
1745 ctlr->intbusy++;
1746 iunlock(ctlr);
1747 if(DEBUG & DbgBsy)
1748 print("IBsy+");
1749 return;
1750 }
1751 cmdport = ctlr->cmdport;
1752 status = inb(cmdport+Status);
1753 if((drive = ctlr->curdrive) == nil){
1754 ctlr->intnil++;
1755 if(ctlr->irqack != nil)
1756 ctlr->irqack(ctlr);
1757 iunlock(ctlr);
1758 if((DEBUG & DbgINL) && ctlr->command != Cedd)
1759 print("Inil%2.2uX+", ctlr->command);
1760 return;
1761 }
1762
1763 ctlr->intok++;
1764
1765 if(status & Err)
1766 drive->error = inb(cmdport+Error);
1767 else switch(drive->command){
1768 default:
1769 drive->error = Abrt;
1770 break;
1771
1772 case Crs:
1773 case Crsm:
1774 drive->intrd++;
1775 if(!(status & Drq)){
1776 drive->error = Abrt;
1777 break;
1778 }
1779 len = drive->block;
1780 if(drive->data+len > drive->limit)
1781 len = drive->limit-drive->data;
1782 inss(cmdport+Data, drive->data, len/2);
1783 drive->data += len;
1784 if(drive->data >= drive->limit)
1785 ctlr->done = 1;
1786 break;
1787
1788 case Cws:
1789 case Cwsm:
1790 drive->intwr++;
1791 len = drive->block;
1792 if(drive->data+len > drive->limit)
1793 len = drive->limit-drive->data;
1794 drive->data += len;
1795 if(drive->data >= drive->limit){
1796 ctlr->done = 1;
1797 break;
1798 }
1799 if(!(status & Drq)){
1800 drive->error = Abrt;
1801 break;
1802 }
1803 len = drive->block;
1804 if(drive->data+len > drive->limit)
1805 len = drive->limit-drive->data;
1806 outss(cmdport+Data, drive->data, len/2);
1807 break;
1808
1809 case Cpkt:
1810 atapktinterrupt(drive);
1811 break;
1812
1813 case Crd:
1814 drive->intrd++;
1815 /* fall through */
1816 case Cwd:
1817 if (drive->command == Cwd)
1818 drive->intwr++;
1819 atadmainterrupt(drive, drive->count*drive->secsize);
1820 break;
1821
1822 case Cstandby:
1823 ctlr->done = 1;
1824 break;
1825 }
1826 if(ctlr->irqack != nil)
1827 ctlr->irqack(ctlr);
1828 iunlock(ctlr);
1829
1830 if(drive->error){
1831 status |= Err;
1832 ctlr->done = 1;
1833 }
1834
1835 if(ctlr->done){
1836 ctlr->curdrive = nil;
1837 drive->status = status;
1838 wakeup(ctlr);
1839 }
1840 }
1841
1842 static SDev*
atapnp(void)1843 atapnp(void)
1844 {
1845 Ctlr *ctlr;
1846 Pcidev *p;
1847 SDev *legacy[2], *sdev, *head, *tail;
1848 int channel, ispc87415, maxio, pi, r, span;
1849 void (*irqack)(Ctlr*);
1850
1851 irqack = nil;
1852 legacy[0] = legacy[1] = head = tail = nil;
1853 if(sdev = ataprobe(0x1F0, 0x3F4, IL8259, IrqATA0)){
1854 head = tail = sdev;
1855 legacy[0] = sdev;
1856 }
1857 if(sdev = ataprobe(0x170, 0x374, IL8259, IrqATA1)){
1858 if(head != nil)
1859 tail->next = sdev;
1860 else
1861 head = sdev;
1862 tail = sdev;
1863 legacy[1] = sdev;
1864 }
1865
1866 p = nil;
1867 while(p = pcimatch(p, 0, 0)){
1868 /*
1869 * Look for devices with the correct class and sub-class
1870 * code and known device and vendor ID; add native-mode
1871 * channels to the list to be probed, save info for the
1872 * compatibility mode channels.
1873 * Note that the legacy devices should not be considered
1874 * PCI devices by the interrupt controller.
1875 * For both native and legacy, save info for busmastering
1876 * if capable.
1877 * Promise Ultra ATA/66 (PDC20262) appears to
1878 * 1) give a sub-class of 'other mass storage controller'
1879 * instead of 'IDE controller', regardless of whether it's
1880 * the only controller or not;
1881 * 2) put 0 in the programming interface byte (probably
1882 * as a consequence of 1) above).
1883 * Sub-class code 0x04 is 'RAID controller', e.g. VIA VT8237.
1884 */
1885 if(p->ccrb != Pcibcstore)
1886 continue;
1887 if(p->ccru != Pciscide)
1888 continue;
1889 pi = p->ccrp;
1890 ispc87415 = 0;
1891 maxio = 0;
1892 span = BMspan;
1893
1894 switch((p->did<<16)|p->vid){
1895 default:
1896 continue;
1897
1898 case (0x0002<<16)|0x100B: /* NS PC87415 */
1899 /*
1900 * Disable interrupts on both channels until
1901 * after they are probed for drives.
1902 * This must be called before interrupts are
1903 * enabled because the IRQ may be shared.
1904 */
1905 ispc87415 = 1;
1906 pcicfgw32(p, 0x40, 0x00000300);
1907 break;
1908 case (0x1000<<16)|0x1042: /* PC-Tech RZ1000 */
1909 /*
1910 * Turn off prefetch. Overkill, but cheap.
1911 */
1912 r = pcicfgr32(p, 0x40);
1913 r &= ~0x2000;
1914 pcicfgw32(p, 0x40, r);
1915 break;
1916 case (0x4379<<16)|0x1002: /* ATI SB400 SATA*/
1917 case (0x437a<<16)|0x1002: /* ATI SB400 SATA */
1918 case (0x439c<<16)|0x1002: /* ATI 439c SATA*/
1919 case (0x3373<<16)|0x105A: /* Promise 20378 RAID */
1920 case (0x4D30<<16)|0x105A: /* Promise PDC202xx */
1921 case (0x4D38<<16)|0x105A: /* Promise PDC20262 */
1922 case (0x4D68<<16)|0x105A: /* Promise PDC20268 */
1923 case (0x4D69<<16)|0x105A: /* Promise Ultra/133 TX2 */
1924 case (0x3112<<16)|0x1095: /* SiI 3112 SATA/RAID */
1925 case (0x3149<<16)|0x1106: /* VIA VT8237 SATA/RAID */
1926 maxio = 15;
1927 span = 8*1024;
1928 /*FALLTHROUGH*/
1929 case (0x0680<<16)|0x1095: /* SiI 0680/680A PATA133 ATAPI/RAID */
1930 case (0x3114<<16)|0x1095: /* SiI 3114 SATA/RAID */
1931 pi = 0x85;
1932 break;
1933 case (0x0004<<16)|0x1103: /* HighPoint HPT366 */
1934 pi = 0x85;
1935 /*
1936 * Turn off fast interrupt prediction.
1937 */
1938 if((r = pcicfgr8(p, 0x51)) & 0x80)
1939 pcicfgw8(p, 0x51, r & ~0x80);
1940 if((r = pcicfgr8(p, 0x55)) & 0x80)
1941 pcicfgw8(p, 0x55, r & ~0x80);
1942 break;
1943 case (0x0640<<16)|0x1095: /* CMD 640B */
1944 /*
1945 * Bugfix code here...
1946 */
1947 break;
1948 case (0x7441<<16)|0x1022: /* AMD 768 */
1949 /*
1950 * Set:
1951 * 0x41 prefetch, postwrite;
1952 * 0x43 FIFO configuration 1/2 and 1/2;
1953 * 0x44 status register read retry;
1954 * 0x46 DMA read and end of sector flush.
1955 */
1956 r = pcicfgr8(p, 0x41);
1957 pcicfgw8(p, 0x41, r|0xF0);
1958 r = pcicfgr8(p, 0x43);
1959 pcicfgw8(p, 0x43, (r & 0x90)|0x2A);
1960 r = pcicfgr8(p, 0x44);
1961 pcicfgw8(p, 0x44, r|0x08);
1962 r = pcicfgr8(p, 0x46);
1963 pcicfgw8(p, 0x46, (r & 0x0C)|0xF0);
1964 /*FALLTHROUGH*/
1965 case (0x7401<<16)|0x1022: /* AMD 755 Cobra */
1966 case (0x7409<<16)|0x1022: /* AMD 756 Viper */
1967 case (0x7410<<16)|0x1022: /* AMD 766 Viper Plus */
1968 case (0x7469<<16)|0x1022: /* AMD 3111 */
1969 /*
1970 * This can probably be lumped in with the 768 above.
1971 */
1972 /*FALLTHROUGH*/
1973 case (0x209A<<16)|0x1022: /* AMD CS5536 */
1974 case (0x01BC<<16)|0x10DE: /* nVidia nForce1 */
1975 case (0x0065<<16)|0x10DE: /* nVidia nForce2 */
1976 case (0x0085<<16)|0x10DE: /* nVidia nForce2 MCP */
1977 case (0x00E3<<16)|0x10DE: /* nVidia nForce2 250 SATA */
1978 case (0x00D5<<16)|0x10DE: /* nVidia nForce3 */
1979 case (0x00E5<<16)|0x10DE: /* nVidia nForce3 Pro */
1980 case (0x00EE<<16)|0x10DE: /* nVidia nForce3 250 SATA */
1981 case (0x0035<<16)|0x10DE: /* nVidia nForce3 MCP */
1982 case (0x0053<<16)|0x10DE: /* nVidia nForce4 */
1983 case (0x0054<<16)|0x10DE: /* nVidia nForce4 SATA */
1984 case (0x0055<<16)|0x10DE: /* nVidia nForce4 SATA */
1985 case (0x0266<<16)|0x10DE: /* nVidia nForce4 430 SATA */
1986 case (0x0267<<16)|0x10DE: /* nVidia nForce 55 MCP SATA */
1987 case (0x03EC<<16)|0x10DE: /* nVidia nForce 61 MCP SATA */
1988 case (0x0448<<16)|0x10DE: /* nVidia nForce 65 MCP SATA */
1989 case (0x0560<<16)|0x10DE: /* nVidia nForce 69 MCP SATA */
1990 /*
1991 * Ditto, although it may have a different base
1992 * address for the registers (0x50?).
1993 */
1994 /*FALLTHROUGH*/
1995 case (0x4376<<16)|0x1002: /* ATI SB400 PATA */
1996 case (0x438c<<16)|0x1002: /* ATI SB600 PATA */
1997 break;
1998 case (0x0211<<16)|0x1166: /* ServerWorks IB6566 */
1999 {
2000 Pcidev *sb;
2001
2002 sb = pcimatch(nil, 0x1166, 0x0200);
2003 if(sb == nil)
2004 break;
2005 r = pcicfgr32(sb, 0x64);
2006 r &= ~0x2000;
2007 pcicfgw32(sb, 0x64, r);
2008 }
2009 span = 32*1024;
2010 break;
2011 case (0x0502<<17)|0x100B: /* NS SC1100/SCx200 */
2012 case (0x5229<<16)|0x10B9: /* ALi M1543 */
2013 case (0x5288<<16)|0x10B9: /* ALi M5288 SATA */
2014 case (0x5513<<16)|0x1039: /* SiS 962 */
2015 case (0x0646<<16)|0x1095: /* CMD 646 */
2016 case (0x0571<<16)|0x1106: /* VIA 82C686 */
2017 case (0x2363<<16)|0x197b: /* JMicron SATA */
2018 break; /* TODO: verify that this should be here; wasn't in original patch */
2019 case (0x1230<<16)|0x8086: /* 82371FB (PIIX) */
2020 case (0x7010<<16)|0x8086: /* 82371SB (PIIX3) */
2021 case (0x7111<<16)|0x8086: /* 82371[AE]B (PIIX4[E]) */
2022 case (0x2411<<16)|0x8086: /* 82801AA (ICH) */
2023 case (0x2421<<16)|0x8086: /* 82801AB (ICH0) */
2024 case (0x244A<<16)|0x8086: /* 82801BA (ICH2, Mobile) */
2025 case (0x244B<<16)|0x8086: /* 82801BA (ICH2, High-End) */
2026 case (0x248A<<16)|0x8086: /* 82801CA (ICH3, Mobile) */
2027 case (0x248B<<16)|0x8086: /* 82801CA (ICH3, High-End) */
2028 case (0x24CA<<16)|0x8086: /* 82801DBM (ICH4, Mobile) */
2029 case (0x24CB<<16)|0x8086: /* 82801DB (ICH4, High-End) */
2030 case (0x24D1<<16)|0x8086: /* 82801EB/ER (ICH5 High-End) */
2031 case (0x24DB<<16)|0x8086: /* 82801EB (ICH5) */
2032 case (0x25A3<<16)|0x8086: /* 6300ESB (E7210) */
2033 case (0x2653<<16)|0x8086: /* 82801FBM (ICH6M) */
2034 case (0x266F<<16)|0x8086: /* 82801FB (ICH6) */
2035 case (0x27DF<<16)|0x8086: /* 82801G SATA (ICH7) */
2036 case (0x27C0<<16)|0x8086: /* 82801GB SATA AHCI (ICH7) */
2037 // case (0x27C4<<16)|0x8086: /* 82801GBM SATA (ICH7) */
2038 case (0x27C5<<16)|0x8086: /* 82801GBM SATA AHCI (ICH7) */
2039 case (0x2920<<16)|0x8086: /* 82801(IB)/IR/IH/IO SATA IDE (ICH9) */
2040 case (0x3a20<<16)|0x8086: /* 82801JI (ICH10) */
2041 case (0x3a26<<16)|0x8086: /* 82801JI (ICH10) */
2042 irqack = ichirqack;
2043 break;
2044 }
2045
2046 for(channel = 0; channel < 2; channel++){
2047 if(pi & (1<<(2*channel))){
2048 sdev = ataprobe(p->mem[0+2*channel].bar & ~0x01,
2049 p->mem[1+2*channel].bar & ~0x01,
2050 ILpci, pcisubirq(p->tbdf));
2051 if(sdev == nil)
2052 continue;
2053
2054 ctlr = sdev->ctlr;
2055 if(ispc87415) {
2056 // ctlr->ienable = pc87415ienable;
2057 print("pc87415disable: not yet implemented\n");
2058 }
2059
2060 if(head != nil)
2061 tail->next = sdev;
2062 else
2063 head = sdev;
2064 tail = sdev;
2065 ctlr->tbdf = p->tbdf;
2066 }
2067 else if((sdev = legacy[channel]) == nil)
2068 continue;
2069 else
2070 ctlr = sdev->ctlr;
2071
2072 ctlr->pcidev = p;
2073 ctlr->maxio = maxio;
2074 ctlr->span = span;
2075 ctlr->irqack = irqack;
2076 if(!(pi & 0x80))
2077 continue;
2078 ctlr->bmiba = (p->mem[4].bar & ~0x01) + channel*8;
2079 }
2080 }
2081
2082 return head;
2083 }
2084
2085 static SDev*
atalegacy(int port,int irq)2086 atalegacy(int port, int irq)
2087 {
2088 return ataprobe(port, port+0x204, IL8259, irq);
2089 }
2090
2091 static int
ataenable(SDev * sdev)2092 ataenable(SDev* sdev)
2093 {
2094 Ctlr *ctlr;
2095 char name[32];
2096
2097 ctlr = sdev->ctlr;
2098
2099 if(ctlr->bmiba){
2100 if(ctlr->pcidev != nil)
2101 pcisetbme(ctlr->pcidev);
2102 ctlr->prdt = mallocalign(Nprd*sizeof(Prd), 4, 0, 4*1024);
2103 if(ctlr->prdt == nil)
2104 error(Enomem);
2105 }
2106 snprint(name, sizeof(name), "%s (%s)", sdev->name, sdev->ifc->name);
2107 intrenable(ctlr->irq, atainterrupt, ctlr, ctlr->subirq);
2108 outb(ctlr->ctlport+Dc, 0);
2109 if(ctlr->ienable)
2110 ctlr->ienable(ctlr);
2111
2112 return 1;
2113 }
2114
2115 static int
atadisable(SDev * sdev)2116 atadisable(SDev *sdev)
2117 {
2118 Ctlr *ctlr;
2119 char name[32];
2120
2121 ctlr = sdev->ctlr;
2122 outb(ctlr->ctlport+Dc, Nien); /* disable interrupts */
2123 if (ctlr->idisable)
2124 ctlr->idisable(ctlr);
2125 snprint(name, sizeof(name), "%s (%s)", sdev->name, sdev->ifc->name);
2126 // intrdisable(ctlr->irq, atainterrupt, ctlr, ctlr->subirq); // XXX
2127 if (ctlr->bmiba) {
2128 if (ctlr->pcidev)
2129 pciclrbme(ctlr->pcidev);
2130 sdfree(ctlr->prdt);
2131 }
2132 return 0;
2133 }
2134
2135 static int
atarctl(SDunit * unit,char * p,int l)2136 atarctl(SDunit* unit, char* p, int l)
2137 {
2138 int n;
2139 Ctlr *ctlr;
2140 Drive *drive;
2141
2142 if((ctlr = unit->dev->ctlr) == nil || ctlr->drive[unit->subno] == nil)
2143 return 0;
2144 drive = ctlr->drive[unit->subno];
2145
2146 qlock(drive);
2147 n = snprint(p, l, "config %4.4uX capabilities %4.4uX",
2148 drive->info[Iconfig], drive->info[Icapabilities]);
2149 if(drive->dma)
2150 n += snprint(p+n, l-n, " dma %8.8uX dmactl %8.8uX",
2151 drive->dma, drive->dmactl);
2152 if(drive->rwm)
2153 n += snprint(p+n, l-n, " rwm %ud rwmctl %ud",
2154 drive->rwm, drive->rwmctl);
2155 if(drive->flags&Lba48)
2156 n += snprint(p+n, l-n, " lba48always %s",
2157 (drive->flags&Lba48always) ? "on" : "off");
2158 n += snprint(p+n, l-n, "\n");
2159 n += snprint(p+n, l-n, "interrupts read %lud write %lud cmds %lud\n",
2160 drive->intrd, drive->intwr, drive->intcmd);
2161 if(drive->sectors){
2162 n += snprint(p+n, l-n, "geometry %lld %d",
2163 drive->sectors, drive->secsize);
2164 if(drive->pkt == 0)
2165 n += snprint(p+n, l-n, " %d %d %d",
2166 drive->c, drive->h, drive->s);
2167 n += snprint(p+n, l-n, "\n");
2168 }
2169 qunlock(drive);
2170
2171 return n;
2172 }
2173
2174 static int
atawctl(SDunit * unit,Cmdbuf * cb)2175 atawctl(SDunit* unit, Cmdbuf* cb)
2176 {
2177 int period;
2178 Ctlr *ctlr;
2179 Drive *drive;
2180
2181 if((ctlr = unit->dev->ctlr) == nil || ctlr->drive[unit->subno] == nil)
2182 return 0;
2183 drive = ctlr->drive[unit->subno];
2184
2185 qlock(drive);
2186 if(waserror()){
2187 qunlock(drive);
2188 nexterror();
2189 }
2190
2191 /*
2192 * Dma and rwm control is passive at the moment,
2193 * i.e. it is assumed that the hardware is set up
2194 * correctly already either by the BIOS or when
2195 * the drive was initially identified.
2196 */
2197 if(strcmp(cb->f[0], "dma") == 0){
2198 if(cb->nf != 2 || drive->dma == 0)
2199 error(Ebadctl);
2200 if(strcmp(cb->f[1], "on") == 0)
2201 drive->dmactl = drive->dma;
2202 else if(strcmp(cb->f[1], "off") == 0)
2203 drive->dmactl = 0;
2204 else
2205 error(Ebadctl);
2206 }
2207 else if(strcmp(cb->f[0], "rwm") == 0){
2208 if(cb->nf != 2 || drive->rwm == 0)
2209 error(Ebadctl);
2210 if(strcmp(cb->f[1], "on") == 0)
2211 drive->rwmctl = drive->rwm;
2212 else if(strcmp(cb->f[1], "off") == 0)
2213 drive->rwmctl = 0;
2214 else
2215 error(Ebadctl);
2216 }
2217 else if(strcmp(cb->f[0], "standby") == 0){
2218 switch(cb->nf){
2219 default:
2220 error(Ebadctl);
2221 case 2:
2222 period = strtol(cb->f[1], 0, 0);
2223 if(period && (period < 30 || period > 240*5))
2224 error(Ebadctl);
2225 period /= 5;
2226 break;
2227 }
2228 if(atastandby(drive, period) != SDok)
2229 error(Ebadctl);
2230 }
2231 else if(strcmp(cb->f[0], "lba48always") == 0){
2232 if(cb->nf != 2 || !(drive->flags&Lba48))
2233 error(Ebadctl);
2234 if(strcmp(cb->f[1], "on") == 0)
2235 drive->flags |= Lba48always;
2236 else if(strcmp(cb->f[1], "off") == 0)
2237 drive->flags &= ~Lba48always;
2238 else
2239 error(Ebadctl);
2240 }
2241 else
2242 error(Ebadctl);
2243 qunlock(drive);
2244 poperror();
2245
2246 return 0;
2247 }
2248
2249 SDifc sdataifc = {
2250 "ata", /* name */
2251
2252 atapnp, /* pnp */
2253 atalegacy, /* legacy */
2254 ataenable, /* enable */
2255 atadisable, /* disable */
2256
2257 scsiverify, /* verify */
2258 scsionline, /* online */
2259 atario, /* rio */
2260 atarctl, /* rctl */
2261 atawctl, /* wctl */
2262
2263 scsibio, /* bio */
2264 nil, /* probe */
2265 ataclear, /* clear */
2266 atastat, /* rtopctl */
2267 nil, /* wtopctl */
2268 };
2269