The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/pc/sdata.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    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


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.