sdata.c 33 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483
  1. #include "u.h"
  2. #include "lib.h"
  3. #include "mem.h"
  4. #include "dat.h"
  5. #include "fns.h"
  6. #include "io.h"
  7. #include "ureg.h"
  8. #include "error.h"
  9. #include "sd.h"
  10. extern SDifc sdataifc;
  11. enum {
  12. DbgCONFIG = 0x01, /* detected drive config info */
  13. DbgIDENTIFY = 0x02, /* detected drive identify info */
  14. DbgSTATE = 0x04, /* dump state on panic */
  15. DbgPROBE = 0x08, /* trace device probing */
  16. DbgDEBUG = 0x80, /* the current problem... */
  17. };
  18. #define DEBUG (DbgDEBUG/*|DbgPROBE*/|DbgCONFIG)
  19. enum { /* I/O ports */
  20. Data = 0,
  21. Error = 1, /* (read) */
  22. Features = 1, /* (write) */
  23. Count = 2, /* sector count */
  24. Ir = 2, /* interrupt reason (PACKET) */
  25. Sector = 3, /* sector number, LBA<7-0> */
  26. Cyllo = 4, /* cylinder low, LBA<15-8> */
  27. Bytelo = 4, /* byte count low (PACKET) */
  28. Cylhi = 5, /* cylinder high, LBA<23-16> */
  29. Bytehi = 5, /* byte count hi (PACKET) */
  30. Dh = 6, /* Device/Head, LBA<32-14> */
  31. Status = 7, /* (read) */
  32. Command = 7, /* (write) */
  33. As = 2, /* Alternate Status (read) */
  34. Dc = 2, /* Device Control (write) */
  35. };
  36. enum { /* Error */
  37. Med = 0x01, /* Media error */
  38. Ili = 0x01, /* command set specific (PACKET) */
  39. Nm = 0x02, /* No Media */
  40. Eom = 0x02, /* command set specific (PACKET) */
  41. Abrt = 0x04, /* Aborted command */
  42. Mcr = 0x08, /* Media Change Request */
  43. Idnf = 0x10, /* no user-accessible address */
  44. Mc = 0x20, /* Media Change */
  45. Unc = 0x40, /* Uncorrectable data error */
  46. Wp = 0x40, /* Write Protect */
  47. Icrc = 0x80, /* Interface CRC error */
  48. };
  49. enum { /* Features */
  50. Dma = 0x01, /* data transfer via DMA (PACKET) */
  51. Ovl = 0x02, /* command overlapped (PACKET) */
  52. };
  53. enum { /* Interrupt Reason */
  54. Cd = 0x01, /* Command/Data */
  55. Io = 0x02, /* I/O direction */
  56. Rel = 0x04, /* Bus Release */
  57. };
  58. enum { /* Device/Head */
  59. Dev0 = 0xA0, /* Master */
  60. Dev1 = 0xB0, /* Slave */
  61. Lba = 0x40, /* LBA mode */
  62. };
  63. enum { /* Status, Alternate Status */
  64. Err = 0x01, /* Error */
  65. Chk = 0x01, /* Check error (PACKET) */
  66. Drq = 0x08, /* Data Request */
  67. Dsc = 0x10, /* Device Seek Complete */
  68. Serv = 0x10, /* Service */
  69. Df = 0x20, /* Device Fault */
  70. Dmrd = 0x20, /* DMA ready (PACKET) */
  71. Drdy = 0x40, /* Device Ready */
  72. Bsy = 0x80, /* Busy */
  73. };
  74. enum { /* Command */
  75. Cnop = 0x00, /* NOP */
  76. Cdr = 0x08, /* Device Reset */
  77. Crs = 0x20, /* Read Sectors */
  78. Cws = 0x30, /* Write Sectors */
  79. Cedd = 0x90, /* Execute Device Diagnostics */
  80. Cpkt = 0xA0, /* Packet */
  81. Cidpkt = 0xA1, /* Identify Packet Device */
  82. Crsm = 0xC4, /* Read Multiple */
  83. Cwsm = 0xC5, /* Write Multiple */
  84. Csm = 0xC6, /* Set Multiple */
  85. Crdq = 0xC7, /* Read DMA queued */
  86. Crd = 0xC8, /* Read DMA */
  87. Cwd = 0xCA, /* Write DMA */
  88. Cwdq = 0xCC, /* Write DMA queued */
  89. Cid = 0xEC, /* Identify Device */
  90. Csf = 0xEF, /* Set Features */
  91. };
  92. enum { /* Device Control */
  93. Nien = 0x02, /* (not) Interrupt Enable */
  94. Srst = 0x04, /* Software Reset */
  95. };
  96. enum { /* PCI Configuration Registers */
  97. Bmiba = 0x20, /* Bus Master Interface Base Address */
  98. Idetim = 0x40, /* IE Timing */
  99. Sidetim = 0x44, /* Slave IE Timing */
  100. Udmactl = 0x48, /* Ultra DMA/33 Control */
  101. Udmatim = 0x4A, /* Ultra DMA/33 Timing */
  102. };
  103. enum { /* Bus Master IDE I/O Ports */
  104. Bmicx = 0, /* Command */
  105. Bmisx = 2, /* Status */
  106. Bmidtpx = 4, /* Descriptor Table Pointer */
  107. };
  108. enum { /* Bmicx */
  109. Ssbm = 0x01, /* Start/Stop Bus Master */
  110. Rwcon = 0x08, /* Read/Write Control */
  111. };
  112. enum { /* Bmisx */
  113. Bmidea = 0x01, /* Bus Master IDE Active */
  114. Idedmae = 0x02, /* IDE DMA Error (R/WC) */
  115. Ideints = 0x04, /* IDE Interrupt Status (R/WC) */
  116. Dma0cap = 0x20, /* Drive 0 DMA Capable */
  117. Dma1cap = 0x40, /* Drive 0 DMA Capable */
  118. };
  119. enum { /* Physical Region Descriptor */
  120. PrdEOT = 0x80000000, /* Bus Master IDE Active */
  121. };
  122. enum { /* offsets into the identify info. */
  123. Iconfig = 0, /* general configuration */
  124. Ilcyl = 1, /* logical cylinders */
  125. Ilhead = 3, /* logical heads */
  126. Ilsec = 6, /* logical sectors per logical track */
  127. Iserial = 10, /* serial number */
  128. Ifirmware = 23, /* firmware revision */
  129. Imodel = 27, /* model number */
  130. Imaxrwm = 47, /* max. read/write multiple sectors */
  131. Icapabilities = 49, /* capabilities */
  132. Istandby = 50, /* device specific standby timer */
  133. Ipiomode = 51, /* PIO data transfer mode number */
  134. Ivalid = 53,
  135. Iccyl = 54, /* cylinders if (valid&0x01) */
  136. Ichead = 55, /* heads if (valid&0x01) */
  137. Icsec = 56, /* sectors if (valid&0x01) */
  138. Iccap = 57, /* capacity if (valid&0x01) */
  139. Irwm = 59, /* read/write multiple */
  140. Ilba0 = 60, /* LBA size */
  141. Ilba1 = 61, /* LBA size */
  142. Imwdma = 63, /* multiword DMA mode */
  143. Iapiomode = 64, /* advanced PIO modes supported */
  144. Iminmwdma = 65, /* min. multiword DMA cycle time */
  145. Irecmwdma = 66, /* rec. multiword DMA cycle time */
  146. Iminpio = 67, /* min. PIO cycle w/o flow control */
  147. Iminiordy = 68, /* min. PIO cycle with IORDY */
  148. Ipcktbr = 71, /* time from PACKET to bus release */
  149. Iserbsy = 72, /* time from SERVICE to !Bsy */
  150. Iqdepth = 75, /* max. queue depth */
  151. Imajor = 80, /* major version number */
  152. Iminor = 81, /* minor version number */
  153. Icmdset0 = 82, /* command sets supported */
  154. Icmdset1 = 83, /* command sets supported */
  155. Icmdset2 = 84, /* command sets supported extension */
  156. Icmdset3 = 85, /* command sets enabled */
  157. Icmdset4 = 86, /* command sets enabled */
  158. Icmdset5 = 87, /* command sets enabled extension */
  159. Iudma = 88, /* ultra DMA mode */
  160. Ierase = 89, /* time for security erase */
  161. Ieerase = 90, /* time for enhanced security erase */
  162. Ipower = 91, /* current advanced power management */
  163. Irmsn = 127, /* removable status notification */
  164. Istatus = 128, /* security status */
  165. };
  166. typedef struct Ctlr Ctlr;
  167. typedef struct Drive Drive;
  168. typedef struct Prd {
  169. ulong pa; /* Physical Base Address */
  170. int count;
  171. } Prd;
  172. enum {
  173. Nprd = SDmaxio/(64*1024)+2,
  174. };
  175. typedef struct Ctlr {
  176. int cmdport;
  177. int ctlport;
  178. int irq;
  179. int tbdf;
  180. Pcidev* pcidev;
  181. void (*ienable)(Ctlr*);
  182. SDev* sdev;
  183. Drive* drive[2];
  184. Prd* prdt; /* physical region descriptor table */
  185. // QLock; /* current command */
  186. Drive* curdrive;
  187. int command; /* last command issued (debugging) */
  188. // Rendez;
  189. int done;
  190. Lock; /* register access */
  191. } Ctlr;
  192. typedef struct Drive {
  193. Ctlr* ctlr;
  194. int dev;
  195. ushort info[256];
  196. int c; /* cylinder */
  197. int h; /* head */
  198. int s; /* sector */
  199. int sectors; /* total */
  200. int secsize; /* sector size */
  201. // int dma; /* DMA R/W possible */
  202. // int dmactl;
  203. // int rwm; /* read/write multiple possible */
  204. // int rwmctl;
  205. int pkt; /* PACKET device, length of pktcmd */
  206. uchar pktcmd[16];
  207. // int pktdma; /* this PACKET command using dma */
  208. uchar sense[18];
  209. uchar inquiry[48];
  210. // QLock; /* drive access */
  211. int command; /* current command */
  212. int write;
  213. uchar* data;
  214. int dlen;
  215. uchar* limit;
  216. int count; /* sectors */
  217. int block; /* R/W bytes per block */
  218. int status;
  219. int error;
  220. } Drive;
  221. static void
  222. pc87415ienable(Ctlr* ctlr)
  223. {
  224. Pcidev *p;
  225. int x;
  226. p = ctlr->pcidev;
  227. if(p == nil)
  228. return;
  229. x = pcicfgr32(p, 0x40);
  230. if(ctlr->cmdport == p->mem[0].bar)
  231. x &= ~0x00000100;
  232. else
  233. x &= ~0x00000200;
  234. pcicfgw32(p, 0x40, x);
  235. }
  236. static int
  237. atadebug(int cmdport, int ctlport, char* fmt, ...)
  238. {
  239. int i, n;
  240. va_list arg;
  241. char buf[PRINTSIZE];
  242. if(!(DEBUG & DbgPROBE)){
  243. USED(cmdport, ctlport, fmt);
  244. return 0;
  245. }
  246. va_start(arg, fmt);
  247. n = doprint(buf, buf+sizeof(buf), fmt, arg) - buf;
  248. va_end(arg);
  249. if(cmdport){
  250. if(buf[n-1] == '\n')
  251. n--;
  252. n += snprint(buf+n, PRINTSIZE-n, " ataregs 0x%uX:",
  253. cmdport);
  254. for(i = Features; i < Command; i++)
  255. n += snprint(buf+n, PRINTSIZE-n, " 0x%2.2uX",
  256. inb(cmdport+i));
  257. if(ctlport)
  258. n += snprint(buf+n, PRINTSIZE-n, " 0x%2.2uX",
  259. inb(ctlport+As));
  260. n += snprint(buf+n, PRINTSIZE-n, "\n");
  261. }
  262. putstrn(buf, n);
  263. return n;
  264. }
  265. static int
  266. ataready(int cmdport, int ctlport, int dev, int reset, int ready, int micro)
  267. {
  268. int as;
  269. atadebug(cmdport, ctlport, "ataready: dev %uX reset %uX ready %uX",
  270. dev, reset, ready);
  271. for(;;){
  272. /*
  273. * Wait for the controller to become not busy and
  274. * possibly for a status bit to become true (usually
  275. * Drdy). Must change to the appropriate device
  276. * register set if necessary before testing for ready.
  277. * Always run through the loop at least once so it
  278. * can be used as a test for !Bsy.
  279. */
  280. as = inb(ctlport+As);
  281. if(as & reset){
  282. /* nothing to do */;
  283. }
  284. else if(dev){
  285. outb(cmdport+Dh, dev);
  286. dev = 0;
  287. }
  288. else if(ready == 0 || (as & ready)){
  289. atadebug(0, 0, "ataready: %d 0x%2.2uX\n", micro, as);
  290. return as;
  291. }
  292. if(micro-- <= 0){
  293. atadebug(0, 0, "ataready: %d 0x%2.2uX\n", micro, as);
  294. break;
  295. }
  296. microdelay(1);
  297. }
  298. atadebug(cmdport, ctlport, "ataready: timeout");
  299. return -1;
  300. }
  301. static int
  302. atacsfenabled(Drive* drive, vlong csf)
  303. {
  304. int cmdset, i, x;
  305. for(i = 0; i < 3; i++){
  306. x = (csf>>(16*i)) & 0xFFFF;
  307. if(x == 0)
  308. continue;
  309. cmdset = drive->info[Icmdset3+i];
  310. if(cmdset == 0 || cmdset == 0xFFFF)
  311. return 0;
  312. return cmdset & x;
  313. }
  314. return 0;
  315. }
  316. static int
  317. atasf(int cmdport, int ctlport, int dev, uchar* command)
  318. {
  319. int as, i;
  320. if(ataready(cmdport, ctlport, dev, Bsy|Drq, Drdy, 108*1000) < 0)
  321. return -1;
  322. for(i = Features; i < Dh; i++)
  323. outb(cmdport+i, command[i]);
  324. outb(cmdport+Command, Csf);
  325. microdelay(100);
  326. as = ataready(cmdport, ctlport, 0, Bsy, Drdy|Df|Err, 109*1000);
  327. if(as < 0 || (as & (Df|Err)))
  328. return -1;
  329. return 0;
  330. }
  331. static int
  332. ataidentify(int cmdport, int ctlport, int dev, int pkt, void* info)
  333. {
  334. int as, command, drdy;
  335. if(pkt){
  336. command = Cidpkt;
  337. drdy = 0;
  338. }
  339. else{
  340. command = Cid;
  341. drdy = Drdy;
  342. }
  343. as = ataready(cmdport, ctlport, dev, Bsy|Drq, drdy, 103*1000);
  344. if(as < 0)
  345. return as;
  346. outb(cmdport+Command, command);
  347. microdelay(1);
  348. as = ataready(cmdport, ctlport, 0, Bsy, Drq|Err, 400*1000);
  349. if(as < 0)
  350. return -1;
  351. if(as & Err)
  352. return as;
  353. memset(info, 0, 512);
  354. inss(cmdport+Data, info, 256);
  355. inb(cmdport+Status);
  356. if(DEBUG & DbgIDENTIFY){
  357. int i;
  358. ushort *sp;
  359. sp = (ushort*)info;
  360. for(i = 0; i < 256; i++){
  361. if(i && (i%16) == 0)
  362. print("\n");
  363. print("%4.4uX ", *sp);
  364. sp++;
  365. }
  366. print("\n");
  367. }
  368. return 0;
  369. }
  370. static Drive*
  371. atadrive(int cmdport, int ctlport, int dev)
  372. {
  373. ushort *sp;
  374. Drive *drive;
  375. int as, i, pkt;
  376. uchar buf[512], *p;
  377. atadebug(0, 0, "identify: port 0x%uX dev 0x%2.2uX\n", cmdport, dev);
  378. pkt = 1;
  379. retry:
  380. as = ataidentify(cmdport, ctlport, dev, pkt, buf);
  381. if(as < 0)
  382. return nil;
  383. if(as & Err){
  384. if(pkt == 0)
  385. return nil;
  386. pkt = 0;
  387. goto retry;
  388. }
  389. if((drive = malloc(sizeof(Drive))) == nil)
  390. return nil;
  391. drive->dev = dev;
  392. memmove(drive->info, buf, sizeof(drive->info));
  393. drive->sense[0] = 0x70;
  394. drive->sense[7] = sizeof(drive->sense)-7;
  395. drive->inquiry[2] = 2;
  396. drive->inquiry[3] = 2;
  397. drive->inquiry[4] = sizeof(drive->inquiry)-4;
  398. p = &drive->inquiry[8];
  399. sp = &drive->info[Imodel];
  400. for(i = 0; i < 20; i++){
  401. *p++ = *sp>>8;
  402. *p++ = *sp++;
  403. }
  404. drive->secsize = 512;
  405. if((drive->info[Iconfig] & 0xC000) == 0x8000){
  406. if(drive->info[Iconfig] & 0x01)
  407. drive->pkt = 16;
  408. else
  409. drive->pkt = 12;
  410. }
  411. else{
  412. if(drive->info[Ivalid] & 0x0001){
  413. drive->c = drive->info[Iccyl];
  414. drive->h = drive->info[Ichead];
  415. drive->s = drive->info[Icsec];
  416. }
  417. else{
  418. drive->c = drive->info[Ilcyl];
  419. drive->h = drive->info[Ilhead];
  420. drive->s = drive->info[Ilsec];
  421. }
  422. if(drive->info[Icapabilities] & 0x0200){
  423. drive->sectors = (drive->info[Ilba1]<<16)
  424. |drive->info[Ilba0];
  425. drive->dev |= Lba;
  426. }
  427. else
  428. drive->sectors = drive->c*drive->h*drive->s;
  429. // atarwmmode(drive, cmdport, ctlport, dev);
  430. }
  431. // atadmamode(drive);
  432. if(DEBUG & DbgCONFIG){
  433. print("dev %2.2uX port %uX config %4.4uX capabilities %4.4uX",
  434. dev, cmdport,
  435. drive->info[Iconfig], drive->info[Icapabilities]);
  436. print(" mwdma %4.4uX", drive->info[Imwdma]);
  437. if(drive->info[Ivalid] & 0x04)
  438. print(" udma %4.4uX", drive->info[Iudma]);
  439. // print(" dma %8.8uX rwm %ud\n", drive->dma, drive->rwm);
  440. print("\n");
  441. }
  442. return drive;
  443. }
  444. static void
  445. atasrst(int ctlport)
  446. {
  447. /*
  448. * Srst is a big stick and may cause problems if further
  449. * commands are tried before the drives become ready again.
  450. * Also, there will be problems here if overlapped commands
  451. * are ever supported.
  452. */
  453. microdelay(5);
  454. outb(ctlport+Dc, Srst);
  455. microdelay(5);
  456. outb(ctlport+Dc, 0);
  457. microdelay(2*1000);
  458. }
  459. static SDev*
  460. ataprobe(int cmdport, int ctlport, int irq)
  461. {
  462. Ctlr* ctlr;
  463. SDev *sdev;
  464. Drive *drive;
  465. int dev, error, rhi, rlo;
  466. // if(ioalloc(cmdport, 8, 0, "atacmd") < 0)
  467. // return nil;
  468. // if(ioalloc(ctlport+As, 1, 0, "atactl") < 0){
  469. // iofree(cmdport);
  470. // return nil;
  471. // }
  472. /*
  473. * Try to detect a floating bus.
  474. * Bsy should be cleared. If not, see if the cylinder registers
  475. * are read/write capable.
  476. * If the master fails, try the slave to catch slave-only
  477. * configurations.
  478. * There's no need to restore the tested registers as they will
  479. * be reset on any detected drives by the Cedd command.
  480. * All this indicates is that there is at least one drive on the
  481. * controller; when the non-existent drive is selected in a
  482. * single-drive configuration the registers of the existing drive
  483. * are often seen, only command execution fails.
  484. */
  485. dev = Dev0;
  486. if(inb(ctlport+As) & Bsy){
  487. outb(cmdport+Dh, dev);
  488. microdelay(1);
  489. trydev1:
  490. atadebug(cmdport, ctlport, "ataprobe bsy");
  491. outb(cmdport+Cyllo, 0xAA);
  492. outb(cmdport+Cylhi, 0x55);
  493. outb(cmdport+Sector, 0xFF);
  494. rlo = inb(cmdport+Cyllo);
  495. rhi = inb(cmdport+Cylhi);
  496. if(rlo != 0xAA && (rlo == 0xFF || rhi != 0x55)){
  497. if(dev == Dev1){
  498. release:
  499. // iofree(cmdport);
  500. // iofree(ctlport+As);
  501. return nil;
  502. }
  503. dev = Dev1;
  504. if(ataready(cmdport, ctlport, dev, Bsy, 0, 20*1000) < 0)
  505. goto trydev1;
  506. }
  507. }
  508. /*
  509. * Disable interrupts on any detected controllers.
  510. */
  511. outb(ctlport+Dc, Nien);
  512. tryedd1:
  513. if(ataready(cmdport, ctlport, dev, Bsy|Drq, 0, 105*1000) < 0){
  514. /*
  515. * There's something there, but it didn't come up clean,
  516. * so try hitting it with a big stick. The timing here is
  517. * wrong but this is a last-ditch effort and it sometimes
  518. * gets some marginal hardware back online.
  519. */
  520. atasrst(ctlport);
  521. if(ataready(cmdport, ctlport, dev, Bsy|Drq, 0, 106*1000) < 0)
  522. goto release;
  523. }
  524. /*
  525. * Can only get here if controller is not busy.
  526. * If there are drives Bsy will be set within 400nS,
  527. * must wait 2mS before testing Status.
  528. * Wait for the command to complete (6 seconds max).
  529. */
  530. outb(cmdport+Command, Cedd);
  531. delay(2);
  532. if(ataready(cmdport, ctlport, dev, Bsy|Drq, 0, 6*1000*1000) < 0)
  533. goto release;
  534. /*
  535. * If bit 0 of the error register is set then the selected drive
  536. * exists. This is enough to detect single-drive configurations.
  537. * However, if the master exists there is no way short of executing
  538. * a command to determine if a slave is present.
  539. * It appears possible to get here testing Dev0 although it doesn't
  540. * exist and the EDD won't take, so try again with Dev1.
  541. */
  542. error = inb(cmdport+Error);
  543. atadebug(cmdport, ctlport, "ataprobe: dev %uX", dev);
  544. if((error & ~0x80) != 0x01){
  545. if(dev == Dev1)
  546. goto release;
  547. dev = Dev1;
  548. goto tryedd1;
  549. }
  550. /*
  551. * At least one drive is known to exist, try to
  552. * identify it. If that fails, don't bother checking
  553. * any further.
  554. * If the one drive found is Dev0 and the EDD command
  555. * didn't indicate Dev1 doesn't exist, check for it.
  556. */
  557. if((drive = atadrive(cmdport, ctlport, dev)) == nil)
  558. goto release;
  559. if((ctlr = malloc(sizeof(Ctlr))) == nil){
  560. free(drive);
  561. goto release;
  562. }
  563. if((sdev = malloc(sizeof(SDev))) == nil){
  564. free(ctlr);
  565. free(drive);
  566. goto release;
  567. }
  568. drive->ctlr = ctlr;
  569. if(dev == Dev0){
  570. ctlr->drive[0] = drive;
  571. if(!(error & 0x80)){
  572. /*
  573. * Always leave Dh pointing to a valid drive,
  574. * otherwise a subsequent call to ataready on
  575. * this controller may try to test a bogus Status.
  576. * Ataprobe is the only place possibly invalid
  577. * drives should be selected.
  578. */
  579. drive = atadrive(cmdport, ctlport, Dev1);
  580. if(drive != nil){
  581. drive->ctlr = ctlr;
  582. ctlr->drive[1] = drive;
  583. }
  584. else{
  585. outb(cmdport+Dh, Dev0);
  586. microdelay(1);
  587. }
  588. }
  589. }
  590. else
  591. ctlr->drive[1] = drive;
  592. ctlr->cmdport = cmdport;
  593. ctlr->ctlport = ctlport;
  594. ctlr->irq = irq;
  595. ctlr->tbdf = BUSUNKNOWN;
  596. ctlr->command = Cedd; /* debugging */
  597. sdev->ifc = &sdataifc;
  598. sdev->ctlr = ctlr;
  599. sdev->nunit = 2;
  600. ctlr->sdev = sdev;
  601. return sdev;
  602. }
  603. static int
  604. atasetsense(Drive* drive, int status, int key, int asc, int ascq)
  605. {
  606. drive->sense[2] = key;
  607. drive->sense[12] = asc;
  608. drive->sense[13] = ascq;
  609. return status;
  610. }
  611. static int
  612. atamodesense(Drive* drive, uchar* cmd)
  613. {
  614. int len;
  615. /*
  616. * Fake a vendor-specific request with page code 0,
  617. * return the drive info.
  618. */
  619. if((cmd[2] & 0x3F) != 0 && (cmd[2] & 0x3F) != 0x3F)
  620. return atasetsense(drive, SDcheck, 0x05, 0x24, 0);
  621. len = (cmd[7]<<8)|cmd[8];
  622. if(len == 0)
  623. return SDok;
  624. if(len < 8+sizeof(drive->info))
  625. return atasetsense(drive, SDcheck, 0x05, 0x1A, 0);
  626. if(drive->data == nil || drive->dlen < len)
  627. return atasetsense(drive, SDcheck, 0x05, 0x20, 1);
  628. memset(drive->data, 0, 8);
  629. drive->data[0] = sizeof(drive->info)>>8;
  630. drive->data[1] = sizeof(drive->info);
  631. memmove(drive->data+8, drive->info, sizeof(drive->info));
  632. drive->data += 8+sizeof(drive->info);
  633. return SDok;
  634. }
  635. static void
  636. atanop(Drive* drive, int subcommand)
  637. {
  638. Ctlr* ctlr;
  639. int as, cmdport, ctlport, timeo;
  640. /*
  641. * Attempt to abort a command by using NOP.
  642. * In response, the drive is supposed to set Abrt
  643. * in the Error register, set (Drdy|Err) in Status
  644. * and clear Bsy when done. However, some drives
  645. * (e.g. ATAPI Zip) just go Bsy then clear Status
  646. * when done, hence the timeout loop only on Bsy
  647. * and the forced setting of drive->error.
  648. */
  649. ctlr = drive->ctlr;
  650. cmdport = ctlr->cmdport;
  651. outb(cmdport+Features, subcommand);
  652. outb(cmdport+Dh, drive->dev);
  653. ctlr->command = Cnop; /* debugging */
  654. outb(cmdport+Command, Cnop);
  655. microdelay(1);
  656. ctlport = ctlr->ctlport;
  657. for(timeo = 0; timeo < 1000; timeo++){
  658. as = inb(ctlport+As);
  659. if(!(as & Bsy))
  660. break;
  661. microdelay(1);
  662. }
  663. drive->error |= Abrt;
  664. }
  665. static void
  666. ataabort(Drive* drive, int dolock)
  667. {
  668. /*
  669. * If NOP is available (packet commands) use it otherwise
  670. * must try a software reset.
  671. */
  672. if(dolock)
  673. ilock(drive->ctlr);
  674. if(atacsfenabled(drive, 0x0000000000004000LL))
  675. atanop(drive, 0);
  676. else{
  677. atasrst(drive->ctlr->ctlport);
  678. drive->error |= Abrt;
  679. }
  680. if(dolock)
  681. iunlock(drive->ctlr);
  682. }
  683. static int
  684. atapktiodone(void* arg)
  685. {
  686. return ((Ctlr*)arg)->done;
  687. }
  688. static void
  689. atapktinterrupt(Drive* drive)
  690. {
  691. Ctlr* ctlr;
  692. int cmdport, len;
  693. ctlr = drive->ctlr;
  694. cmdport = ctlr->cmdport;
  695. switch(inb(cmdport+Ir) & (/*Rel|*/Io|Cd)){
  696. case Cd:
  697. outss(cmdport+Data, drive->pktcmd, drive->pkt/2);
  698. break;
  699. case 0:
  700. len = (inb(cmdport+Bytehi)<<8)|inb(cmdport+Bytelo);
  701. if(drive->data+len > drive->limit){
  702. atanop(drive, 0);
  703. break;
  704. }
  705. outss(cmdport+Data, drive->data, len/2);
  706. drive->data += len;
  707. break;
  708. case Io:
  709. len = (inb(cmdport+Bytehi)<<8)|inb(cmdport+Bytelo);
  710. if(drive->data+len > drive->limit){
  711. atanop(drive, 0);
  712. break;
  713. }
  714. inss(cmdport+Data, drive->data, len/2);
  715. drive->data += len;
  716. break;
  717. case Io|Cd:
  718. // if(drive->pktdma)
  719. // atadmainterrupt(drive, drive->dlen);
  720. // else
  721. ctlr->done = 1;
  722. break;
  723. }
  724. }
  725. static int
  726. atapktio(Drive* drive, uchar* cmd, int clen)
  727. {
  728. Ctlr *ctlr;
  729. int as, cmdport, ctlport, len, r;
  730. if(cmd[0] == 0x5A && (cmd[2] & 0x3F) == 0)
  731. return atamodesense(drive, cmd);
  732. r = SDok;
  733. drive->command = Cpkt;
  734. memmove(drive->pktcmd, cmd, clen);
  735. memset(drive->pktcmd+clen, 0, drive->pkt-clen);
  736. drive->limit = drive->data+drive->dlen;
  737. ctlr = drive->ctlr;
  738. cmdport = ctlr->cmdport;
  739. ctlport = ctlr->ctlport;
  740. qlock(ctlr);
  741. if(ataready(cmdport, ctlport, drive->dev, Bsy|Drq, 0, 107*1000) < 0){
  742. qunlock(ctlr);
  743. return -1;
  744. }
  745. ilock(ctlr);
  746. // if(drive->dlen && drive->dmactl && !atadmasetup(drive, drive->dlen))
  747. // drive->pktdma = Dma;
  748. // else
  749. // drive->pktdma = 0;
  750. outb(cmdport+Features, 0/*drive->pktdma*/);
  751. outb(cmdport+Count, 0);
  752. outb(cmdport+Sector, 0);
  753. len = 16*drive->secsize;
  754. outb(cmdport+Bytelo, len);
  755. outb(cmdport+Bytehi, len>>8);
  756. outb(cmdport+Dh, drive->dev);
  757. ctlr->done = 0;
  758. ctlr->curdrive = drive;
  759. ctlr->command = Cpkt; /* debugging */
  760. // if(drive->pktdma)
  761. // atadmastart(ctlr, drive->write);
  762. outb(cmdport+Command, Cpkt);
  763. if((drive->info[Iconfig] & 0x0060) != 0x0020){
  764. microdelay(1);
  765. as = ataready(cmdport, ctlport, 0, Bsy, Drq|Chk, 4*1000);
  766. if(as < 0)
  767. r = SDtimeout;
  768. else if(as & Chk)
  769. r = SDcheck;
  770. else
  771. atapktinterrupt(drive);
  772. }
  773. iunlock(ctlr);
  774. sleep(ctlr, atapktiodone, ctlr);
  775. qunlock(ctlr);
  776. if(drive->status & Chk)
  777. r = SDcheck;
  778. return r;
  779. }
  780. static int
  781. atageniodone(void* arg)
  782. {
  783. return ((Ctlr*)arg)->done;
  784. }
  785. static int
  786. atageniostart(Drive* drive, int lba)
  787. {
  788. Ctlr *ctlr;
  789. int as, c, cmdport, ctlport, h, len, s;
  790. if(drive->dev & Lba){
  791. c = (lba>>8) & 0xFFFF;
  792. h = (lba>>24) & 0x0F;
  793. s = lba & 0xFF;
  794. }
  795. else{
  796. c = lba/(drive->s*drive->h);
  797. h = ((lba/drive->s) % drive->h);
  798. s = (lba % drive->s) + 1;
  799. }
  800. ctlr = drive->ctlr;
  801. cmdport = ctlr->cmdport;
  802. ctlport = ctlr->ctlport;
  803. if(ataready(cmdport, ctlport, drive->dev, Bsy|Drq, 0, 101*1000) < 0)
  804. return -1;
  805. ilock(ctlr);
  806. drive->block = drive->secsize;
  807. if(drive->write)
  808. drive->command = Cws;
  809. else
  810. drive->command = Crs;
  811. drive->limit = drive->data + drive->count*drive->secsize;
  812. outb(cmdport+Count, drive->count);
  813. outb(cmdport+Sector, s);
  814. outb(cmdport+Dh, drive->dev|h);
  815. outb(cmdport+Cyllo, c);
  816. outb(cmdport+Cylhi, c>>8);
  817. ctlr->done = 0;
  818. ctlr->curdrive = drive;
  819. ctlr->command = drive->command; /* debugging */
  820. outb(cmdport+Command, drive->command);
  821. switch(drive->command){
  822. case Cws:
  823. case Cwsm:
  824. microdelay(1);
  825. as = ataready(cmdport, ctlport, 0, Bsy, Drq|Err, 1000);
  826. if(as < 0 || (as & Err)){
  827. iunlock(ctlr);
  828. return -1;
  829. }
  830. len = drive->block;
  831. if(drive->data+len > drive->limit)
  832. len = drive->limit-drive->data;
  833. outss(cmdport+Data, drive->data, len/2);
  834. break;
  835. case Crd:
  836. case Cwd:
  837. // atadmastart(ctlr, drive->write);
  838. break;
  839. }
  840. iunlock(ctlr);
  841. return 0;
  842. }
  843. static int
  844. atagenioretry(Drive* drive)
  845. {
  846. return atasetsense(drive, SDcheck, 4, 8, drive->error);
  847. }
  848. static int
  849. atagenio(Drive* drive, uchar* cmd, int)
  850. {
  851. uchar *p;
  852. Ctlr *ctlr;
  853. int count, lba, len;
  854. /*
  855. * Map SCSI commands into ATA commands for discs.
  856. * Fail any command with a LUN except INQUIRY which
  857. * will return 'logical unit not supported'.
  858. */
  859. if((cmd[1]>>5) && cmd[0] != 0x12)
  860. return atasetsense(drive, SDcheck, 0x05, 0x25, 0);
  861. switch(cmd[0]){
  862. default:
  863. return atasetsense(drive, SDcheck, 0x05, 0x20, 0);
  864. case 0x00: /* test unit ready */
  865. return SDok;
  866. case 0x03: /* request sense */
  867. if(cmd[4] < sizeof(drive->sense))
  868. len = cmd[4];
  869. else
  870. len = sizeof(drive->sense);
  871. if(drive->data && drive->dlen >= len){
  872. memmove(drive->data, drive->sense, len);
  873. drive->data += len;
  874. }
  875. return SDok;
  876. case 0x12: /* inquiry */
  877. if(cmd[4] < sizeof(drive->inquiry))
  878. len = cmd[4];
  879. else
  880. len = sizeof(drive->inquiry);
  881. if(drive->data && drive->dlen >= len){
  882. memmove(drive->data, drive->inquiry, len);
  883. drive->data += len;
  884. }
  885. return SDok;
  886. case 0x1B: /* start/stop unit */
  887. /*
  888. * NOP for now, can use the power management feature
  889. * set later.
  890. */
  891. return SDok;
  892. case 0x25: /* read capacity */
  893. if((cmd[1] & 0x01) || cmd[2] || cmd[3])
  894. return atasetsense(drive, SDcheck, 0x05, 0x24, 0);
  895. if(drive->data == nil || drive->dlen < 8)
  896. return atasetsense(drive, SDcheck, 0x05, 0x20, 1);
  897. /*
  898. * Read capacity returns the LBA of the last sector.
  899. */
  900. len = drive->sectors-1;
  901. p = drive->data;
  902. *p++ = len>>24;
  903. *p++ = len>>16;
  904. *p++ = len>>8;
  905. *p++ = len;
  906. len = drive->secsize;
  907. *p++ = len>>24;
  908. *p++ = len>>16;
  909. *p++ = len>>8;
  910. *p = len;
  911. drive->data += 8;
  912. return SDok;
  913. case 0x28: /* read */
  914. case 0x2A: /* write */
  915. break;
  916. case 0x5A:
  917. return atamodesense(drive, cmd);
  918. }
  919. ctlr = drive->ctlr;
  920. lba = (cmd[2]<<24)|(cmd[3]<<16)|(cmd[4]<<8)|cmd[5];
  921. count = (cmd[7]<<8)|cmd[8];
  922. if(drive->data == nil)
  923. return SDok;
  924. if(drive->dlen < count*drive->secsize)
  925. count = drive->dlen/drive->secsize;
  926. qlock(ctlr);
  927. while(count){
  928. if(count > 256)
  929. drive->count = 256;
  930. else
  931. drive->count = count;
  932. if(atageniostart(drive, lba)){
  933. ilock(ctlr);
  934. atanop(drive, 0);
  935. iunlock(ctlr);
  936. qunlock(ctlr);
  937. return atagenioretry(drive);
  938. }
  939. tsleep(ctlr, atageniodone, ctlr, 10*1000);
  940. if(!ctlr->done){
  941. /*
  942. * What should the above timeout be? In
  943. * standby and sleep modes it could take as
  944. * long as 30 seconds for a drive to respond.
  945. * Very hard to get out of this cleanly.
  946. */
  947. // atadumpstate(drive, cmd, lba, count);
  948. ataabort(drive, 1);
  949. return atagenioretry(drive);
  950. }
  951. if(drive->status & Err){
  952. qunlock(ctlr);
  953. return atasetsense(drive, SDcheck, 4, 8, drive->error);
  954. }
  955. count -= drive->count;
  956. lba += drive->count;
  957. }
  958. qunlock(ctlr);
  959. return SDok;
  960. }
  961. static int
  962. atario(SDreq* r)
  963. {
  964. Ctlr *ctlr;
  965. Drive *drive;
  966. SDunit *unit;
  967. uchar cmd10[10], *cmdp, *p;
  968. int clen, reqstatus, status;
  969. unit = r->unit;
  970. if((ctlr = unit->dev->ctlr) == nil || ctlr->drive[unit->subno] == nil){
  971. r->status = SDtimeout;
  972. return SDtimeout;
  973. }
  974. drive = ctlr->drive[unit->subno];
  975. /*
  976. * Most SCSI commands can be passed unchanged except for
  977. * the padding on the end. The few which require munging
  978. * are not used internally. Mode select/sense(6) could be
  979. * converted to the 10-byte form but it's not worth the
  980. * effort. Read/write(6) are easy.
  981. */
  982. switch(r->cmd[0]){
  983. case 0x08: /* read */
  984. case 0x0A: /* write */
  985. cmdp = cmd10;
  986. memset(cmdp, 0, sizeof(cmd10));
  987. cmdp[0] = r->cmd[0]|0x20;
  988. cmdp[1] = r->cmd[1] & 0xE0;
  989. cmdp[5] = r->cmd[3];
  990. cmdp[4] = r->cmd[2];
  991. cmdp[3] = r->cmd[1] & 0x0F;
  992. cmdp[8] = r->cmd[4];
  993. clen = sizeof(cmd10);
  994. break;
  995. default:
  996. cmdp = r->cmd;
  997. clen = r->clen;
  998. break;
  999. }
  1000. qlock(drive);
  1001. drive->write = r->write;
  1002. drive->data = r->data;
  1003. drive->dlen = r->dlen;
  1004. drive->status = 0;
  1005. drive->error = 0;
  1006. if(drive->pkt)
  1007. status = atapktio(drive, cmdp, clen);
  1008. else
  1009. status = atagenio(drive, cmdp, clen);
  1010. if(status == SDok){
  1011. atasetsense(drive, SDok, 0, 0, 0);
  1012. if(drive->data){
  1013. p = r->data;
  1014. r->rlen = drive->data - p;
  1015. }
  1016. else
  1017. r->rlen = 0;
  1018. }
  1019. else if(status == SDcheck && !(r->flags & SDnosense)){
  1020. drive->write = 0;
  1021. memset(cmd10, 0, sizeof(cmd10));
  1022. cmd10[0] = 0x03;
  1023. cmd10[1] = r->lun<<5;
  1024. cmd10[4] = sizeof(r->sense)-1;
  1025. drive->data = r->sense;
  1026. drive->dlen = sizeof(r->sense)-1;
  1027. drive->status = 0;
  1028. drive->error = 0;
  1029. if(drive->pkt)
  1030. reqstatus = atapktio(drive, cmd10, 6);
  1031. else
  1032. reqstatus = atagenio(drive, cmd10, 6);
  1033. if(reqstatus == SDok){
  1034. r->flags |= SDvalidsense;
  1035. atasetsense(drive, SDok, 0, 0, 0);
  1036. }
  1037. }
  1038. qunlock(drive);
  1039. r->status = status;
  1040. if(status != SDok)
  1041. return status;
  1042. /*
  1043. * Fix up any results.
  1044. * Many ATAPI CD-ROMs ignore the LUN field completely and
  1045. * return valid INQUIRY data. Patch the response to indicate
  1046. * 'logical unit not supported' if the LUN is non-zero.
  1047. */
  1048. switch(cmdp[0]){
  1049. case 0x12: /* inquiry */
  1050. if((p = r->data) == nil)
  1051. break;
  1052. if((cmdp[1]>>5) && (!drive->pkt || (p[0] & 0x1F) == 0x05))
  1053. p[0] = 0x7F;
  1054. /*FALLTHROUGH*/
  1055. default:
  1056. break;
  1057. }
  1058. return SDok;
  1059. }
  1060. static void
  1061. atainterrupt(Ureg*, void* arg)
  1062. {
  1063. Ctlr *ctlr;
  1064. Drive *drive;
  1065. int cmdport, len, status;
  1066. ctlr = arg;
  1067. ilock(ctlr);
  1068. if(inb(ctlr->ctlport+As) & Bsy){
  1069. iunlock(ctlr);
  1070. if(DEBUG & DbgDEBUG)
  1071. print("IBsy+");
  1072. return;
  1073. }
  1074. cmdport = ctlr->cmdport;
  1075. status = inb(cmdport+Status);
  1076. if((drive = ctlr->curdrive) == nil){
  1077. iunlock(ctlr);
  1078. if((DEBUG & DbgDEBUG) && ctlr->command != Cedd)
  1079. print("Inil%2.2uX+", ctlr->command);
  1080. return;
  1081. }
  1082. if(status & Err)
  1083. drive->error = inb(cmdport+Error);
  1084. else switch(drive->command){
  1085. default:
  1086. drive->error = Abrt;
  1087. break;
  1088. case Crs:
  1089. case Crsm:
  1090. if(!(status & Drq)){
  1091. drive->error = Abrt;
  1092. break;
  1093. }
  1094. len = drive->block;
  1095. if(drive->data+len > drive->limit)
  1096. len = drive->limit-drive->data;
  1097. inss(cmdport+Data, drive->data, len/2);
  1098. drive->data += len;
  1099. if(drive->data >= drive->limit)
  1100. ctlr->done = 1;
  1101. break;
  1102. case Cws:
  1103. case Cwsm:
  1104. len = drive->block;
  1105. if(drive->data+len > drive->limit)
  1106. len = drive->limit-drive->data;
  1107. drive->data += len;
  1108. if(drive->data >= drive->limit){
  1109. ctlr->done = 1;
  1110. break;
  1111. }
  1112. if(!(status & Drq)){
  1113. drive->error = Abrt;
  1114. break;
  1115. }
  1116. len = drive->block;
  1117. if(drive->data+len > drive->limit)
  1118. len = drive->limit-drive->data;
  1119. outss(cmdport+Data, drive->data, len/2);
  1120. break;
  1121. case Cpkt:
  1122. atapktinterrupt(drive);
  1123. break;
  1124. case Crd:
  1125. case Cwd:
  1126. // atadmainterrupt(drive, drive->count*drive->secsize);
  1127. break;
  1128. }
  1129. iunlock(ctlr);
  1130. if(drive->error){
  1131. status |= Err;
  1132. ctlr->done = 1;
  1133. }
  1134. if(ctlr->done){
  1135. ctlr->curdrive = nil;
  1136. drive->status = status;
  1137. wakeup(ctlr);
  1138. }
  1139. }
  1140. static SDev*
  1141. atapnp(void)
  1142. {
  1143. Ctlr *ctlr;
  1144. Pcidev *p;
  1145. int channel, ispc87415, pi, r;
  1146. SDev *legacy[2], *sdev, *head, *tail;
  1147. legacy[0] = legacy[1] = head = tail = nil;
  1148. if(sdev = ataprobe(0x1F0, 0x3F4, IrqATA0)){
  1149. head = tail = sdev;
  1150. legacy[0] = sdev;
  1151. }
  1152. if(sdev = ataprobe(0x170, 0x374, IrqATA1)){
  1153. if(head != nil)
  1154. tail->next = sdev;
  1155. else
  1156. head = sdev;
  1157. tail = sdev;
  1158. legacy[1] = sdev;
  1159. }
  1160. p = nil;
  1161. while(p = pcimatch(p, 0, 0)){
  1162. /*
  1163. * Look for devices with the correct class and sub-class
  1164. * code and known device and vendor ID; add native-mode
  1165. * channels to the list to be probed, save info for the
  1166. * compatibility mode channels.
  1167. * Note that the legacy devices should not be considered
  1168. * PCI devices by the interrupt controller.
  1169. * For both native and legacy, save info for busmastering
  1170. * if capable.
  1171. * Promise Ultra ATA/66 (PDC20262) appears to
  1172. * 1) give a sub-class of 'other mass storage controller'
  1173. * instead of 'IDE controller', regardless of whether it's
  1174. * the only controller or not;
  1175. * 2) put 0 in the programming interface byte (probably
  1176. * as a consequence of 1) above).
  1177. */
  1178. if(p->ccrb != 0x01 || (p->ccru != 0x01 && p->ccru != 0x80))
  1179. continue;
  1180. pi = p->ccrp;
  1181. ispc87415 = 0;
  1182. switch((p->did<<16)|p->vid){
  1183. default:
  1184. continue;
  1185. case (0x0002<<16)|0x100B: /* NS PC87415 */
  1186. /*
  1187. * Disable interrupts on both channels until
  1188. * after they are probed for drives.
  1189. * This must be called before interrupts are
  1190. * enabled because the IRQ may be shared.
  1191. */
  1192. ispc87415 = 1;
  1193. pcicfgw32(p, 0x40, 0x00000300);
  1194. break;
  1195. case (0x1000<<16)|0x1042: /* PC-Tech RZ1000 */
  1196. /*
  1197. * Turn off prefetch. Overkill, but cheap.
  1198. */
  1199. r = pcicfgr32(p, 0x40);
  1200. r &= ~0x2000;
  1201. pcicfgw32(p, 0x40, r);
  1202. break;
  1203. case (0x4D38<<16)|0x105A: /* Promise PDC20262 */
  1204. case (0x4D30<<16)|0x105A: /* Promise PDC202xx */
  1205. case (0x0004<<16)|0x1103: /* HighPoint HPT-370 */
  1206. pi = 0x85;
  1207. break;
  1208. case (0x0640<<16)|0x1095: /* CMD 640B */
  1209. /*
  1210. * Bugfix code here...
  1211. */
  1212. break;
  1213. case (0x0646<<16)|0x1095: /* CMD 646 */
  1214. case (0x0571<<16)|0x1106: /* VIA 82C686 */
  1215. case (0x0211<<16)|0x1166: /* ServerWorks IB6566 */
  1216. case (0x1230<<16)|0x8086: /* 82371FB (PIIX) */
  1217. case (0x248A<<16)|0x8086: /* 82801BAM ICH2-M */
  1218. case (0x7010<<16)|0x8086: /* 82371SB (PIIX3) */
  1219. case (0x7111<<16)|0x8086: /* 82371[AE]B (PIIX4[E]) */
  1220. break;
  1221. }
  1222. for(channel = 0; channel < 2; channel++){
  1223. if(pi & (1<<(2*channel))){
  1224. sdev = ataprobe(p->mem[0+2*channel].bar & ~0x01,
  1225. p->mem[1+2*channel].bar & ~0x01,
  1226. p->intl);
  1227. if(sdev == nil)
  1228. continue;
  1229. ctlr = sdev->ctlr;
  1230. if(ispc87415)
  1231. ctlr->ienable = pc87415ienable;
  1232. if(head != nil)
  1233. tail->next = sdev;
  1234. else
  1235. head = sdev;
  1236. tail = sdev;
  1237. ctlr->tbdf = p->tbdf;
  1238. }
  1239. else if((sdev = legacy[channel]) == nil)
  1240. continue;
  1241. else
  1242. ctlr = sdev->ctlr;
  1243. ctlr->pcidev = p;
  1244. }
  1245. }
  1246. return head;
  1247. }
  1248. static SDev*
  1249. atalegacy(int port, int irq)
  1250. {
  1251. return ataprobe(port, port+0x204, irq);
  1252. }
  1253. static SDev*
  1254. ataid(SDev* sdev)
  1255. {
  1256. int i;
  1257. Ctlr *ctlr;
  1258. /*
  1259. * Legacy controllers are always 'C' and 'D' and if
  1260. * they exist and have drives will be first in the list.
  1261. * If there are no active legacy controllers, native
  1262. * controllers start at 'C'.
  1263. */
  1264. if(sdev == nil)
  1265. return nil;
  1266. ctlr = sdev->ctlr;
  1267. if(ctlr->cmdport == 0x1F0 || ctlr->cmdport == 0x170)
  1268. i = 2;
  1269. else
  1270. i = 0;
  1271. while(sdev){
  1272. if(sdev->ifc == &sdataifc){
  1273. ctlr = sdev->ctlr;
  1274. if(ctlr->cmdport == 0x1F0)
  1275. sdev->idno = 'C';
  1276. else if(ctlr->cmdport == 0x170)
  1277. sdev->idno = 'D';
  1278. else{
  1279. sdev->idno = 'C'+i;
  1280. i++;
  1281. }
  1282. // snprint(sdev->name, NAMELEN, "sd%c", sdev->idno);
  1283. }
  1284. sdev = sdev->next;
  1285. }
  1286. return nil;
  1287. }
  1288. static int
  1289. ataenable(SDev* sdev)
  1290. {
  1291. Ctlr *ctlr;
  1292. ctlr = sdev->ctlr;
  1293. setvec(ctlr->irq+VectorPIC, atainterrupt, ctlr);
  1294. outb(ctlr->ctlport+Dc, 0);
  1295. if(ctlr->ienable)
  1296. ctlr->ienable(ctlr);
  1297. return 1;
  1298. }
  1299. SDifc sdataifc = {
  1300. "ata", /* name */
  1301. atapnp, /* pnp */
  1302. atalegacy, /* legacy */
  1303. ataid, /* id */
  1304. ataenable, /* enable */
  1305. nil, /* disable */
  1306. scsiverify, /* verify */
  1307. scsionline, /* online */
  1308. atario, /* rio */
  1309. nil, /* rctl */
  1310. nil, /* wctl */
  1311. scsibio, /* bio */
  1312. };