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