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