sdmylex.c 27 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249
  1. /*
  2. * Mylex MultiMaster (Buslogic BT-*) SCSI Host Adapter
  3. * in both 24-bit and 32-bit mode.
  4. * 24-bit mode works for Adaptec AHA-154xx series too.
  5. *
  6. * To do:
  7. * allocate more Ccb's as needed, up to NMbox-1;
  8. * add nmbox and nccb to Ctlr struct for the above;
  9. * 64-bit LUN/explicit wide support necessary?
  10. *
  11. */
  12. #include "u.h"
  13. #include "../port/lib.h"
  14. #include "mem.h"
  15. #include "dat.h"
  16. #include "fns.h"
  17. #include "io.h"
  18. #include "ureg.h"
  19. #include "../port/error.h"
  20. #include "../port/sd.h"
  21. #define K2BPA(va, tbdf) PADDR(va)
  22. #define BPA2K(pa, tbdf) KADDR(pa)
  23. extern SDifc sdmylexifc;
  24. enum { /* registers */
  25. Rcontrol = 0x00, /* WO: control register */
  26. Rstatus = 0x00, /* RO: status register */
  27. Rcpr = 0x01, /* WO: command/parameter register */
  28. Rdatain = 0x01, /* RO: data-in register */
  29. Rinterrupt = 0x02, /* RO: interrupt register */
  30. };
  31. enum { /* Rcontrol */
  32. Rsbus = 0x10, /* SCSI Bus Reset */
  33. Rint = 0x20, /* Interrupt Reset */
  34. Rsoft = 0x40, /* Soft Reset */
  35. Rhard = 0x80, /* Hard Reset */
  36. };
  37. enum { /* Rstatus */
  38. Cmdinv = 0x01, /* Command Invalid */
  39. Dirrdy = 0x04, /* Data In Register Ready */
  40. Cprbsy = 0x08, /* Command/Parameter Register Busy */
  41. Hardy = 0x10, /* Host Adapter Ready */
  42. Inreq = 0x20, /* Initialisation Required */
  43. Dfail = 0x40, /* Diagnostic Failure */
  44. Dact = 0x80, /* Diagnostic Active */
  45. };
  46. enum { /* Rcpr */
  47. Cinitialise = 0x01, /* Initialise Mailbox */
  48. Cstart = 0x02, /* Start Mailbox Command */
  49. Cinquiry = 0x04, /* Adapter Inquiry */
  50. Ceombri = 0x05, /* Enable OMBR Interrupt */
  51. Cinquire = 0x0B, /* Inquire Configuration */
  52. Cextbios = 0x28, /* AHA-1542: extended BIOS info. */
  53. Cmbienable = 0x29, /* AHA-1542: Mailbox interface enable */
  54. Ciem = 0x81, /* Initialise Extended Mailbox */
  55. Ciesi = 0x8D, /* Inquire Extended Setup Information */
  56. Cerrm = 0x8F, /* Enable strict round-robin mode */
  57. Cwide = 0x96, /* Wide CCB */
  58. };
  59. enum { /* Rinterrupt */
  60. Imbl = 0x01, /* Incoming Mailbox Loaded */
  61. Mbor = 0x02, /* Mailbox Out Ready */
  62. Cmdc = 0x04, /* Command Complete */
  63. Rsts = 0x08, /* SCSI Reset State */
  64. Intv = 0x80, /* Interrupt Valid */
  65. };
  66. typedef struct Mbox24 Mbox24;
  67. struct Mbox24 {
  68. uchar code; /* action/completion code */
  69. uchar ccb[3]; /* CCB pointer (MSB, ..., LSB) */
  70. };
  71. typedef struct Mbox32 Mbox32;
  72. struct Mbox32 {
  73. uchar ccb[4]; /* CCB pointer (LSB, ..., MSB) */
  74. uchar btstat; /* BT-7[45]7[SD] status */
  75. uchar sdstat; /* SCSI device status */
  76. uchar pad;
  77. uchar code; /* action/completion code */
  78. };
  79. enum { /* mailbox commands */
  80. Mbfree = 0x00, /* Mailbox not in use */
  81. Mbostart = 0x01, /* Start a mailbox command */
  82. Mboabort = 0x02, /* Abort a mailbox command */
  83. Mbiok = 0x01, /* CCB completed without error */
  84. Mbiabort = 0x02, /* CCB aborted at request of host */
  85. Mbinx = 0x03, /* Aborted CCB not found */
  86. Mbierror = 0x04, /* CCB completed with error */
  87. };
  88. typedef struct Ccb24 Ccb24;
  89. typedef struct Ccb32 Ccb32;
  90. typedef union Ccb Ccb;
  91. typedef struct Ccb24 {
  92. uchar opcode; /* Operation code */
  93. uchar datadir; /* Data direction control */
  94. uchar cdblen; /* Length of CDB */
  95. uchar senselen; /* Length of sense area */
  96. uchar datalen[3]; /* Data length (MSB, ..., LSB) */
  97. uchar dataptr[3]; /* Data pointer (MSB, ..., LSB) */
  98. uchar linkptr[3]; /* Link pointer (MSB, ..., LSB) */
  99. uchar linkid; /* command linking identifier */
  100. uchar btstat; /* BT-* adapter status */
  101. uchar sdstat; /* SCSI device status */
  102. uchar reserved[2]; /* */
  103. uchar cs[12+0xFF]; /* Command descriptor block + Sense */
  104. void* data; /* buffer if address > 24-bits */
  105. Rendez;
  106. int done; /* command completed */
  107. Ccb* ccb; /* link on free list */
  108. } Ccb24;
  109. typedef struct Ccb32 {
  110. uchar opcode; /* Operation code */
  111. uchar datadir; /* Data direction control */
  112. uchar cdblen; /* Length of CDB */
  113. uchar senselen; /* Length of sense area */
  114. uchar datalen[4]; /* Data length (LSB, ..., MSB) */
  115. uchar dataptr[4]; /* Data pointer (LSB, ..., MSB) */
  116. uchar reserved[2];
  117. uchar btstat; /* BT-* adapter status */
  118. uchar sdstat; /* SCSI device status */
  119. uchar targetid; /* Target ID */
  120. uchar luntag; /* LUN & tag */
  121. uchar cdb[12]; /* Command descriptor block */
  122. uchar ccbctl; /* CCB control */
  123. uchar linkid; /* command linking identifier */
  124. uchar linkptr[4]; /* Link pointer (LSB, ..., MSB) */
  125. uchar senseptr[4]; /* Sense pointer (LSB, ..., MSB) */
  126. uchar sense[0xFF]; /* Sense bytes */
  127. Rendez;
  128. int done; /* command completed */
  129. Ccb* ccb; /* link on free list */
  130. } Ccb32;
  131. typedef union Ccb {
  132. Ccb24;
  133. Ccb32;
  134. } Ccb;
  135. enum { /* opcode */
  136. OInitiator = 0x00, /* initiator CCB */
  137. Ordl = 0x03, /* initiator CCB with
  138. * residual data length returned
  139. */
  140. };
  141. enum { /* datadir */
  142. CCBdatain = 0x08, /* inbound, length is checked */
  143. CCBdataout = 0x10, /* outbound, length is checked */
  144. };
  145. enum { /* btstat */
  146. Eok = 0x00, /* normal completion with no errors */
  147. };
  148. enum { /* luntag */
  149. TagEnable = 0x20, /* Tag enable */
  150. SQTag = 0x00, /* Simple Queue Tag */
  151. HQTag = 0x40, /* Head of Queue Tag */
  152. OQTag = 0x80, /* Ordered Queue Tag */
  153. };
  154. enum { /* CCB control */
  155. NoDisc = 0x08, /* No disconnect */
  156. NoUnd = 0x10, /* No underrrun error report */
  157. NoData = 0x20, /* No data transfer */
  158. NoStat = 0x40, /* No CCB status if zero */
  159. NoIntr = 0x80, /* No Interrupts */
  160. };
  161. typedef struct Ctlr Ctlr;
  162. struct Ctlr {
  163. int port; /* I/O port */
  164. int id; /* adapter SCSI id */
  165. int bus; /* 24 or 32 -bit */
  166. int irq;
  167. int wide;
  168. Pcidev* pcidev;
  169. SDev* sdev;
  170. int spurious;
  171. Lock issuelock;
  172. Lock ccblock;
  173. QLock ccbq;
  174. Rendez ccbr;
  175. Lock mboxlock;
  176. void* mb; /* mailbox out + mailbox in */
  177. int mbox; /* current mailbox out index into mb */
  178. int mbix; /* current mailbox in index into mb */
  179. Lock cachelock;
  180. Ccb* ccb; /* list of free Ccb's */
  181. Ccb** cache; /* last completed Ccb */
  182. };
  183. /*
  184. * The number of mailboxes should be a multiple of 8 (4 for Mbox32)
  185. * to ensure the boundary between the out and in mailboxes doesn't
  186. * straddle a cache-line boundary.
  187. * The number of Ccb's should be less than the number of mailboxes to
  188. * ensure no queueing is necessary on mailbox allocation.
  189. */
  190. enum {
  191. NMbox = 8*8, /* number of Mbox's */
  192. NCcb = NMbox-1, /* number of Ccb's */
  193. };
  194. #define PADDR24(a, n) ((PADDR(a)+(n)) <= (1<<24))
  195. static void
  196. ccbfree(Ctlr* ctlr, Ccb* ccb)
  197. {
  198. lock(&ctlr->ccblock);
  199. if(ctlr->bus == 24)
  200. ((Ccb24*)ccb)->ccb = ctlr->ccb;
  201. else
  202. ((Ccb32*)ccb)->ccb = ctlr->ccb;
  203. if(ctlr->ccb == nil)
  204. wakeup(&ctlr->ccbr);
  205. ctlr->ccb = ccb;
  206. unlock(&ctlr->ccblock);
  207. }
  208. static int
  209. ccbavailable(void* a)
  210. {
  211. return ((Ctlr*)a)->ccb != nil;
  212. }
  213. static Ccb*
  214. ccballoc(Ctlr* ctlr)
  215. {
  216. Ccb *ccb;
  217. for(;;){
  218. lock(&ctlr->ccblock);
  219. if((ccb = ctlr->ccb) != nil){
  220. if(ctlr->bus == 24)
  221. ctlr->ccb = ((Ccb24*)ccb)->ccb;
  222. else
  223. ctlr->ccb = ((Ccb32*)ccb)->ccb;
  224. unlock(&ctlr->ccblock);
  225. break;
  226. }
  227. unlock(&ctlr->ccblock);
  228. qlock(&ctlr->ccbq);
  229. if(waserror()){
  230. qunlock(&ctlr->ccbq);
  231. continue;
  232. }
  233. sleep(&ctlr->ccbr, ccbavailable, ctlr);
  234. qunlock(&ctlr->ccbq);
  235. poperror();
  236. }
  237. return ccb;
  238. }
  239. static int
  240. done24(void* arg)
  241. {
  242. return ((Ccb24*)arg)->done;
  243. }
  244. static int
  245. mylex24rio(SDreq* r)
  246. {
  247. ulong p;
  248. Ctlr *ctlr;
  249. Ccb24 *ccb;
  250. Mbox24 *mb;
  251. uchar *data, lun, *sense;
  252. int d, n, btstat, sdstat, target;
  253. ctlr = r->unit->dev->ctlr;
  254. target = r->unit->subno;
  255. lun = (r->cmd[1]>>5) & 0x07;
  256. /*
  257. * Ctlr->cache holds the last completed Ccb for this target if it
  258. * returned 'check condition'.
  259. * If this command is a request-sense and there is valid sense data
  260. * from the last completed Ccb, return it immediately.
  261. */
  262. lock(&ctlr->cachelock);
  263. if((ccb = ctlr->cache[target]) != nil){
  264. ctlr->cache[target] = nil;
  265. if(r->cmd[0] == 0x03
  266. && ccb->sdstat == SDcheck && lun == ((ccb->cs[1]>>5) & 0x07)){
  267. unlock(&ctlr->cachelock);
  268. if(r->dlen){
  269. sense = &ccb->cs[ccb->cdblen];
  270. n = 8+sense[7];
  271. if(n > r->dlen)
  272. n = r->dlen;
  273. memmove(r->data, sense, n);
  274. r->rlen = n;
  275. }
  276. ccbfree(ctlr, (Ccb*)ccb);
  277. return SDok;
  278. }
  279. }
  280. unlock(&ctlr->cachelock);
  281. if(ccb == nil)
  282. ccb = ccballoc(ctlr);
  283. /*
  284. * Check if the transfer is to memory above the 24-bit limit the
  285. * controller can address. If it is, try to allocate a temporary
  286. * buffer as a staging area.
  287. */
  288. n = r->dlen;
  289. if(n && !PADDR24(r->data, n)){
  290. data = mallocz(n, 0);
  291. if(data == nil || !PADDR24(data, n)){
  292. if(data != nil){
  293. free(data);
  294. ccb->data = nil;
  295. }
  296. ccbfree(ctlr, (Ccb*)ccb);
  297. return SDmalloc;
  298. }
  299. if(r->write)
  300. memmove(data, r->data, n);
  301. ccb->data = r->data;
  302. }
  303. else
  304. data = r->data;
  305. /*
  306. * Fill in the ccb.
  307. */
  308. ccb->opcode = Ordl;
  309. ccb->datadir = (target<<5)|lun;
  310. if(n == 0)
  311. ccb->datadir |= CCBdataout|CCBdatain;
  312. else if(!r->write)
  313. ccb->datadir |= CCBdatain;
  314. else
  315. ccb->datadir |= CCBdataout;
  316. ccb->cdblen = r->clen;
  317. ccb->senselen = 0xFF;
  318. ccb->datalen[0] = n>>16;
  319. ccb->datalen[1] = n>>8;
  320. ccb->datalen[2] = n;
  321. p = PADDR(data);
  322. ccb->dataptr[0] = p>>16;
  323. ccb->dataptr[1] = p>>8;
  324. ccb->dataptr[2] = p;
  325. ccb->linkptr[0] = ccb->linkptr[1] = ccb->linkptr[2] = 0;
  326. ccb->linkid = 0;
  327. ccb->btstat = ccb->sdstat = 0;
  328. ccb->reserved[0] = ccb->reserved[1] = 0;
  329. memmove(ccb->cs, r->cmd, r->clen);
  330. /*
  331. * There's one more mbox than there there is
  332. * ccb so there is always one free.
  333. */
  334. lock(&ctlr->mboxlock);
  335. mb = ctlr->mb;
  336. mb += ctlr->mbox;
  337. p = PADDR(ccb);
  338. mb->ccb[0] = p>>16;
  339. mb->ccb[1] = p>>8;
  340. mb->ccb[2] = p;
  341. mb->code = Mbostart;
  342. ctlr->mbox++;
  343. if(ctlr->mbox >= NMbox)
  344. ctlr->mbox = 0;
  345. /*
  346. * This command does not require Hardy
  347. * and doesn't generate a Cmdc interrupt.
  348. */
  349. ccb->done = 0;
  350. outb(ctlr->port+Rcpr, Cstart);
  351. unlock(&ctlr->mboxlock);
  352. /*
  353. * Wait for the request to complete and return the status.
  354. * Since the buffer is not reference counted cannot return
  355. * until the DMA is done writing into the buffer so the caller
  356. * cannot free the buffer prematurely.
  357. */
  358. while(waserror())
  359. ;
  360. sleep(ccb, done24, ccb);
  361. poperror();
  362. /*
  363. * Save the status and patch up the number of
  364. * bytes actually transferred.
  365. * There's a firmware bug on some 956C controllers
  366. * which causes the return count from a successful
  367. * READ CAPACITY not be updated, so fix it here.
  368. */
  369. sdstat = ccb->sdstat;
  370. btstat = ccb->btstat;
  371. d = ccb->datalen[0]<<16;
  372. d |= ccb->datalen[1]<<8;
  373. d |= ccb->datalen[2];
  374. if(ccb->cs[0] == 0x25 && sdstat == SDok)
  375. d = 0;
  376. n -= d;
  377. r->rlen = n;
  378. /*
  379. * Tidy things up if a staging area was used for the data,
  380. */
  381. if(ccb->data != nil){
  382. if(sdstat == SDok && btstat == 0 && !r->write)
  383. memmove(ccb->data, data, n);
  384. free(data);
  385. ccb->data = nil;
  386. }
  387. /*
  388. * If there was a check-condition, save the
  389. * ccb for a possible request-sense command.
  390. */
  391. if(sdstat == SDcheck){
  392. if(r->flags & SDnosense){
  393. lock(&ctlr->cachelock);
  394. if(ctlr->cache[target])
  395. ccbfree(ctlr, ctlr->cache[target]);
  396. ctlr->cache[target] = (Ccb*)ccb;
  397. unlock(&ctlr->cachelock);
  398. return SDcheck;
  399. }
  400. sense = &ccb->cs[ccb->cdblen];
  401. n = 8+sense[7];
  402. if(n > sizeof(r->sense)-1)
  403. n = sizeof(r->sense)-1;
  404. memmove(r->sense, sense, n);
  405. r->flags |= SDvalidsense;
  406. }
  407. ccbfree(ctlr, (Ccb*)ccb);
  408. if(btstat){
  409. if(btstat == 0x11)
  410. return SDtimeout;
  411. return SDeio;
  412. }
  413. return sdstat;
  414. }
  415. static void
  416. mylex24interrupt(Ureg*, void* arg)
  417. {
  418. ulong pa;
  419. Ctlr *ctlr;
  420. Ccb24 *ccb;
  421. Mbox24 *mb, *mbox;
  422. int port, rinterrupt, rstatus;
  423. ctlr = arg;
  424. port = ctlr->port;
  425. /*
  426. * Save and clear the interrupt(s). The only
  427. * interrupts expected are Cmdc, which is ignored,
  428. * and Imbl which means something completed.
  429. * There's one spurious interrupt left over from
  430. * initialisation, ignore it.
  431. */
  432. rinterrupt = inb(port+Rinterrupt);
  433. rstatus = inb(port+Rstatus);
  434. outb(port+Rcontrol, Rint);
  435. if((rinterrupt & ~(Cmdc|Imbl)) != Intv && ctlr->spurious++)
  436. print("%s: interrupt 0x%2.2ux\n",
  437. ctlr->sdev->name, rinterrupt);
  438. if((rinterrupt & Cmdc) && (rstatus & Cmdinv))
  439. print("%s: command invalid\n", ctlr->sdev->name);
  440. /*
  441. * Look for something in the mail.
  442. * If there is, save the status, free the mailbox
  443. * and wakeup whoever.
  444. */
  445. mb = ctlr->mb;
  446. for(mbox = &mb[ctlr->mbix]; mbox->code; mbox = &mb[ctlr->mbix]){
  447. pa = (mbox->ccb[0]<<16)|(mbox->ccb[1]<<8)|mbox->ccb[2];
  448. ccb = BPA2K(pa, BUSUNKNOWN);
  449. mbox->code = 0;
  450. ccb->done = 1;
  451. wakeup(ccb);
  452. ctlr->mbix++;
  453. if(ctlr->mbix >= NMbox+NMbox)
  454. ctlr->mbix = NMbox;
  455. }
  456. }
  457. static int
  458. done32(void* arg)
  459. {
  460. return ((Ccb32*)arg)->done;
  461. }
  462. static int
  463. mylex32rio(SDreq* r)
  464. {
  465. ulong p;
  466. uchar lun;
  467. Ctlr *ctlr;
  468. Ccb32 *ccb;
  469. Mbox32 *mb;
  470. int d, n, btstat, sdstat, target;
  471. ctlr = r->unit->dev->ctlr;
  472. target = r->unit->subno;
  473. lun = (r->cmd[1]>>5) & 0x07;
  474. /*
  475. * Ctlr->cache holds the last completed Ccb for this target if it
  476. * returned 'check condition'.
  477. * If this command is a request-sense and there is valid sense data
  478. * from the last completed Ccb, return it immediately.
  479. */
  480. lock(&ctlr->cachelock);
  481. if((ccb = ctlr->cache[target]) != nil){
  482. ctlr->cache[target] = nil;
  483. if(r->cmd[0] == 0x03
  484. && ccb->sdstat == SDcheck && lun == (ccb->luntag & 0x07)){
  485. unlock(&ctlr->cachelock);
  486. if(r->dlen){
  487. n = 8+ccb->sense[7];
  488. if(n > r->dlen)
  489. n = r->dlen;
  490. memmove(r->data, ccb->sense, n);
  491. r->rlen = n;
  492. }
  493. ccbfree(ctlr, (Ccb*)ccb);
  494. return SDok;
  495. }
  496. }
  497. unlock(&ctlr->cachelock);
  498. if(ccb == nil)
  499. ccb = ccballoc(ctlr);
  500. /*
  501. * Fill in the ccb.
  502. */
  503. ccb->opcode = Ordl;
  504. n = r->dlen;
  505. if(n == 0)
  506. ccb->datadir = CCBdataout|CCBdatain;
  507. else if(!r->write)
  508. ccb->datadir = CCBdatain;
  509. else
  510. ccb->datadir = CCBdataout;
  511. ccb->cdblen = r->clen;
  512. ccb->datalen[0] = n;
  513. ccb->datalen[1] = n>>8;
  514. ccb->datalen[2] = n>>16;
  515. ccb->datalen[3] = n>>24;
  516. p = PADDR(r->data);
  517. ccb->dataptr[0] = p;
  518. ccb->dataptr[1] = p>>8;
  519. ccb->dataptr[2] = p>>16;
  520. ccb->dataptr[3] = p>>24;
  521. ccb->targetid = target;
  522. ccb->luntag = lun;
  523. if(r->unit->inquiry[7] & 0x02)
  524. ccb->luntag |= SQTag|TagEnable;
  525. memmove(ccb->cdb, r->cmd, r->clen);
  526. ccb->btstat = ccb->sdstat = 0;
  527. ccb->ccbctl = 0;
  528. /*
  529. * There's one more mbox than there there is
  530. * ccb so there is always one free.
  531. */
  532. lock(&ctlr->mboxlock);
  533. mb = ctlr->mb;
  534. mb += ctlr->mbox;
  535. p = PADDR(ccb);
  536. mb->ccb[0] = p;
  537. mb->ccb[1] = p>>8;
  538. mb->ccb[2] = p>>16;
  539. mb->ccb[3] = p>>24;
  540. mb->code = Mbostart;
  541. ctlr->mbox++;
  542. if(ctlr->mbox >= NMbox)
  543. ctlr->mbox = 0;
  544. /*
  545. * This command does not require Hardy
  546. * and doesn't generate a Cmdc interrupt.
  547. */
  548. ccb->done = 0;
  549. outb(ctlr->port+Rcpr, Cstart);
  550. unlock(&ctlr->mboxlock);
  551. /*
  552. * Wait for the request to complete and return the status.
  553. * Since the buffer is not reference counted cannot return
  554. * until the DMA is done writing into the buffer so the caller
  555. * cannot free the buffer prematurely.
  556. */
  557. while(waserror())
  558. ;
  559. sleep(ccb, done32, ccb);
  560. poperror();
  561. /*
  562. * Save the status and patch up the number of
  563. * bytes actually transferred.
  564. * There's a firmware bug on some 956C controllers
  565. * which causes the return count from a successful
  566. * READ CAPACITY not to be updated, so fix it here.
  567. */
  568. sdstat = ccb->sdstat;
  569. btstat = ccb->btstat;
  570. d = ccb->datalen[0];
  571. d |= (ccb->datalen[1]<<8);
  572. d |= (ccb->datalen[2]<<16);
  573. d |= (ccb->datalen[3]<<24);
  574. if(ccb->cdb[0] == 0x25 && sdstat == SDok)
  575. d = 0;
  576. n -= d;
  577. r->rlen = n;
  578. /*
  579. * If there was a check-condition, save the
  580. * ccb for a possible request-sense command.
  581. */
  582. if(sdstat == SDcheck){
  583. if(r->flags & SDnosense){
  584. lock(&ctlr->cachelock);
  585. if(ctlr->cache[target])
  586. ccbfree(ctlr, ctlr->cache[target]);
  587. ctlr->cache[target] = (Ccb*)ccb;
  588. unlock(&ctlr->cachelock);
  589. return SDcheck;
  590. }
  591. n = 8+ccb->sense[7];
  592. if(n > sizeof(r->sense)-1)
  593. n = sizeof(r->sense)-1;
  594. memmove(r->sense, ccb->sense, n);
  595. r->flags |= SDvalidsense;
  596. }
  597. ccbfree(ctlr, (Ccb*)ccb);
  598. if(btstat){
  599. if(btstat == 0x11)
  600. return SDtimeout;
  601. return SDeio;
  602. }
  603. return sdstat;
  604. }
  605. static void
  606. mylex32interrupt(Ureg*, void* arg)
  607. {
  608. ulong pa;
  609. Ctlr *ctlr;
  610. Ccb32 *ccb;
  611. Mbox32 *mb, *mbox;
  612. int port, rinterrupt, rstatus;
  613. ctlr = arg;
  614. port = ctlr->port;
  615. /*
  616. * Save and clear the interrupt(s). The only
  617. * interrupts expected are Cmdc, which is ignored,
  618. * and Imbl which means something completed.
  619. * There's one spurious interrupt left over from
  620. * initialisation, ignore it.
  621. */
  622. rinterrupt = inb(port+Rinterrupt);
  623. rstatus = inb(port+Rstatus);
  624. outb(port+Rcontrol, Rint);
  625. if((rinterrupt & ~(Cmdc|Imbl)) != Intv && ctlr->spurious++)
  626. print("%s: interrupt 0x%2.2ux\n",
  627. ctlr->sdev->name, rinterrupt);
  628. if((rinterrupt & Cmdc) && (rstatus & Cmdinv))
  629. print("%s: command invalid\n", ctlr->sdev->name);
  630. /*
  631. * Look for something in the mail.
  632. * If there is, free the mailbox and wakeup whoever.
  633. */
  634. mb = ctlr->mb;
  635. for(mbox = &mb[ctlr->mbix]; mbox->code; mbox = &mb[ctlr->mbix]){
  636. pa = (mbox->ccb[3]<<24)
  637. |(mbox->ccb[2]<<16)
  638. |(mbox->ccb[1]<<8)
  639. |mbox->ccb[0];
  640. if(ctlr->pcidev)
  641. ccb = BPA2K(pa, ctlr->pcidev->tbdf);
  642. else
  643. ccb = BPA2K(pa, BUSUNKNOWN);
  644. mbox->code = 0;
  645. ccb->done = 1;
  646. wakeup(ccb);
  647. ctlr->mbix++;
  648. if(ctlr->mbix >= NMbox+NMbox)
  649. ctlr->mbix = NMbox;
  650. }
  651. }
  652. static int
  653. mylexrio(SDreq* r)
  654. {
  655. int subno;
  656. Ctlr *ctlr;
  657. subno = r->unit->subno;
  658. ctlr = r->unit->dev->ctlr;
  659. if(subno == ctlr->id || (!ctlr->wide && subno >= 8))
  660. r->status = SDtimeout;
  661. else if(ctlr->bus == 24)
  662. r->status = mylex24rio(r);
  663. else
  664. r->status = mylex32rio(r);
  665. return r->status;
  666. }
  667. /*
  668. * Issue a command to a controller. The command and its length is
  669. * contained in cmd and cmdlen. If any data is to be
  670. * returned, datalen should be non-zero, and the returned data
  671. * will be placed in data.
  672. * If Cmdc is set, bail out, the invalid command will be handled
  673. * when the interrupt is processed.
  674. */
  675. static void
  676. issueio(int port, uchar* cmd, int cmdlen, uchar* data, int datalen)
  677. {
  678. int len;
  679. if(cmd[0] != Cstart && cmd[0] != Ceombri){
  680. while(!(inb(port+Rstatus) & Hardy))
  681. ;
  682. }
  683. outb(port+Rcpr, cmd[0]);
  684. len = 1;
  685. while(len < cmdlen){
  686. if(!(inb(port+Rstatus) & Cprbsy)){
  687. outb(port+Rcpr, cmd[len]);
  688. len++;
  689. }
  690. if(inb(port+Rinterrupt) & Cmdc)
  691. return;
  692. }
  693. if(datalen){
  694. len = 0;
  695. while(len < datalen){
  696. if(inb(port+Rstatus) & Dirrdy){
  697. data[len] = inb(port+Rdatain);
  698. len++;
  699. }
  700. if(inb(port+Rinterrupt) & Cmdc)
  701. return;
  702. }
  703. }
  704. }
  705. /*
  706. * Issue a command to a controller, wait for it to complete then
  707. * try to reset the interrupt. Should only be called at initialisation.
  708. */
  709. static int
  710. issue(Ctlr* ctlr, uchar* cmd, int cmdlen, uchar* data, int datalen)
  711. {
  712. int port;
  713. uchar rinterrupt, rstatus;
  714. static Lock mylexissuelock;
  715. port = ctlr->port;
  716. ilock(&ctlr->issuelock);
  717. issueio(port, cmd, cmdlen, data, datalen);
  718. while(!((rinterrupt = inb(port+Rinterrupt)) & Cmdc))
  719. ;
  720. rstatus = inb(port+Rstatus);
  721. outb(port+Rcontrol, Rint);
  722. iunlock(&ctlr->issuelock);
  723. if((rinterrupt & Cmdc) && (rstatus & Cmdinv))
  724. return 0;
  725. return 1;
  726. }
  727. static SDev*
  728. mylexprobe(int port, int irq)
  729. {
  730. SDev *sdev;
  731. Ctlr *ctlr;
  732. uchar cmd[6], data[256];
  733. int clen, dlen, timeo;
  734. if(ioalloc(port, 0x3, 0, "mylex") < 0)
  735. return nil;
  736. ctlr = nil;
  737. sdev = nil;
  738. /*
  739. * Attempt to hard-reset the board and reset
  740. * the SCSI bus. If the board state doesn't settle to
  741. * idle with mailbox initialisation required, either
  742. * it isn't a compatible board or it's broken.
  743. * If the controller has SCAM set this can take a while.
  744. */
  745. if(getconf("*noscsireset") != nil)
  746. outb(port+Rcontrol, Rhard);
  747. else
  748. outb(port+Rcontrol, Rhard|Rsbus);
  749. for(timeo = 0; timeo < 100; timeo++){
  750. if(inb(port+Rstatus) == (Inreq|Hardy))
  751. break;
  752. delay(100);
  753. }
  754. if(inb(port+Rstatus) != (Inreq|Hardy)){
  755. buggery:
  756. if(ctlr != nil)
  757. free(ctlr);
  758. if (sdev != nil)
  759. free(sdev);
  760. iofree(port);
  761. return nil;
  762. }
  763. if((ctlr = malloc(sizeof(Ctlr))) == nil)
  764. goto buggery;
  765. ctlr->port = port;
  766. ctlr->irq = irq;
  767. ctlr->bus = 24;
  768. ctlr->wide = 0;
  769. /*
  770. * Try to determine if this is a 32-bit MultiMaster controller
  771. * by attempting to obtain the extended inquiry information;
  772. * this command is not implemented on Adaptec 154xx
  773. * controllers. If successful, the first byte of the returned
  774. * data is the host adapter bus type, 'E' for 32-bit EISA,
  775. * PCI and VLB buses.
  776. */
  777. cmd[0] = Ciesi;
  778. cmd[1] = 4;
  779. clen = 2;
  780. dlen = 256;
  781. if(issue(ctlr, cmd, clen, data, dlen)){
  782. if(data[0] == 'E')
  783. ctlr->bus = 32;
  784. ctlr->wide = data[0x0D] & 0x01;
  785. }
  786. else{
  787. /*
  788. * Inconceivable though it may seem, a hard controller reset
  789. * is necessary here to clear out the command queue. Every
  790. * board seems to lock-up in a different way if you give an
  791. * invalid command and then try to clear out the
  792. * command/parameter and/or data-in register.
  793. * Soft reset doesn't do the job either. Fortunately no
  794. * serious initialisation has been done yet so there's nothing
  795. * to tidy up.
  796. */
  797. outb(port+Rcontrol, Rhard);
  798. for(timeo = 0; timeo < 100; timeo++){
  799. if(inb(port+Rstatus) == (Inreq|Hardy))
  800. break;
  801. delay(100);
  802. }
  803. if(inb(port+Rstatus) != (Inreq|Hardy))
  804. goto buggery;
  805. }
  806. /*
  807. * If the BIOS is enabled on the AHA-1542C/CF and BIOS options for
  808. * support of drives > 1Gb, dynamic scanning of the SCSI bus or more
  809. * than 2 drives under DOS 5.0 are enabled, the BIOS disables
  810. * accepting Cmbinit to protect against running with drivers which
  811. * don't support those options. In order to unlock the interface it
  812. * is necessary to read a lock-code using Cextbios and write it back
  813. * using Cmbienable; the lock-code is non-zero.
  814. */
  815. cmd[0] = Cinquiry;
  816. clen = 1;
  817. dlen = 4;
  818. if(issue(ctlr, cmd, clen, data, dlen) == 0)
  819. goto buggery;
  820. if(data[0] >= 0x43){
  821. cmd[0] = Cextbios;
  822. clen = 1;
  823. dlen = 2;
  824. if(issue(ctlr, cmd, clen, data, dlen) == 0)
  825. goto buggery;
  826. /*
  827. * Lock-code returned in data[1]. If it's non-zero write
  828. * it back along with bit 0 of byte 0 cleared to enable
  829. * mailbox initialisation.
  830. */
  831. if(data[1]){
  832. cmd[0] = Cmbienable;
  833. cmd[1] = 0;
  834. cmd[2] = data[1];
  835. clen = 3;
  836. if(issue(ctlr, cmd, clen, 0, 0) == 0)
  837. goto buggery;
  838. }
  839. }
  840. /*
  841. * Get the id, DMA and IRQ info from the board. This will
  842. * cause an interrupt which will hopefully not cause any
  843. * trouble because the interrupt number isn't known yet.
  844. * This is necessary as the DMA won't be set up if the
  845. * board has the BIOS disabled.
  846. *
  847. * If the IRQ is already known, this must be a 32-bit PCI
  848. * or EISA card, in which case the returned DMA and IRQ can
  849. * be ignored.
  850. */
  851. cmd[0] = Cinquire;
  852. clen = 1;
  853. dlen = 3;
  854. if(issue(ctlr, cmd, clen, data, dlen) == 0)
  855. goto buggery;
  856. ctlr->id = data[2] & 0x07;
  857. if(ctlr->irq < 0){
  858. switch(data[0]){ /* DMA Arbitration Priority */
  859. case 0x80: /* Channel 7 */
  860. outb(0xD6, 0xC3);
  861. outb(0xD4, 0x03);
  862. break;
  863. case 0x40: /* Channel 6 */
  864. outb(0xD6, 0xC2);
  865. outb(0xD4, 0x02);
  866. break;
  867. case 0x20: /* Channel 5 */
  868. outb(0xD6, 0xC1);
  869. outb(0xD4, 0x01);
  870. break;
  871. case 0x01: /* Channel 0 */
  872. outb(0x0B, 0xC0);
  873. outb(0x0A, 0x00);
  874. break;
  875. default:
  876. if(ctlr->bus == 24)
  877. goto buggery;
  878. break;
  879. }
  880. switch(data[1]){ /* Interrupt Channel */
  881. case 0x40:
  882. ctlr->irq = 15;
  883. break;
  884. case 0x20:
  885. ctlr->irq = 14;
  886. break;
  887. case 0x08:
  888. ctlr->irq = 12;
  889. break;
  890. case 0x04:
  891. ctlr->irq = 11;
  892. break;
  893. case 0x02:
  894. ctlr->irq = 10;
  895. break;
  896. case 0x01:
  897. ctlr->irq = 9;
  898. break;
  899. default:
  900. goto buggery;
  901. }
  902. }
  903. if((sdev = malloc(sizeof(SDev))) == nil)
  904. goto buggery;
  905. sdev->ifc = &sdmylexifc;
  906. sdev->ctlr = ctlr;
  907. ctlr->sdev = sdev;
  908. if(!ctlr->wide)
  909. sdev->nunit = 8;
  910. else
  911. sdev->nunit = 16;
  912. return sdev;
  913. }
  914. static int mylexport[8] = {
  915. 0x330, 0x334, 0x230, 0x234, 0x130, 0x134, 0x000, 0x000,
  916. };
  917. static SDev*
  918. mylexpnp(void)
  919. {
  920. Pcidev *p;
  921. Ctlr *ctlr;
  922. ISAConf isa;
  923. int cfg, ctlrno, i, x;
  924. SDev *sdev, *head, *tail;
  925. p = nil;
  926. head = tail = nil;
  927. while(p = pcimatch(p, 0x104B, 0)){
  928. if((sdev = mylexprobe(p->mem[0].bar & ~0x01, p->intl)) == nil)
  929. continue;
  930. ctlr = sdev->ctlr;
  931. ctlr->pcidev = p;
  932. if(head != nil)
  933. tail->next = sdev;
  934. else
  935. head = sdev;
  936. tail = sdev;
  937. }
  938. if(strncmp(KADDR(0xFFFD9), "EISA", 4) == 0){
  939. for(cfg = 0x1000; cfg < MaxEISA*0x1000; cfg += 0x1000){
  940. x = 0;
  941. for(i = 0; i < 4; i++)
  942. x |= inb(cfg+CfgEISA+i)<<(i*8);
  943. if(x != 0x0142B30A && x != 0x0242B30A)
  944. continue;
  945. x = inb(cfg+0xC8C);
  946. if((sdev = mylexprobe(mylexport[x & 0x07], -1)) == nil)
  947. continue;
  948. if(head != nil)
  949. tail->next = sdev;
  950. else
  951. head = sdev;
  952. tail = sdev;
  953. }
  954. }
  955. for(ctlrno = 0; ctlrno < 4; ctlrno++){
  956. memset(&isa, 0, sizeof(isa));
  957. if(!isaconfig("scsi", ctlrno, &isa))
  958. continue;
  959. if(strcmp(isa.type, "aha1542"))
  960. continue;
  961. if((sdev = mylexprobe(isa.port, -1)) == nil)
  962. continue;
  963. if(head != nil)
  964. tail->next = sdev;
  965. else
  966. head = sdev;
  967. tail = sdev;
  968. }
  969. return head;
  970. }
  971. static SDev*
  972. mylexid(SDev* sdev)
  973. {
  974. return scsiid(sdev, &sdmylexifc);
  975. }
  976. static int
  977. mylex24enable(Ctlr* ctlr)
  978. {
  979. ulong p;
  980. Ccb24 *ccb, *ccbp;
  981. uchar cmd[6], *v;
  982. int len;
  983. len = (sizeof(Mbox24)*NMbox*2)+(sizeof(Ccb24)*NCcb);
  984. v = xspanalloc(len, 32, 0);
  985. if(!PADDR24(ctlr, sizeof(Ctlr)) || !PADDR24(v, len))
  986. return 0;
  987. ctlr->mb = v;
  988. v += sizeof(Mbox24)*NMbox*2;
  989. ccb = (Ccb24*)v;
  990. for(ccbp = ccb; ccbp < &ccb[NCcb]; ccbp++){
  991. ccbp->ccb = ctlr->ccb;
  992. ctlr->ccb = (Ccb*)ccbp;
  993. }
  994. /*
  995. * Initialise the software controller and
  996. * set the board scanning the mailboxes.
  997. */
  998. ctlr->mbix = NMbox;
  999. cmd[0] = Cinitialise;
  1000. cmd[1] = NMbox;
  1001. p = K2BPA(ctlr->mb, BUSUNKNOWN);
  1002. cmd[2] = p>>16;
  1003. cmd[3] = p>>8;
  1004. cmd[4] = p;
  1005. return issue(ctlr, cmd, 5, 0, 0);
  1006. }
  1007. static int
  1008. mylex32enable(Ctlr* ctlr)
  1009. {
  1010. ulong p;
  1011. Ccb32 *ccb, *ccbp;
  1012. uchar cmd[6], *v;
  1013. v = xspanalloc((sizeof(Mbox32)*NMbox*2)+(sizeof(Ccb32)*NCcb), 32, 0);
  1014. ctlr->mb = v;
  1015. v += sizeof(Mbox32)*NMbox*2;
  1016. ccb = (Ccb32*)v;
  1017. for(ccbp = ccb; ccbp < &ccb[NCcb]; ccbp++){
  1018. /*
  1019. * Fill in some stuff that doesn't change.
  1020. */
  1021. ccbp->senselen = sizeof(ccbp->sense);
  1022. p = PADDR(ccbp->sense);
  1023. ccbp->senseptr[0] = p;
  1024. ccbp->senseptr[1] = p>>8;
  1025. ccbp->senseptr[2] = p>>16;
  1026. ccbp->senseptr[3] = p>>24;
  1027. ccbp->ccb = ctlr->ccb;
  1028. ctlr->ccb = (Ccb*)ccbp;
  1029. }
  1030. /*
  1031. * Attempt wide mode setup.
  1032. */
  1033. if(ctlr->wide){
  1034. cmd[0] = Cwide;
  1035. cmd[1] = 1;
  1036. if(!issue(ctlr, cmd, 2, 0, 0))
  1037. ctlr->wide = 0;
  1038. }
  1039. /*
  1040. * Initialise the software controller and
  1041. * set the board scanning the mailboxes.
  1042. */
  1043. ctlr->mbix = NMbox;
  1044. cmd[0] = Ciem;
  1045. cmd[1] = NMbox;
  1046. if(ctlr->pcidev)
  1047. p = K2BPA(ctlr->mb, ctlr->tbdf);
  1048. else
  1049. p = K2BPA(ctlr->mb, BUSUNKNOWN);
  1050. cmd[2] = p;
  1051. cmd[3] = p>>8;
  1052. cmd[4] = p>>16;
  1053. cmd[5] = p>>24;
  1054. return issue(ctlr, cmd, 6, 0, 0);
  1055. }
  1056. static int
  1057. mylexenable(SDev* sdev)
  1058. {
  1059. int tbdf;
  1060. Ctlr *ctlr;
  1061. void (*interrupt)(Ureg*, void*);
  1062. char name[32];
  1063. ctlr = sdev->ctlr;
  1064. if(ctlr->cache == nil){
  1065. if((ctlr->cache = malloc(sdev->nunit*sizeof(Ccb*))) == nil)
  1066. return 0;
  1067. }
  1068. tbdf = BUSUNKNOWN;
  1069. if(ctlr->bus == 32){
  1070. if(ctlr->pcidev){
  1071. tbdf = ctlr->pcidev->tbdf;
  1072. pcisetbme(ctlr->pcidev);
  1073. }
  1074. if(!mylex32enable(ctlr))
  1075. return 0;
  1076. interrupt = mylex32interrupt;
  1077. }
  1078. else if(mylex24enable(ctlr))
  1079. interrupt = mylex24interrupt;
  1080. else
  1081. return 0;
  1082. snprint(name, sizeof(name), "sd%c (%s)", sdev->idno, sdev->ifc->name);
  1083. intrenable(ctlr->irq, interrupt, ctlr, tbdf, name);
  1084. return 1;
  1085. }
  1086. SDifc sdmylexifc = {
  1087. "mylex", /* name */
  1088. mylexpnp, /* pnp */
  1089. nil, /* legacy */
  1090. mylexid, /* id */
  1091. mylexenable, /* enable */
  1092. nil, /* disable */
  1093. scsiverify, /* verify */
  1094. scsionline, /* online */
  1095. mylexrio, /* rio */
  1096. nil, /* rctl */
  1097. nil, /* wctl */
  1098. scsibio, /* bio */
  1099. nil, /* probe */
  1100. nil, /* clear */
  1101. nil, /* stat */
  1102. };