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