sdmylex.c 28 KB

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