FreeBSD/Linux Kernel Cross Reference
sys/bitsy/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
13 extern SDifc sdataifc;
14
15 //BUG?
16 #define PCIWADDR(x) ((ulong)(x))
17
18 enum {
19 DbgCONFIG = 0x01, /* detected drive config info */
20 DbgIDENTIFY = 0x02, /* detected drive identify info */
21 DbgSTATE = 0x04, /* dump state on panic */
22 DbgPROBE = 0x08, /* trace device probing */
23 DbgDEBUG = 0x80, /* the current problem... */
24 };
25 #define DEBUG (DbgDEBUG|DbgSTATE|DbgCONFIG)
26
27 enum { /* I/O ports */
28 Data = 0,
29 Error = 1, /* (read) */
30 Features = 1, /* (write) */
31 Count = 2, /* sector count */
32 Ir = 2, /* interrupt reason (PACKET) */
33 Sector = 3, /* sector number, LBA<7-0> */
34 Cyllo = 4, /* cylinder low, LBA<15-8> */
35 Bytelo = 4, /* byte count low (PACKET) */
36 Cylhi = 5, /* cylinder high, LBA<23-16> */
37 Bytehi = 5, /* byte count hi (PACKET) */
38 Dh = 6, /* Device/Head, LBA<32-14> */
39 Status = 7, /* (read) */
40 Command = 7, /* (write) */
41
42 As = 2, /* Alternate Status (read) */
43 Dc = 2, /* Device Control (write) */
44 };
45
46 enum { /* Error */
47 Med = 0x01, /* Media error */
48 Ili = 0x01, /* command set specific (PACKET) */
49 Nm = 0x02, /* No Media */
50 Eom = 0x02, /* command set specific (PACKET) */
51 Abrt = 0x04, /* Aborted command */
52 Mcr = 0x08, /* Media Change Request */
53 Idnf = 0x10, /* no user-accessible address */
54 Mc = 0x20, /* Media Change */
55 Unc = 0x40, /* Uncorrectable data error */
56 Wp = 0x40, /* Write Protect */
57 Icrc = 0x80, /* Interface CRC error */
58 };
59
60 enum { /* Features */
61 Dma = 0x01, /* data transfer via DMA (PACKET) */
62 Ovl = 0x02, /* command overlapped (PACKET) */
63 };
64
65 enum { /* Interrupt Reason */
66 Cd = 0x01, /* Command/Data */
67 Io = 0x02, /* I/O direction */
68 Rel = 0x04, /* Bus Release */
69 };
70
71 enum { /* Device/Head */
72 Dev0 = 0xA0, /* Master */
73 Dev1 = 0xB0, /* Slave */
74 Lba = 0x40, /* LBA mode */
75 };
76
77 enum { /* Status, Alternate Status */
78 Err = 0x01, /* Error */
79 Chk = 0x01, /* Check error (PACKET) */
80 Drq = 0x08, /* Data Request */
81 Dsc = 0x10, /* Device Seek Complete */
82 Serv = 0x10, /* Service */
83 Df = 0x20, /* Device Fault */
84 Dmrd = 0x20, /* DMA ready (PACKET) */
85 Drdy = 0x40, /* Device Ready */
86 Bsy = 0x80, /* Busy */
87 };
88
89 enum { /* Command */
90 Cnop = 0x00, /* NOP */
91 Cdr = 0x08, /* Device Reset */
92 Crs = 0x20, /* Read Sectors */
93 Cws = 0x30, /* Write Sectors */
94 Cedd = 0x90, /* Execute Device Diagnostics */
95 Cpkt = 0xA0, /* Packet */
96 Cidpkt = 0xA1, /* Identify Packet Device */
97 Crsm = 0xC4, /* Read Multiple */
98 Cwsm = 0xC5, /* Write Multiple */
99 Csm = 0xC6, /* Set Multiple */
100 Crdq = 0xC7, /* Read DMA queued */
101 Crd = 0xC8, /* Read DMA */
102 Cwd = 0xCA, /* Write DMA */
103 Cwdq = 0xCC, /* Write DMA queued */
104 Cstandby = 0xE2, /* Standby */
105 Cid = 0xEC, /* Identify Device */
106 Csf = 0xEF, /* Set Features */
107 };
108
109 enum { /* Device Control */
110 Nien = 0x02, /* (not) Interrupt Enable */
111 Srst = 0x04, /* Software Reset */
112 };
113
114 enum { /* PCI Configuration Registers */
115 Bmiba = 0x20, /* Bus Master Interface Base Address */
116 Idetim = 0x40, /* IE Timing */
117 Sidetim = 0x44, /* Slave IE Timing */
118 Udmactl = 0x48, /* Ultra DMA/33 Control */
119 Udmatim = 0x4A, /* Ultra DMA/33 Timing */
120 };
121
122 enum { /* Bus Master IDE I/O Ports */
123 Bmicx = 0, /* Command */
124 Bmisx = 2, /* Status */
125 Bmidtpx = 4, /* Descriptor Table Pointer */
126 };
127
128 enum { /* Bmicx */
129 Ssbm = 0x01, /* Start/Stop Bus Master */
130 Rwcon = 0x08, /* Read/Write Control */
131 };
132
133 enum { /* Bmisx */
134 Bmidea = 0x01, /* Bus Master IDE Active */
135 Idedmae = 0x02, /* IDE DMA Error (R/WC) */
136 Ideints = 0x04, /* IDE Interrupt Status (R/WC) */
137 Dma0cap = 0x20, /* Drive 0 DMA Capable */
138 Dma1cap = 0x40, /* Drive 0 DMA Capable */
139 };
140 enum { /* Physical Region Descriptor */
141 PrdEOT = 0x80000000, /* Bus Master IDE Active */
142 };
143
144 enum { /* offsets into the identify info. */
145 Iconfig = 0, /* general configuration */
146 Ilcyl = 1, /* logical cylinders */
147 Ilhead = 3, /* logical heads */
148 Ilsec = 6, /* logical sectors per logical track */
149 Iserial = 10, /* serial number */
150 Ifirmware = 23, /* firmware revision */
151 Imodel = 27, /* model number */
152 Imaxrwm = 47, /* max. read/write multiple sectors */
153 Icapabilities = 49, /* capabilities */
154 Istandby = 50, /* device specific standby timer */
155 Ipiomode = 51, /* PIO data transfer mode number */
156 Ivalid = 53,
157 Iccyl = 54, /* cylinders if (valid&0x01) */
158 Ichead = 55, /* heads if (valid&0x01) */
159 Icsec = 56, /* sectors if (valid&0x01) */
160 Iccap = 57, /* capacity if (valid&0x01) */
161 Irwm = 59, /* read/write multiple */
162 Ilba0 = 60, /* LBA size */
163 Ilba1 = 61, /* LBA size */
164 Imwdma = 63, /* multiword DMA mode */
165 Iapiomode = 64, /* advanced PIO modes supported */
166 Iminmwdma = 65, /* min. multiword DMA cycle time */
167 Irecmwdma = 66, /* rec. multiword DMA cycle time */
168 Iminpio = 67, /* min. PIO cycle w/o flow control */
169 Iminiordy = 68, /* min. PIO cycle with IORDY */
170 Ipcktbr = 71, /* time from PACKET to bus release */
171 Iserbsy = 72, /* time from SERVICE to !Bsy */
172 Iqdepth = 75, /* max. queue depth */
173 Imajor = 80, /* major version number */
174 Iminor = 81, /* minor version number */
175 Icsfs = 82, /* command set/feature supported */
176 Icsfe = 85, /* command set/feature enabled */
177 Iudma = 88, /* ultra DMA mode */
178 Ierase = 89, /* time for security erase */
179 Ieerase = 90, /* time for enhanced security erase */
180 Ipower = 91, /* current advanced power management */
181 Irmsn = 127, /* removable status notification */
182 Istatus = 128, /* security status */
183 };
184
185 typedef struct Ctlr Ctlr;
186 typedef struct Drive Drive;
187
188 typedef struct Prd {
189 ulong pa; /* Physical Base Address */
190 int count;
191 } Prd;
192
193 enum {
194 Nprd = SDmaxio/(64*1024)+2,
195 };
196
197 typedef struct Ctlr {
198 int cmdport;
199 int ctlport;
200 int irq;
201 int tbdf;
202 int bmiba; /* bus master interface base address */
203
204 void (*ienable)(Ctlr*);
205 SDev* sdev;
206
207 Drive* drive[2];
208
209 Prd* prdt; /* physical region descriptor table */
210
211 QLock; /* current command */
212 Drive* curdrive;
213 int command; /* last command issued (debugging) */
214 Rendez;
215 int done;
216
217 Lock; /* register access */
218 } Ctlr;
219
220 typedef struct Drive {
221 Ctlr* ctlr;
222
223 int dev;
224 ushort info[256];
225 int c; /* cylinder */
226 int h; /* head */
227 int s; /* sector */
228 int sectors; /* total */
229 int secsize; /* sector size */
230
231 int dma; /* DMA R/W possible */
232 int dmactl;
233 int rwm; /* read/write multiple possible */
234 int rwmctl;
235
236 int pkt; /* PACKET device, length of pktcmd */
237 uchar pktcmd[16];
238 int pktdma; /* this PACKET command using dma */
239
240 uchar sense[18];
241 uchar inquiry[48];
242
243 QLock; /* drive access */
244 int command; /* current command */
245 int write;
246 uchar* data;
247 int dlen;
248 uchar* limit;
249 int count; /* sectors */
250 int block; /* R/W bytes per block */
251 int status;
252 int error;
253 } Drive;
254
255
256
257 static void
258 atadumpstate(Drive* drive, uchar* cmd, int lba, int count)
259 {
260 Prd *prd;
261 Ctlr *ctlr;
262 int i, bmiba;
263
264 if(!(DEBUG & DbgSTATE)){
265 USED(drive, cmd, lba, count);
266 return;
267 }
268
269 ctlr = drive->ctlr;
270 print("command %2.2uX\n", ctlr->command);
271 print("data %8.8p limit %8.8p dlen %d status %uX error %uX\n",
272 drive->data, drive->limit, drive->dlen,
273 drive->status, drive->error);
274 if(cmd != nil){
275 print("lba %d -> %d, count %d -> %d (%d)\n",
276 (cmd[2]<<24)|(cmd[3]<<16)|(cmd[4]<<8)|cmd[5], lba,
277 (cmd[7]<<8)|cmd[8], count, drive->count);
278 }
279 if(!(inb(ctlr->ctlport+As) & Bsy)){
280 for(i = 1; i < 7; i++)
281 print(" 0x%2.2uX", inb(ctlr->cmdport+i));
282 print(" 0x%2.2uX\n", inb(ctlr->ctlport+As));
283 }
284 if(drive->command == Cwd || drive->command == Crd){
285 bmiba = ctlr->bmiba;
286 prd = ctlr->prdt;
287 print("bmicx %2.2uX bmisx %2.2uX prdt %8.8p\n",
288 inb(bmiba+Bmicx), inb(bmiba+Bmisx), prd);
289 for(;;){
290 print("pa 0x%8.8luX count %8.8uX\n",
291 prd->pa, prd->count);
292 if(prd->count & PrdEOT)
293 break;
294 prd++;
295 }
296 }
297 }
298
299 static int
300 atadebug(int cmdport, int ctlport, char* fmt, ...)
301 {
302 int i, n;
303 va_list arg;
304 char buf[PRINTSIZE];
305
306 if(!(DEBUG & DbgPROBE)){
307 USED(cmdport, ctlport, fmt);
308 return 0;
309 }
310
311 va_start(arg, fmt);
312 n = vseprint(buf, buf+sizeof(buf), fmt, arg) - buf;
313 va_end(arg);
314
315 if(cmdport){
316 if(buf[n-1] == '\n')
317 n--;
318 n += snprint(buf+n, PRINTSIZE-n, " ataregs 0x%uX:",
319 cmdport);
320 for(i = Features; i < Command; i++)
321 n += snprint(buf+n, PRINTSIZE-n, " 0x%2.2uX",
322 inb(cmdport+i));
323 if(ctlport)
324 n += snprint(buf+n, PRINTSIZE-n, " 0x%2.2uX",
325 inb(ctlport+As));
326 n += snprint(buf+n, PRINTSIZE-n, "\n");
327 }
328 putstrn(buf, n);
329
330 return n;
331 }
332
333 static int
334 ataready(int cmdport, int ctlport, int dev, int reset, int ready, int micro)
335 {
336 int as;
337
338 atadebug(cmdport, ctlport, "ataready: dev %uX reset %uX ready %uX",
339 dev, reset, ready);
340
341 for(;;){
342 /*
343 * Wait for the controller to become not busy and
344 * possibly for a status bit to become true (usually
345 * Drdy). Must change to the appropriate device
346 * register set if necessary before testing for ready.
347 * Always run through the loop at least once so it
348 * can be used as a test for !Bsy.
349 */
350 as = inb(ctlport+As);
351 if((as & reset) == 0){
352 if(dev){
353 outb(cmdport+Dh, dev);
354 dev = 0;
355 }
356 else if(ready == 0 || (as & ready)){
357 atadebug(0, 0, "ataready: %d 0x%2.2uX\n", micro, as);
358 return as;
359 }
360 }
361 if(micro-- <= 0){
362 atadebug(0, 0, "ataready: %d 0x%2.2uX\n", micro, as);
363 break;
364 }
365 microdelay(4);
366 }
367 atadebug(cmdport, ctlport, "ataready: timeout");
368
369 return -1;
370 }
371
372 static int
373 atacsf(Drive* drive, vlong csf, int supported)
374 {
375 ushort *info;
376 int cmdset, i, x;
377
378 if(supported)
379 info = &drive->info[Icsfs];
380 else
381 info = &drive->info[Icsfe];
382
383 for(i = 0; i < 3; i++){
384 x = (csf>>(16*i)) & 0xFFFF;
385 if(x == 0)
386 continue;
387 cmdset = info[i];
388 if(cmdset == 0 || cmdset == 0xFFFF)
389 return 0;
390 return cmdset & x;
391 }
392
393 return 0;
394 }
395
396 static int
397 atadone(void* arg)
398 {
399 return ((Ctlr*)arg)->done;
400 }
401
402 static int
403 atarwmmode(Drive* drive, int cmdport, int ctlport, int dev)
404 {
405 int as, maxrwm, rwm;
406
407 maxrwm = (drive->info[Imaxrwm] & 0xFF);
408 if(maxrwm == 0)
409 return 0;
410
411 /*
412 * Sometimes drives come up with the current count set
413 * to 0; if so, set a suitable value, otherwise believe
414 * the value in Irwm if the 0x100 bit is set.
415 */
416 if(drive->info[Irwm] & 0x100)
417 rwm = (drive->info[Irwm] & 0xFF);
418 else
419 rwm = 0;
420 if(rwm == 0)
421 rwm = maxrwm;
422 if(rwm > 16)
423 rwm = 16;
424 if(ataready(cmdport, ctlport, dev, Bsy|Drq, Drdy, 102*1000) < 0)
425 return 0;
426 outb(cmdport+Count, rwm);
427 outb(cmdport+Command, Csm);
428 microdelay(4);
429 as = ataready(cmdport, ctlport, 0, Bsy, Drdy|Df|Err, 1000);
430 inb(cmdport+Status);
431 if(as < 0 || (as & (Df|Err)))
432 return 0;
433
434 drive->rwm = rwm;
435
436 return rwm;
437 }
438
439 static int
440 atadmamode(Drive* drive)
441 {
442 int dma;
443
444 /*
445 * Check if any DMA mode enabled.
446 * Assumes the BIOS has picked and enabled the best.
447 * This is completely passive at the moment, no attempt is
448 * made to ensure the hardware is correctly set up.
449 */
450 dma = drive->info[Imwdma] & 0x0707;
451 drive->dma = (dma>>8) & dma;
452 if(drive->dma == 0 && (drive->info[Ivalid] & 0x04)){
453 dma = drive->info[Iudma] & 0x1F1F;
454 drive->dma = (dma>>8) & dma;
455 if(drive->dma)
456 drive->dma |= 'U'<<16;
457 }
458
459 return dma;
460 }
461
462 static int
463 ataidentify(int cmdport, int ctlport, int dev, int pkt, void* info)
464 {
465 int as, command, drdy;
466
467 if(pkt){
468 command = Cidpkt;
469 drdy = 0;
470 }
471 else{
472 command = Cid;
473 drdy = Drdy;
474 }
475 as = ataready(cmdport, ctlport, dev, Bsy|Drq, drdy, 103*1000);
476 if(as < 0)
477 return as;
478 outb(cmdport+Command, command);
479 microdelay(4);
480
481 as = ataready(cmdport, ctlport, 0, Bsy, Drq|Err, 400*1000);
482 if(as < 0)
483 return -1;
484 if(as & Err)
485 return as;
486
487 memset(info, 0, 512);
488 inss(cmdport+Data, info, 256);
489 inb(cmdport+Status);
490
491 if(DEBUG & DbgIDENTIFY){
492 int i;
493 ushort *sp;
494
495 sp = (ushort*)info;
496 for(i = 0; i < 32; i++){
497 if(i && (i%16) == 0)
498 print("\n");
499 print(" %4.4uX", *sp);
500 sp++;
501 }
502 print("\n");
503 }
504
505 return 0;
506 }
507
508 static Drive*
509 atadrive(int cmdport, int ctlport, int dev)
510 {
511 ushort *sp;
512 Drive *drive;
513 int as, i, pkt;
514 uchar buf[512], *p;
515
516 atadebug(0, 0, "identify: port 0x%uX dev 0x%2.2uX\n", cmdport, dev);
517 pkt = 1;
518 retry:
519 as = ataidentify(cmdport, ctlport, dev, pkt, buf);
520 if(as < 0)
521 return nil;
522 if(as & Err){
523 if(pkt == 0)
524 return nil;
525 pkt = 0;
526 goto retry;
527 }
528
529 if((drive = malloc(sizeof(Drive))) == nil)
530 return nil;
531 drive->dev = dev;
532 memmove(drive->info, buf, sizeof(drive->info));
533 drive->sense[0] = 0x70;
534 drive->sense[7] = sizeof(drive->sense)-7;
535
536 drive->inquiry[2] = 2;
537 drive->inquiry[3] = 2;
538 drive->inquiry[4] = sizeof(drive->inquiry)-4;
539 p = &drive->inquiry[8];
540 sp = &drive->info[Imodel];
541 for(i = 0; i < 20; i++){
542 *p++ = *sp>>8;
543 *p++ = *sp++;
544 }
545
546 drive->secsize = 512;
547 if(drive->info[Iconfig] != 0x848A && (drive->info[Iconfig] & 0xC000) == 0x8000){
548 if(drive->info[Iconfig] & 0x01)
549 drive->pkt = 16;
550 else
551 drive->pkt = 12;
552 }
553 else{
554 if(drive->info[Ivalid] & 0x0001){
555 drive->c = drive->info[Ilcyl];
556 drive->h = drive->info[Ilhead];
557 drive->s = drive->info[Ilsec];
558 }
559 else{
560 drive->c = drive->info[Iccyl];
561 drive->h = drive->info[Ichead];
562 drive->s = drive->info[Icsec];
563 }
564 if(drive->info[Icapabilities] & 0x0200){
565 drive->sectors = (drive->info[Ilba1]<<16)
566 |drive->info[Ilba0];
567 drive->dev |= Lba;
568 }
569 else
570 drive->sectors = drive->c*drive->h*drive->s;
571 atarwmmode(drive, cmdport, ctlport, dev);
572 }
573 atadmamode(drive);
574
575 if(DEBUG & DbgCONFIG){
576 print("dev %2.2uX port %uX config %4.4uX capabilities %4.4uX",
577 dev, cmdport,
578 drive->info[Iconfig], drive->info[Icapabilities]);
579 print(" mwdma %4.4uX", drive->info[Imwdma]);
580 if(drive->info[Ivalid] & 0x04)
581 print(" udma %4.4uX", drive->info[Iudma]);
582 print(" dma %8.8uX rwm %ud\n", drive->dma, drive->rwm);
583 }
584
585 return drive;
586 }
587
588 static void
589 atasrst(int ctlport)
590 {
591 /*
592 * Srst is a big stick and may cause problems if further
593 * commands are tried before the drives become ready again.
594 * Also, there will be problems here if overlapped commands
595 * are ever supported.
596 */
597 microdelay(20);
598 outb(ctlport+Dc, Srst);
599 microdelay(20);
600 outb(ctlport+Dc, 0);
601 microdelay(4*1000);
602 }
603
604 static SDev*
605 ataprobe(int cmdport, int ctlport, int irq)
606 {
607 Ctlr* ctlr;
608 SDev *sdev;
609 Drive *drive;
610 int dev, error, rhi, rlo;
611
612 /*
613 * Try to detect a floating bus.
614 * Bsy should be cleared. If not, see if the cylinder registers
615 * are read/write capable.
616 * If the master fails, try the slave to catch slave-only
617 * configurations.
618 * There's no need to restore the tested registers as they will
619 * be reset on any detected drives by the Cedd command.
620 * All this indicates is that there is at least one drive on the
621 * controller; when the non-existent drive is selected in a
622 * single-drive configuration the registers of the existing drive
623 * are often seen, only command execution fails.
624 */
625 dev = Dev0;
626 if(inb(ctlport+As) & Bsy){
627 outb(cmdport+Dh, dev);
628 microdelay(5);
629 trydev1:
630 atadebug(cmdport, ctlport, "ataprobe bsy");
631 outb(cmdport+Cyllo, 0xAA);
632 outb(cmdport+Cylhi, 0x55);
633 outb(cmdport+Sector, 0xFF);
634 rlo = inb(cmdport+Cyllo);
635 rhi = inb(cmdport+Cylhi);
636 if(rlo != 0xAA && (rlo == 0xFF || rhi != 0x55)){
637 if(dev == Dev1){
638 release:
639 return nil;
640 }
641 dev = Dev1;
642 if(ataready(cmdport, ctlport, dev, Bsy, 0, 20*1000) < 0)
643 goto trydev1;
644 }
645 }
646
647 /*
648 * Disable interrupts on any detected controllers.
649 */
650 outb(ctlport+Dc, Nien);
651 tryedd1:
652 if(ataready(cmdport, ctlport, dev, Bsy|Drq, 0, 105*1000) < 0){
653 /*
654 * There's something there, but it didn't come up clean,
655 * so try hitting it with a big stick. The timing here is
656 * wrong but this is a last-ditch effort and it sometimes
657 * gets some marginal hardware back online.
658 */
659 atasrst(ctlport);
660 if(ataready(cmdport, ctlport, dev, Bsy|Drq, 0, 106*1000) < 0)
661 goto release;
662 }
663
664 /*
665 * Can only get here if controller is not busy.
666 * If there are drives Bsy will be set within 400nS,
667 * must wait 2mS before testing Status.
668 * Wait for the command to complete (6 seconds max).
669 */
670 outb(cmdport+Command, Cedd);
671 delay(5);
672 if(ataready(cmdport, ctlport, dev, Bsy|Drq, 0, 6*1000*1000) < 0)
673 goto release;
674
675 /*
676 * If bit 0 of the error register is set then the selected drive
677 * exists. This is enough to detect single-drive configurations.
678 * However, if the master exists there is no way short of executing
679 * a command to determine if a slave is present.
680 * It appears possible to get here testing Dev0 although it doesn't
681 * exist and the EDD won't take, so try again with Dev1.
682 */
683 error = inb(cmdport+Error);
684 atadebug(cmdport, ctlport, "ataprobe: dev %uX", dev);
685 if((error & ~0x80) != 0x01){
686 if(dev == Dev1)
687 goto release;
688 dev = Dev1;
689 goto tryedd1;
690 }
691
692 /*
693 * At least one drive is known to exist, try to
694 * identify it. If that fails, don't bother checking
695 * any further.
696 * If the one drive found is Dev0 and the EDD command
697 * didn't indicate Dev1 doesn't exist, check for it.
698 */
699 if((drive = atadrive(cmdport, ctlport, dev)) == nil)
700 goto release;
701 if((ctlr = malloc(sizeof(Ctlr))) == nil){
702 free(drive);
703 goto release;
704 }
705 if((sdev = malloc(sizeof(SDev))) == nil){
706 free(ctlr);
707 free(drive);
708 goto release;
709 }
710 drive->ctlr = ctlr;
711 if(dev == Dev0){
712 ctlr->drive[0] = drive;
713 #ifdef notdef
714 if(!(error & 0x80)){
715 /*
716 * Always leave Dh pointing to a valid drive,
717 * otherwise a subsequent call to ataready on
718 * this controller may try to test a bogus Status.
719 * Ataprobe is the only place possibly invalid
720 * drives should be selected.
721 */
722 drive = atadrive(cmdport, ctlport, Dev1);
723 if(drive != nil){
724 drive->ctlr = ctlr;
725 ctlr->drive[1] = drive;
726 }
727 else{
728 outb(cmdport+Dh, Dev0);
729 microdelay(1);
730 }
731 }
732 #endif
733 }
734 else
735 ctlr->drive[1] = drive;
736
737 ctlr->cmdport = cmdport;
738 ctlr->ctlport = ctlport;
739 ctlr->irq = irq;
740 ctlr->tbdf = -1;
741 ctlr->command = Cedd; /* debugging */
742
743 sdev->ifc = &sdataifc;
744 sdev->ctlr = ctlr;
745 sdev->idno = 'C';
746 sdev->nunit = 1;
747 ctlr->sdev = sdev;
748
749 return sdev;
750 }
751
752 static int
753 atasetsense(Drive* drive, int status, int key, int asc, int ascq)
754 {
755 drive->sense[2] = key;
756 drive->sense[12] = asc;
757 drive->sense[13] = ascq;
758
759 return status;
760 }
761
762 static int
763 atastandby(Drive* drive, int period)
764 {
765 Ctlr* ctlr;
766 int cmdport, done;
767
768 ctlr = drive->ctlr;
769 drive->command = Cstandby;
770 qlock(ctlr);
771
772 cmdport = ctlr->cmdport;
773 ilock(ctlr);
774 outb(cmdport+Count, period);
775 outb(cmdport+Dh, drive->dev);
776 ctlr->done = 0;
777 ctlr->curdrive = drive;
778 ctlr->command = Cstandby; /* debugging */
779 outb(cmdport+Command, Cstandby);
780 iunlock(ctlr);
781
782 while(waserror())
783 ;
784 tsleep(ctlr, atadone, ctlr, 30*1000);
785 poperror();
786
787 done = ctlr->done;
788 qunlock(ctlr);
789
790 if(!done || (drive->status & Err))
791 return atasetsense(drive, SDcheck, 4, 8, drive->error);
792 return SDok;
793 }
794
795 static int
796 atamodesense(Drive* drive, uchar* cmd)
797 {
798 int len;
799
800 /*
801 * Fake a vendor-specific request with page code 0,
802 * return the drive info.
803 */
804 if((cmd[2] & 0x3F) != 0 && (cmd[2] & 0x3F) != 0x3F)
805 return atasetsense(drive, SDcheck, 0x05, 0x24, 0);
806 len = (cmd[7]<<8)|cmd[8];
807 if(len == 0)
808 return SDok;
809 if(len < 8+sizeof(drive->info))
810 return atasetsense(drive, SDcheck, 0x05, 0x1A, 0);
811 if(drive->data == nil || drive->dlen < len)
812 return atasetsense(drive, SDcheck, 0x05, 0x20, 1);
813 memset(drive->data, 0, 8);
814 drive->data[0] = sizeof(drive->info)>>8;
815 drive->data[1] = sizeof(drive->info);
816 memmove(drive->data+8, drive->info, sizeof(drive->info));
817 drive->data += 8+sizeof(drive->info);
818
819 return SDok;
820 }
821
822 static void
823 atanop(Drive* drive, int subcommand)
824 {
825 Ctlr* ctlr;
826 int as, cmdport, ctlport, timeo;
827
828 /*
829 * Attempt to abort a command by using NOP.
830 * In response, the drive is supposed to set Abrt
831 * in the Error register, set (Drdy|Err) in Status
832 * and clear Bsy when done. However, some drives
833 * (e.g. ATAPI Zip) just go Bsy then clear Status
834 * when done, hence the timeout loop only on Bsy
835 * and the forced setting of drive->error.
836 */
837 ctlr = drive->ctlr;
838 cmdport = ctlr->cmdport;
839 outb(cmdport+Features, subcommand);
840 outb(cmdport+Dh, drive->dev);
841 ctlr->command = Cnop; /* debugging */
842 outb(cmdport+Command, Cnop);
843
844 microdelay(1);
845 ctlport = ctlr->ctlport;
846 for(timeo = 0; timeo < 1000; timeo++){
847 as = inb(ctlport+As);
848 if(!(as & Bsy))
849 break;
850 microdelay(1);
851 }
852 drive->error |= Abrt;
853 }
854
855 static void
856 ataabort(Drive* drive, int dolock)
857 {
858 /*
859 * If NOP is available (packet commands) use it otherwise
860 * must try a software reset.
861 */
862 if(dolock)
863 ilock(drive->ctlr);
864 if(atacsf(drive, 0x0000000000004000LL, 0))
865 atanop(drive, 0);
866 else{
867 atasrst(drive->ctlr->ctlport);
868 drive->error |= Abrt;
869 }
870 if(dolock)
871 iunlock(drive->ctlr);
872 }
873
874 static int
875 atadmasetup(Drive* drive, int )
876 {
877 drive->dmactl = 0;
878 return -1;
879
880 #ifdef notdef
881 Prd *prd;
882 ulong pa;
883 Ctlr *ctlr;
884 int bmiba, bmisx, count;
885
886 pa = PCIWADDR(drive->data);
887 if(pa & 0x03)
888 return -1;
889 ctlr = drive->ctlr;
890 prd = ctlr->prdt;
891
892 /*
893 * Sometimes drives identify themselves as being DMA capable
894 * although they are not on a busmastering controller.
895 */
896 if(prd == nil){
897 drive->dmactl = 0;
898 return -1;
899 }
900
901 for(;;){
902 prd->pa = pa;
903 count = 64*1024 - (pa & 0xFFFF);
904 if(count >= len){
905 prd->count = PrdEOT|(len & 0xFFFF);
906 break;
907 }
908 prd->count = count;
909 len -= count;
910 pa += count;
911 prd++;
912 }
913
914 bmiba = ctlr->bmiba;
915 outl(bmiba+Bmidtpx, PCIWADDR(ctlr->prdt));
916 if(drive->write)
917 outb(ctlr->bmiba+Bmicx, 0);
918 else
919 outb(ctlr->bmiba+Bmicx, Rwcon);
920 bmisx = inb(bmiba+Bmisx);
921 outb(bmiba+Bmisx, bmisx|Ideints|Idedmae);
922
923 return 0;
924 #endif
925 }
926
927 static void
928 atadmastart(Ctlr* ctlr, int write)
929 {
930 if(write)
931 outb(ctlr->bmiba+Bmicx, Ssbm);
932 else
933 outb(ctlr->bmiba+Bmicx, Rwcon|Ssbm);
934 }
935
936 static int
937 atadmastop(Ctlr* ctlr)
938 {
939 int bmiba;
940
941 bmiba = ctlr->bmiba;
942 outb(bmiba+Bmicx, inb(bmiba+Bmicx) & ~Ssbm);
943
944 return inb(bmiba+Bmisx);
945 }
946
947 static void
948 atadmainterrupt(Drive* drive, int count)
949 {
950 Ctlr* ctlr;
951 int bmiba, bmisx;
952
953 ctlr = drive->ctlr;
954 bmiba = ctlr->bmiba;
955 bmisx = inb(bmiba+Bmisx);
956 switch(bmisx & (Ideints|Idedmae|Bmidea)){
957 case Bmidea:
958 /*
959 * Data transfer still in progress, nothing to do
960 * (this should never happen).
961 */
962 return;
963
964 case Ideints:
965 case Ideints|Bmidea:
966 /*
967 * Normal termination, tidy up.
968 */
969 drive->data += count;
970 break;
971
972 default:
973 /*
974 * What's left are error conditions (memory transfer
975 * problem) and the device is not done but the PRD is
976 * exhausted. For both cases must somehow tell the
977 * drive to abort.
978 */
979 ataabort(drive, 0);
980 break;
981 }
982 atadmastop(ctlr);
983 ctlr->done = 1;
984 }
985
986 static void
987 atapktinterrupt(Drive* drive)
988 {
989 Ctlr* ctlr;
990 int cmdport, len;
991
992 ctlr = drive->ctlr;
993 cmdport = ctlr->cmdport;
994 switch(inb(cmdport+Ir) & (/*Rel|*/Io|Cd)){
995 case Cd:
996 outss(cmdport+Data, drive->pktcmd, drive->pkt/2);
997 break;
998
999 case 0:
1000 len = (inb(cmdport+Bytehi)<<8)|inb(cmdport+Bytelo);
1001 if(drive->data+len > drive->limit){
1002 atanop(drive, 0);
1003 break;
1004 }
1005 outss(cmdport+Data, drive->data, len/2);
1006 drive->data += len;
1007 break;
1008
1009 case Io:
1010 len = (inb(cmdport+Bytehi)<<8)|inb(cmdport+Bytelo);
1011 if(drive->data+len > drive->limit){
1012 atanop(drive, 0);
1013 break;
1014 }
1015 inss(cmdport+Data, drive->data, len/2);
1016 drive->data += len;
1017 break;
1018
1019 case Io|Cd:
1020 if(drive->pktdma)
1021 atadmainterrupt(drive, drive->dlen);
1022 else
1023 ctlr->done = 1;
1024 break;
1025 }
1026 }
1027
1028 static int
1029 atapktio(Drive* drive, uchar* cmd, int clen)
1030 {
1031 Ctlr *ctlr;
1032 int as, cmdport, ctlport, len, r, timeo;
1033
1034 if(cmd[0] == 0x5A && (cmd[2] & 0x3F) == 0)
1035 return atamodesense(drive, cmd);
1036
1037 r = SDok;
1038
1039 drive->command = Cpkt;
1040 memmove(drive->pktcmd, cmd, clen);
1041 memset(drive->pktcmd+clen, 0, drive->pkt-clen);
1042 drive->limit = drive->data+drive->dlen;
1043
1044 ctlr = drive->ctlr;
1045 cmdport = ctlr->cmdport;
1046 ctlport = ctlr->ctlport;
1047
1048 qlock(ctlr);
1049
1050 if(ataready(cmdport, ctlport, drive->dev, Bsy|Drq, 0, 107*1000) < 0){
1051 qunlock(ctlr);
1052 return -1;
1053 }
1054
1055 ilock(ctlr);
1056 if(drive->dlen && drive->dmactl && !atadmasetup(drive, drive->dlen))
1057 drive->pktdma = Dma;
1058 else
1059 drive->pktdma = 0;
1060
1061 outb(cmdport+Features, drive->pktdma);
1062 outb(cmdport+Count, 0);
1063 outb(cmdport+Sector, 0);
1064 len = 16*drive->secsize;
1065 outb(cmdport+Bytelo, len);
1066 outb(cmdport+Bytehi, len>>8);
1067 outb(cmdport+Dh, drive->dev);
1068 ctlr->done = 0;
1069 ctlr->curdrive = drive;
1070 ctlr->command = Cpkt; /* debugging */
1071 if(drive->pktdma)
1072 atadmastart(ctlr, drive->write);
1073 outb(cmdport+Command, Cpkt);
1074
1075 if((drive->info[Iconfig] & 0x0060) != 0x0020){
1076 microdelay(1);
1077 as = ataready(cmdport, ctlport, 0, Bsy, Drq|Chk, 4*1000);
1078 if(as < 0)
1079 r = SDtimeout;
1080 else if(as & Chk)
1081 r = SDcheck;
1082 else
1083 atapktinterrupt(drive);
1084 }
1085 iunlock(ctlr);
1086
1087 while(waserror())
1088 ;
1089 if(!drive->pktdma)
1090 sleep(ctlr, atadone, ctlr);
1091 else for(timeo = 0; !ctlr->done; timeo++){
1092 tsleep(ctlr, atadone, ctlr, 1000);
1093 if(ctlr->done)
1094 break;
1095 ilock(ctlr);
1096 atadmainterrupt(drive, 0);
1097 if(!drive->error && timeo > 10){
1098 ataabort(drive, 0);
1099 atadmastop(ctlr);
1100 drive->dmactl = 0;
1101 drive->error |= Abrt;
1102 }
1103 if(drive->error){
1104 drive->status |= Chk;
1105 ctlr->curdrive = nil;
1106 }
1107 iunlock(ctlr);
1108 }
1109 poperror();
1110
1111 qunlock(ctlr);
1112
1113 if(drive->status & Chk)
1114 r = SDcheck;
1115
1116 return r;
1117 }
1118
1119 static int
1120 atageniostart(Drive* drive, int lba)
1121 {
1122 Ctlr *ctlr;
1123 int as, c, cmdport, ctlport, h, len, s;
1124
1125 if(drive->dev & Lba){
1126 c = (lba>>8) & 0xFFFF;
1127 h = (lba>>24) & 0x0F;
1128 s = lba & 0xFF;
1129 }
1130 else{
1131 c = lba/(drive->s*drive->h);
1132 h = ((lba/drive->s) % drive->h);
1133 s = (lba % drive->s) + 1;
1134 }
1135
1136 ctlr = drive->ctlr;
1137 cmdport = ctlr->cmdport;
1138 ctlport = ctlr->ctlport;
1139 if(ataready(cmdport, ctlport, drive->dev, Bsy|Drq, 0, 101*1000) < 0)
1140 return -1;
1141
1142 ilock(ctlr);
1143 if(drive->dmactl && !atadmasetup(drive, drive->count*drive->secsize)){
1144 if(drive->write)
1145 drive->command = Cwd;
1146 else
1147 drive->command = Crd;
1148 }
1149 else if(drive->rwmctl){
1150 drive->block = drive->rwm*drive->secsize;
1151 if(drive->write)
1152 drive->command = Cwsm;
1153 else
1154 drive->command = Crsm;
1155 }
1156 else{
1157 drive->block = drive->secsize;
1158 if(drive->write)
1159 drive->command = Cws;
1160 else
1161 drive->command = Crs;
1162 }
1163 drive->limit = drive->data + drive->count*drive->secsize;
1164
1165 outb(cmdport+Count, drive->count);
1166 outb(cmdport+Sector, s);
1167 outb(cmdport+Dh, drive->dev|h);
1168 outb(cmdport+Cyllo, c);
1169 outb(cmdport+Cylhi, c>>8);
1170 ctlr->done = 0;
1171 ctlr->curdrive = drive;
1172 ctlr->command = drive->command; /* debugging */
1173 outb(cmdport+Command, drive->command);
1174
1175 switch(drive->command){
1176 case Cws:
1177 case Cwsm:
1178 microdelay(1);
1179 as = ataready(cmdport, ctlport, 0, Bsy, Drq|Err, 1000);
1180 if(as < 0 || (as & Err)){
1181 iunlock(ctlr);
1182 return -1;
1183 }
1184 len = drive->block;
1185 if(drive->data+len > drive->limit)
1186 len = drive->limit-drive->data;
1187 outss(cmdport+Data, drive->data, len/2);
1188 break;
1189
1190 case Crd:
1191 case Cwd:
1192 atadmastart(ctlr, drive->write);
1193 break;
1194 }
1195 iunlock(ctlr);
1196
1197 return 0;
1198 }
1199
1200 static int
1201 atagenioretry(Drive* drive)
1202 {
1203 if(drive->dmactl)
1204 drive->dmactl = 0;
1205 else if(drive->rwmctl)
1206 drive->rwmctl = 0;
1207 else
1208 return atasetsense(drive, SDcheck, 4, 8, drive->error);
1209
1210 return SDretry;
1211 }
1212
1213 static int
1214 atagenio(Drive* drive, uchar* cmd, int)
1215 {
1216 uchar *p;
1217 Ctlr *ctlr;
1218 int count, lba, len;
1219
1220 /*
1221 * Map SCSI commands into ATA commands for discs.
1222 * Fail any command with a LUN except INQUIRY which
1223 * will return 'logical unit not supported'.
1224 */
1225 if((cmd[1]>>5) && cmd[0] != 0x12)
1226 return atasetsense(drive, SDcheck, 0x05, 0x25, 0);
1227
1228 switch(cmd[0]){
1229 default:
1230 return atasetsense(drive, SDcheck, 0x05, 0x20, 0);
1231
1232 case 0x00: /* test unit ready */
1233 return SDok;
1234
1235 case 0x03: /* request sense */
1236 if(cmd[4] < sizeof(drive->sense))
1237 len = cmd[4];
1238 else
1239 len = sizeof(drive->sense);
1240 if(drive->data && drive->dlen >= len){
1241 memmove(drive->data, drive->sense, len);
1242 drive->data += len;
1243 }
1244 return SDok;
1245
1246 case 0x12: /* inquiry */
1247 if(cmd[4] < sizeof(drive->inquiry))
1248 len = cmd[4];
1249 else
1250 len = sizeof(drive->inquiry);
1251 if(drive->data && drive->dlen >= len){
1252 memmove(drive->data, drive->inquiry, len);
1253 drive->data += len;
1254 }
1255 return SDok;
1256
1257 case 0x1B: /* start/stop unit */
1258 /*
1259 * NOP for now, can use the power management feature
1260 * set later.
1261 */
1262 return SDok;
1263
1264 case 0x25: /* read capacity */
1265 if((cmd[1] & 0x01) || cmd[2] || cmd[3])
1266 return atasetsense(drive, SDcheck, 0x05, 0x24, 0);
1267 if(drive->data == nil || drive->dlen < 8)
1268 return atasetsense(drive, SDcheck, 0x05, 0x20, 1);
1269 /*
1270 * Read capacity returns the LBA of the last sector.
1271 */
1272 len = drive->sectors-1;
1273 p = drive->data;
1274 *p++ = len>>24;
1275 *p++ = len>>16;
1276 *p++ = len>>8;
1277 *p++ = len;
1278 len = drive->secsize;
1279 *p++ = len>>24;
1280 *p++ = len>>16;
1281 *p++ = len>>8;
1282 *p = len;
1283 drive->data += 8;
1284 return SDok;
1285
1286 case 0x28: /* read */
1287 case 0x2A: /* write */
1288 break;
1289
1290 case 0x5A:
1291 return atamodesense(drive, cmd);
1292 }
1293
1294 ctlr = drive->ctlr;
1295 lba = (cmd[2]<<24)|(cmd[3]<<16)|(cmd[4]<<8)|cmd[5];
1296 count = (cmd[7]<<8)|cmd[8];
1297 if(drive->data == nil)
1298 return SDok;
1299 if(drive->dlen < count*drive->secsize)
1300 count = drive->dlen/drive->secsize;
1301 qlock(ctlr);
1302 while(count){
1303 if(count > 256)
1304 drive->count = 256;
1305 else
1306 drive->count = count;
1307 if(atageniostart(drive, lba)){
1308 ilock(ctlr);
1309 atanop(drive, 0);
1310 iunlock(ctlr);
1311 qunlock(ctlr);
1312 return atagenioretry(drive);
1313 }
1314
1315 while(waserror())
1316 ;
1317 tsleep(ctlr, atadone, ctlr, 30*1000);
1318 poperror();
1319 if(!ctlr->done){
1320 /*
1321 * What should the above timeout be? In
1322 * standby and sleep modes it could take as
1323 * long as 30 seconds for a drive to respond.
1324 * Very hard to get out of this cleanly.
1325 */
1326 atadumpstate(drive, cmd, lba, count);
1327 ataabort(drive, 1);
1328 qunlock(ctlr);
1329 return atagenioretry(drive);
1330 }
1331
1332 if(drive->status & Err){
1333 qunlock(ctlr);
1334 return atasetsense(drive, SDcheck, 4, 8, drive->error);
1335 }
1336 count -= drive->count;
1337 lba += drive->count;
1338 }
1339 qunlock(ctlr);
1340
1341 return SDok;
1342 }
1343
1344 static int
1345 atario(SDreq* r)
1346 {
1347 Ctlr *ctlr;
1348 Drive *drive;
1349 SDunit *unit;
1350 uchar cmd10[10], *cmdp, *p;
1351 int clen, reqstatus, status;
1352
1353 unit = r->unit;
1354 if((ctlr = unit->dev->ctlr) == nil || ctlr->drive[unit->subno] == nil){
1355 r->status = SDtimeout;
1356 return SDtimeout;
1357 }
1358 drive = ctlr->drive[unit->subno];
1359
1360 /*
1361 * Most SCSI commands can be passed unchanged except for
1362 * the padding on the end. The few which require munging
1363 * are not used internally. Mode select/sense(6) could be
1364 * converted to the 10-byte form but it's not worth the
1365 * effort. Read/write(6) are easy.
1366 */
1367 switch(r->cmd[0]){
1368 case 0x08: /* read */
1369 case 0x0A: /* write */
1370 cmdp = cmd10;
1371 memset(cmdp, 0, sizeof(cmd10));
1372 cmdp[0] = r->cmd[0]|0x20;
1373 cmdp[1] = r->cmd[1] & 0xE0;
1374 cmdp[5] = r->cmd[3];
1375 cmdp[4] = r->cmd[2];
1376 cmdp[3] = r->cmd[1] & 0x0F;
1377 cmdp[8] = r->cmd[4];
1378 clen = sizeof(cmd10);
1379 break;
1380
1381 default:
1382 cmdp = r->cmd;
1383 clen = r->clen;
1384 break;
1385 }
1386
1387 qlock(drive);
1388 retry:
1389 drive->write = r->write;
1390 drive->data = r->data;
1391 drive->dlen = r->dlen;
1392
1393 drive->status = 0;
1394 drive->error = 0;
1395 if(drive->pkt)
1396 status = atapktio(drive, cmdp, clen);
1397 else
1398 status = atagenio(drive, cmdp, clen);
1399 if(status == SDretry){
1400 if(DbgDEBUG)
1401 print("%s: retry: dma %8.8uX rwm %4.4uX\n",
1402 unit->name, drive->dmactl, drive->rwmctl);
1403 goto retry;
1404 }
1405 if(status == SDok){
1406 atasetsense(drive, SDok, 0, 0, 0);
1407 if(drive->data){
1408 p = r->data;
1409 r->rlen = drive->data - p;
1410 }
1411 else
1412 r->rlen = 0;
1413 }
1414 else if(status == SDcheck && !(r->flags & SDnosense)){
1415 drive->write = 0;
1416 memset(cmd10, 0, sizeof(cmd10));
1417 cmd10[0] = 0x03;
1418 cmd10[1] = r->lun<<5;
1419 cmd10[4] = sizeof(r->sense)-1;
1420 drive->data = r->sense;
1421 drive->dlen = sizeof(r->sense)-1;
1422 drive->status = 0;
1423 drive->error = 0;
1424 if(drive->pkt)
1425 reqstatus = atapktio(drive, cmd10, 6);
1426 else
1427 reqstatus = atagenio(drive, cmd10, 6);
1428 if(reqstatus == SDok){
1429 r->flags |= SDvalidsense;
1430 atasetsense(drive, SDok, 0, 0, 0);
1431 }
1432 }
1433 qunlock(drive);
1434 r->status = status;
1435 if(status != SDok)
1436 return status;
1437
1438 /*
1439 * Fix up any results.
1440 * Many ATAPI CD-ROMs ignore the LUN field completely and
1441 * return valid INQUIRY data. Patch the response to indicate
1442 * 'logical unit not supported' if the LUN is non-zero.
1443 */
1444 switch(cmdp[0]){
1445 case 0x12: /* inquiry */
1446 if((p = r->data) == nil)
1447 break;
1448 if((cmdp[1]>>5) && (!drive->pkt || (p[0] & 0x1F) == 0x05))
1449 p[0] = 0x7F;
1450 /*FALLTHROUGH*/
1451 default:
1452 break;
1453 }
1454
1455 return SDok;
1456 }
1457
1458
1459 static void
1460 atainterrupt(Ureg*, void* arg)
1461 {
1462 Ctlr *ctlr;
1463 Drive *drive;
1464 int cmdport, len, status;
1465
1466 ctlr = arg;
1467
1468 ilock(ctlr);
1469 if(inb(ctlr->ctlport+As) & Bsy){
1470 iunlock(ctlr);
1471 if(DEBUG & DbgDEBUG)
1472 print("IBsy+");
1473 return;
1474 }
1475 cmdport = ctlr->cmdport;
1476 status = inb(cmdport+Status);
1477 if((drive = ctlr->curdrive) == nil){
1478 iunlock(ctlr);
1479 if((DEBUG & DbgDEBUG) && ctlr->command != Cedd)
1480 print("Inil%2.2uX/%2.2uX+", ctlr->command, status);
1481 return;
1482 }
1483
1484 if(status & Err)
1485 drive->error = inb(cmdport+Error);
1486 else switch(drive->command){
1487 default:
1488 drive->error = Abrt;
1489 break;
1490
1491 case Crs:
1492 case Crsm:
1493 if(!(status & Drq)){
1494 drive->error = Abrt;
1495 break;
1496 }
1497 len = drive->block;
1498 if(drive->data+len > drive->limit)
1499 len = drive->limit-drive->data;
1500 inss(cmdport+Data, drive->data, len/2);
1501 drive->data += len;
1502 if(drive->data >= drive->limit)
1503 ctlr->done = 1;
1504 break;
1505
1506 case Cws:
1507 case Cwsm:
1508 len = drive->block;
1509 if(drive->data+len > drive->limit)
1510 len = drive->limit-drive->data;
1511 drive->data += len;
1512 if(drive->data >= drive->limit){
1513 ctlr->done = 1;
1514 break;
1515 }
1516 if(!(status & Drq)){
1517 drive->error = Abrt;
1518 break;
1519 }
1520 len = drive->block;
1521 if(drive->data+len > drive->limit)
1522 len = drive->limit-drive->data;
1523 outss(cmdport+Data, drive->data, len/2);
1524 break;
1525
1526 case Cpkt:
1527 atapktinterrupt(drive);
1528 break;
1529
1530 case Crd:
1531 case Cwd:
1532 atadmainterrupt(drive, drive->count*drive->secsize);
1533 break;
1534
1535 case Cstandby:
1536 ctlr->done = 1;
1537 break;
1538 }
1539 iunlock(ctlr);
1540
1541 if(drive->error){
1542 status |= Err;
1543 ctlr->done = 1;
1544 }
1545
1546 if(ctlr->done){
1547 ctlr->curdrive = nil;
1548 drive->status = status;
1549 wakeup(ctlr);
1550 }
1551 }
1552
1553 #ifdef notdef
1554 static SDev*
1555 atapnp(void)
1556 {
1557 int cmdport;
1558 int ctlport;
1559 int irq;
1560
1561 cmdport = 0x200;
1562 ctlport = cmdport + 0x0C;
1563 irq = 10;
1564 return ataprobe(cmdport, ctlport, irq);
1565 }
1566 #endif
1567
1568
1569 static SDev*
1570 atalegacy(int port, int irq)
1571 {
1572 return ataprobe(port, port+0x204, irq);
1573 }
1574
1575 static int ataitype;
1576 static int atairq;
1577 static int
1578 ataenable(SDev* sdev)
1579 {
1580 Ctlr *ctlr;
1581 char name[KNAMELEN];
1582
1583 ctlr = sdev->ctlr;
1584
1585 if(ctlr->bmiba){
1586 ctlr->prdt = xspanalloc(Nprd*sizeof(Prd), 4, 4*1024);
1587 }
1588 snprint(name, KNAMELEN, "%s (%s)", sdev->name, sdev->ifc->name);
1589 // intrenable(ctlr->irq, atainterrupt, ctlr, ctlr->tbdf, name);
1590 outb(ctlr->ctlport+Dc, 0);
1591 intrenable(ataitype, atairq, atainterrupt, ctlr, name);
1592 if(ctlr->ienable)
1593 ctlr->ienable(ctlr);
1594
1595 return 1;
1596 }
1597
1598 static int
1599 atarctl(SDunit* unit, char* p, int l)
1600 {
1601 int n;
1602 Ctlr *ctlr;
1603 Drive *drive;
1604
1605 if((ctlr = unit->dev->ctlr) == nil || ctlr->drive[unit->subno] == nil)
1606 return 0;
1607 drive = ctlr->drive[unit->subno];
1608
1609 qlock(drive);
1610 n = snprint(p, l, "config %4.4uX capabilities %4.4uX",
1611 drive->info[Iconfig], drive->info[Icapabilities]);
1612 if(drive->dma)
1613 n += snprint(p+n, l-n, " dma %8.8uX dmactl %8.8uX",
1614 drive->dma, drive->dmactl);
1615 if(drive->rwm)
1616 n += snprint(p+n, l-n, " rwm %ud rwmctl %ud",
1617 drive->rwm, drive->rwmctl);
1618 n += snprint(p+n, l-n, "\n");
1619 if(unit->sectors){
1620 n += snprint(p+n, l-n, "geometry %llud %ld",
1621 unit->sectors, unit->secsize);
1622 if(drive->pkt == 0)
1623 n += snprint(p+n, l-n, " %d %d %d",
1624 drive->c, drive->h, drive->s);
1625 n += snprint(p+n, l-n, "\n");
1626 }
1627 qunlock(drive);
1628
1629 return n;
1630 }
1631
1632 static int
1633 atawctl(SDunit* unit, Cmdbuf* cb)
1634 {
1635 int period;
1636 Ctlr *ctlr;
1637 Drive *drive;
1638
1639 if((ctlr = unit->dev->ctlr) == nil || ctlr->drive[unit->subno] == nil)
1640 return 0;
1641 drive = ctlr->drive[unit->subno];
1642
1643 qlock(drive);
1644 if(waserror()){
1645 qunlock(drive);
1646 nexterror();
1647 }
1648
1649 /*
1650 * Dma and rwm control is passive at the moment,
1651 * i.e. it is assumed that the hardware is set up
1652 * correctly already either by the BIOS or when
1653 * the drive was initially identified.
1654 */
1655 if(strcmp(cb->f[0], "dma") == 0){
1656 if(cb->nf != 2 || drive->dma == 0)
1657 error(Ebadctl);
1658 if(strcmp(cb->f[1], "on") == 0)
1659 drive->dmactl = drive->dma;
1660 else if(strcmp(cb->f[1], "off") == 0)
1661 drive->dmactl = 0;
1662 else
1663 error(Ebadctl);
1664 }
1665 else if(strcmp(cb->f[0], "rwm") == 0){
1666 if(cb->nf != 2 || drive->rwm == 0)
1667 error(Ebadctl);
1668 if(strcmp(cb->f[1], "on") == 0)
1669 drive->rwmctl = drive->rwm;
1670 else if(strcmp(cb->f[1], "off") == 0)
1671 drive->rwmctl = 0;
1672 else
1673 error(Ebadctl);
1674 }
1675 else if(strcmp(cb->f[0], "standby") == 0){
1676 switch(cb->nf){
1677 default:
1678 error(Ebadctl);
1679 case 2:
1680 period = strtol(cb->f[1], 0, 0);
1681 if(period && (period < 30 || period > 240*5))
1682 error(Ebadctl);
1683 period /= 5;
1684 break;
1685 }
1686 if(atastandby(drive, period) != SDok)
1687 error(Ebadctl);
1688 }
1689 else
1690 error(Ebadctl);
1691 qunlock(drive);
1692 poperror();
1693
1694 return 0;
1695 }
1696
1697 static int
1698 scsitest(SDreq* r)
1699 {
1700 r->write = 0;
1701 memset(r->cmd, 0, sizeof(r->cmd));
1702 r->cmd[1] = r->lun<<5;
1703 r->clen = 6;
1704 r->data = nil;
1705 r->dlen = 0;
1706 r->flags = 0;
1707
1708 r->status = ~0;
1709
1710 return r->unit->dev->ifc->rio(r);
1711 }
1712
1713 static int
1714 scsirio(SDreq* r)
1715 {
1716 /*
1717 * Perform an I/O request, returning
1718 * -1 failure
1719 * 0 ok
1720 * 1 no medium present
1721 * 2 retry
1722 * The contents of r may be altered so the
1723 * caller should re-initialise if necesary.
1724 */
1725 r->status = ~0;
1726 switch(r->unit->dev->ifc->rio(r)){
1727 default:
1728 break;
1729 case SDcheck:
1730 if(!(r->flags & SDvalidsense))
1731 break;
1732 switch(r->sense[2] & 0x0F){
1733 case 0x00: /* no sense */
1734 case 0x01: /* recovered error */
1735 return 2;
1736 case 0x06: /* check condition */
1737 /*
1738 * 0x28 - not ready to ready transition,
1739 * medium may have changed.
1740 * 0x29 - power on or some type of reset.
1741 */
1742 if(r->sense[12] == 0x28 && r->sense[13] == 0)
1743 return 2;
1744 if(r->sense[12] == 0x29)
1745 return 2;
1746 break;
1747 case 0x02: /* not ready */
1748 /*
1749 * If no medium present, bail out.
1750 * If unit is becoming ready, rather than not
1751 * not ready, wait a little then poke it again. */
1752 if(r->sense[12] == 0x3A)
1753 break;
1754 if(r->sense[12] != 0x04 || r->sense[13] != 0x01)
1755 break;
1756
1757 while(waserror())
1758 ;
1759 tsleep(&up->sleep, return0, 0, 500);
1760 poperror();
1761 scsitest(r);
1762 return 2;
1763 default:
1764 break;
1765 }
1766 break;
1767 case SDok:
1768 return 0;
1769 }
1770 return -1;
1771 }
1772
1773
1774 static int
1775 ataverify(SDunit* unit)
1776 {
1777 SDreq *r;
1778 int i, status;
1779 uchar *inquiry;
1780
1781 if((r = malloc(sizeof(SDreq))) == nil)
1782 return 0;
1783 if((inquiry = sdmalloc(sizeof(unit->inquiry))) == nil){
1784 free(r);
1785 return 0;
1786 }
1787 r->unit = unit;
1788 r->lun = 0; /* ??? */
1789
1790 memset(unit->inquiry, 0, sizeof(unit->inquiry));
1791 r->write = 0;
1792 r->cmd[0] = 0x12;
1793 r->cmd[1] = r->lun<<5;
1794 r->cmd[4] = sizeof(unit->inquiry)-1;
1795 r->clen = 6;
1796 r->data = inquiry;
1797 r->dlen = sizeof(unit->inquiry)-1;
1798 r->flags = 0;
1799
1800 r->status = ~0;
1801 if(unit->dev->ifc->rio(r) != SDok){
1802 free(r);
1803 return 0;
1804 }
1805 memmove(unit->inquiry, inquiry, r->dlen);
1806 free(inquiry);
1807
1808 SET(status);
1809 for(i = 0; i < 3; i++){
1810 while((status = scsitest(r)) == SDbusy)
1811 ;
1812 if(status == SDok || status != SDcheck)
1813 break;
1814 if(!(r->flags & SDvalidsense))
1815 break;
1816 if((r->sense[2] & 0x0F) != 0x02)
1817 continue;
1818 /*
1819 * Unit is 'not ready'.
1820 * If it needs an initialising command, set status
1821 * so it will be spun-up below.
1822 * If there's no medium, that's OK too, but don't
1823 * try to spin it up.
1824 */
1825 if(r->sense[12] == 0x04 && r->sense[13] == 0x02){
1826 status = SDok;
1827 break;
1828 }
1829 if(r->sense[12] == 0x3A)
1830 break;
1831 }
1832
1833 if(status == SDok){
1834 /*
1835 * Try to ensure a direct-access device is spinning.
1836 * Don't wait for completion, ignore the result.
1837 */
1838 if((unit->inquiry[0] & 0x1F) == 0){
1839 memset(r->cmd, 0, sizeof(r->cmd));
1840 r->write = 0;
1841 r->cmd[0] = 0x1B;
1842 r->cmd[1] = (r->lun<<5)|0x01;
1843 r->cmd[4] = 1;
1844 r->clen = 6;
1845 r->data = nil;
1846 r->dlen = 0;
1847 r->flags = 0;
1848
1849 r->status = ~0;
1850 unit->dev->ifc->rio(r);
1851 }
1852 }
1853 free(r);
1854
1855 if(status == SDok || status == SDcheck)
1856 return 1;
1857 return 0;
1858 }
1859
1860 static int
1861 ataonline(SDunit* unit)
1862 {
1863 SDreq *r;
1864 uchar *p;
1865 int ok, retries;
1866
1867 if((r = malloc(sizeof(SDreq))) == nil)
1868 return 0;
1869 if((p = sdmalloc(8)) == nil){
1870 free(r);
1871 return 0;
1872 }
1873
1874 ok = 0;
1875
1876 r->unit = unit;
1877 r->lun = 0; /* ??? */
1878 for(retries = 0; retries < 10; retries++){
1879 /*
1880 * Read-capacity is mandatory for DA, WORM, CD-ROM and
1881 * MO. It may return 'not ready' if type DA is not
1882 * spun up, type MO or type CD-ROM are not loaded or just
1883 * plain slow getting their act together after a reset.
1884 */
1885 r->write = 0;
1886 memset(r->cmd, 0, sizeof(r->cmd));
1887 r->cmd[0] = 0x25;
1888 r->cmd[1] = r->lun<<5;
1889 r->clen = 10;
1890 r->data = p;
1891 r->dlen = 8;
1892 r->flags = 0;
1893
1894 r->status = ~0;
1895 switch(scsirio(r)){
1896 default:
1897 break;
1898 case 0:
1899 unit->sectors = (p[0]<<24)|(p[1]<<16)|(p[2]<<8)|p[3];
1900 /*
1901 * Read-capacity returns the LBA of the last sector,
1902 * therefore the number of sectors must be incremented.
1903 */
1904 unit->sectors++;
1905 unit->secsize = (p[4]<<24)|(p[5]<<16)|(p[6]<<8)|p[7];
1906
1907 /*
1908 * Some ATAPI CD readers lie about the block size.
1909 * Since we don't read audio via this interface
1910 * it's okay to always fudge this.
1911 */
1912 if(unit->secsize == 2352)
1913 unit->secsize = 2048;
1914 ok = 1;
1915 break;
1916 case 1:
1917 ok = 1;
1918 break;
1919 case 2:
1920 continue;
1921 }
1922 break;
1923 }
1924 free(p);
1925 free(r);
1926
1927 if(ok)
1928 return ok+retries;
1929 else
1930 return 0;
1931 }
1932
1933 static long
1934 atabio(SDunit* unit, int lun, int write, void* data, long nb, uvlong bno)
1935 {
1936 SDreq *r;
1937 long rlen;
1938
1939 if((r = malloc(sizeof(SDreq))) == nil)
1940 error(Enomem);
1941 r->unit = unit;
1942 r->lun = lun;
1943 again:
1944 r->write = write;
1945 if(write == 0)
1946 r->cmd[0] = 0x28;
1947 else
1948 r->cmd[0] = 0x2A;
1949 r->cmd[1] = (lun<<5);
1950 r->cmd[2] = bno>>24;
1951 r->cmd[3] = bno>>16;
1952 r->cmd[4] = bno>>8;
1953 r->cmd[5] = bno;
1954 r->cmd[6] = 0;
1955 r->cmd[7] = nb>>8;
1956 r->cmd[8] = nb;
1957 r->cmd[9] = 0;
1958 r->clen = 10;
1959 r->data = data;
1960 r->dlen = nb*unit->secsize;
1961 r->flags = 0;
1962
1963 r->status = ~0;
1964 switch(scsirio(r)){
1965 default:
1966 rlen = -1;
1967 break;
1968 case 0:
1969 rlen = r->rlen;
1970 break;
1971 case 2:
1972 rlen = -1;
1973 if(!(r->flags & SDvalidsense))
1974 break;
1975 switch(r->sense[2] & 0x0F){
1976 default:
1977 break;
1978 case 0x06: /* check condition */
1979 /*
1980 * Check for a removeable media change.
1981 * If so, mark it by zapping the geometry info
1982 * to force an online request.
1983 */
1984 if(r->sense[12] != 0x28 || r->sense[13] != 0)
1985 break;
1986 if(unit->inquiry[1] & 0x80)
1987 unit->sectors = 0;
1988 break;
1989 case 0x02: /* not ready */
1990 /*
1991 * If unit is becoming ready,
1992 * rather than not not ready, try again.
1993 */
1994 if(r->sense[12] == 0x04 && r->sense[13] == 0x01)
1995 goto again;
1996 break;
1997 }
1998 break;
1999 }
2000 free(r);
2001
2002 return rlen;
2003 }
2004
2005
2006 struct Try {
2007 int p;
2008 int c;
2009 } tries[] = {
2010 { 0, 0x0c },
2011 { 0, 0 },
2012 };
2013
2014 static SDev*
2015 ataprobew(DevConf *cf)
2016 {
2017 int cmdport;
2018 int ctlport;
2019 int irq;
2020 SDev* rc;
2021 struct Try *try;
2022
2023 rc = nil;
2024 for (try = &tries[0]; try->p != 0 || try->c != 0; try++){
2025 ataitype = cf->itype;
2026 atairq = cf->intnum;
2027 cmdport = cf->ports[0].port + try->p;
2028 ctlport = cmdport + try->c;
2029 irq = cf->intnum;
2030 rc = ataprobe(cmdport, ctlport, irq);
2031 if (rc)
2032 break;
2033 }
2034 return rc;
2035 }
2036
2037 static void
2038 ataclear(SDev *sdev)
2039 {
2040 Ctlr* ctlr;
2041
2042 ctlr = sdev->ctlr;
2043
2044 if (ctlr->drive[0])
2045 free(ctlr->drive[0]);
2046 if (ctlr->drive[1])
2047 free(ctlr->drive[1]);
2048 if (sdev->name)
2049 free(sdev->name);
2050 if (sdev->unitflg)
2051 free(sdev->unitflg);
2052 if (sdev->unit)
2053 free(sdev->unit);
2054 free(ctlr);
2055 free(sdev);
2056 }
2057
2058 static char *
2059 atastat(SDev *sdev, char *p, char *e)
2060 {
2061 Ctlr *ctlr = sdev->ctlr;
2062
2063 return seprint(p, e, "%s ata port %X ctl %X irq %d\n",
2064 sdev->name, ctlr->cmdport, ctlr->ctlport, ctlr->irq);
2065 }
2066
2067
2068 SDifc sdataifc = {
2069 "ata", /* name */
2070
2071 nil, /* pnp */
2072 atalegacy, /* legacy */
2073 ataenable, /* enable */
2074 nil, /* disable */
2075
2076 ataverify, /* verify */
2077 ataonline, /* online */
2078 atario, /* rio */
2079 atarctl, /* rctl */
2080 atawctl, /* wctl */
2081
2082 atabio, /* bio */
2083 ataprobew, /* probew */
2084 ataclear, /* clear */
2085 atastat, /* stat */
2086 };
2087
Cache object: 4e2bebee5fecc705ec58d24e03e00ea6
|