sdata.c 44 KB

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