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