sdmylex.c 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269
  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. if(data == nil)
  322. p = 0;
  323. else
  324. p = PADDR(data);
  325. ccb->dataptr[0] = p>>16;
  326. ccb->dataptr[1] = p>>8;
  327. ccb->dataptr[2] = p;
  328. ccb->linkptr[0] = ccb->linkptr[1] = ccb->linkptr[2] = 0;
  329. ccb->linkid = 0;
  330. ccb->btstat = ccb->sdstat = 0;
  331. ccb->reserved[0] = ccb->reserved[1] = 0;
  332. memmove(ccb->cs, r->cmd, r->clen);
  333. /*
  334. * There's one more mbox than there there is
  335. * ccb so there is always one free.
  336. */
  337. lock(&ctlr->mboxlock);
  338. mb = ctlr->mb;
  339. mb += ctlr->mbox;
  340. p = PADDR(ccb);
  341. mb->ccb[0] = p>>16;
  342. mb->ccb[1] = p>>8;
  343. mb->ccb[2] = p;
  344. mb->code = Mbostart;
  345. ctlr->mbox++;
  346. if(ctlr->mbox >= NMbox)
  347. ctlr->mbox = 0;
  348. /*
  349. * This command does not require Hardy
  350. * and doesn't generate a Cmdc interrupt.
  351. */
  352. ccb->done = 0;
  353. outb(ctlr->port+Rcpr, Cstart);
  354. unlock(&ctlr->mboxlock);
  355. /*
  356. * Wait for the request to complete and return the status.
  357. * Since the buffer is not reference counted cannot return
  358. * until the DMA is done writing into the buffer so the caller
  359. * cannot free the buffer prematurely.
  360. */
  361. while(waserror())
  362. ;
  363. sleep(ccb, done24, ccb);
  364. poperror();
  365. /*
  366. * Save the status and patch up the number of
  367. * bytes actually transferred.
  368. * There's a firmware bug on some 956C controllers
  369. * which causes the return count from a successful
  370. * READ CAPACITY not be updated, so fix it here.
  371. */
  372. sdstat = ccb->sdstat;
  373. btstat = ccb->btstat;
  374. d = ccb->datalen[0]<<16;
  375. d |= ccb->datalen[1]<<8;
  376. d |= ccb->datalen[2];
  377. if(ccb->cs[0] == 0x25 && sdstat == SDok)
  378. d = 0;
  379. n -= d;
  380. r->rlen = n;
  381. /*
  382. * Tidy things up if a staging area was used for the data,
  383. */
  384. if(ccb->data != nil){
  385. if(sdstat == SDok && btstat == 0 && !r->write)
  386. memmove(ccb->data, data, n);
  387. free(data);
  388. ccb->data = nil;
  389. }
  390. /*
  391. * If there was a check-condition, save the
  392. * ccb for a possible request-sense command.
  393. */
  394. if(sdstat == SDcheck){
  395. if(r->flags & SDnosense){
  396. lock(&ctlr->cachelock);
  397. if(ctlr->cache[target])
  398. ccbfree(ctlr, ctlr->cache[target]);
  399. ctlr->cache[target] = (Ccb*)ccb;
  400. unlock(&ctlr->cachelock);
  401. return SDcheck;
  402. }
  403. sense = &ccb->cs[ccb->cdblen];
  404. n = 8+sense[7];
  405. if(n > sizeof(r->sense)-1)
  406. n = sizeof(r->sense)-1;
  407. memmove(r->sense, sense, n);
  408. r->flags |= SDvalidsense;
  409. }
  410. ccbfree(ctlr, (Ccb*)ccb);
  411. if(btstat){
  412. if(btstat == 0x11)
  413. return SDtimeout;
  414. return SDeio;
  415. }
  416. return sdstat;
  417. }
  418. static void
  419. mylex24interrupt(Ureg*, void* arg)
  420. {
  421. ulong pa;
  422. Ctlr *ctlr;
  423. Ccb24 *ccb;
  424. Mbox24 *mb, *mbox;
  425. int port, rinterrupt, rstatus;
  426. ctlr = arg;
  427. port = ctlr->port;
  428. /*
  429. * Save and clear the interrupt(s). The only
  430. * interrupts expected are Cmdc, which is ignored,
  431. * and Imbl which means something completed.
  432. * There's one spurious interrupt left over from
  433. * initialisation, ignore it.
  434. */
  435. rinterrupt = inb(port+Rinterrupt);
  436. rstatus = inb(port+Rstatus);
  437. outb(port+Rcontrol, Rint);
  438. if((rinterrupt & ~(Cmdc|Imbl)) != Intv && ctlr->spurious++)
  439. print("%s: interrupt 0x%2.2ux\n",
  440. ctlr->sdev->name, rinterrupt);
  441. if((rinterrupt & Cmdc) && (rstatus & Cmdinv))
  442. print("%s: command invalid\n", ctlr->sdev->name);
  443. /*
  444. * Look for something in the mail.
  445. * If there is, save the status, free the mailbox
  446. * and wakeup whoever.
  447. */
  448. mb = ctlr->mb;
  449. for(mbox = &mb[ctlr->mbix]; mbox->code; mbox = &mb[ctlr->mbix]){
  450. pa = (mbox->ccb[0]<<16)|(mbox->ccb[1]<<8)|mbox->ccb[2];
  451. ccb = BPA2K(pa, BUSUNKNOWN);
  452. mbox->code = 0;
  453. ccb->done = 1;
  454. wakeup(ccb);
  455. ctlr->mbix++;
  456. if(ctlr->mbix >= NMbox+NMbox)
  457. ctlr->mbix = NMbox;
  458. }
  459. }
  460. static int
  461. done32(void* arg)
  462. {
  463. return ((Ccb32*)arg)->done;
  464. }
  465. static int
  466. mylex32rio(SDreq* r)
  467. {
  468. ulong p;
  469. uchar lun;
  470. Ctlr *ctlr;
  471. Ccb32 *ccb;
  472. Mbox32 *mb;
  473. int d, n, btstat, sdstat, target;
  474. ctlr = r->unit->dev->ctlr;
  475. target = r->unit->subno;
  476. lun = (r->cmd[1]>>5) & 0x07;
  477. /*
  478. * Ctlr->cache holds the last completed Ccb for this target if it
  479. * returned 'check condition'.
  480. * If this command is a request-sense and there is valid sense data
  481. * from the last completed Ccb, return it immediately.
  482. */
  483. lock(&ctlr->cachelock);
  484. if((ccb = ctlr->cache[target]) != nil){
  485. ctlr->cache[target] = nil;
  486. if(r->cmd[0] == 0x03
  487. && ccb->sdstat == SDcheck && lun == (ccb->luntag & 0x07)){
  488. unlock(&ctlr->cachelock);
  489. if(r->dlen){
  490. n = 8+ccb->sense[7];
  491. if(n > r->dlen)
  492. n = r->dlen;
  493. memmove(r->data, ccb->sense, n);
  494. r->rlen = n;
  495. }
  496. ccbfree(ctlr, (Ccb*)ccb);
  497. return SDok;
  498. }
  499. }
  500. unlock(&ctlr->cachelock);
  501. if(ccb == nil)
  502. ccb = ccballoc(ctlr);
  503. /*
  504. * Fill in the ccb.
  505. */
  506. ccb->opcode = Ordl;
  507. n = r->dlen;
  508. if(n == 0)
  509. ccb->datadir = CCBdataout|CCBdatain;
  510. else if(!r->write)
  511. ccb->datadir = CCBdatain;
  512. else
  513. ccb->datadir = CCBdataout;
  514. ccb->cdblen = r->clen;
  515. ccb->datalen[0] = n;
  516. ccb->datalen[1] = n>>8;
  517. ccb->datalen[2] = n>>16;
  518. ccb->datalen[3] = n>>24;
  519. if(r->data == nil)
  520. p = 0;
  521. else
  522. p = PADDR(r->data);
  523. ccb->dataptr[0] = p;
  524. ccb->dataptr[1] = p>>8;
  525. ccb->dataptr[2] = p>>16;
  526. ccb->dataptr[3] = p>>24;
  527. ccb->targetid = target;
  528. ccb->luntag = lun;
  529. if(r->unit->inquiry[7] & 0x02)
  530. if(ctlr->wide)
  531. ccb->datadir |= SQTag|TagEnable;
  532. else
  533. ccb->luntag |= SQTag|TagEnable;
  534. memmove(ccb->cdb, r->cmd, r->clen);
  535. ccb->btstat = ccb->sdstat = 0;
  536. ccb->ccbctl = 0;
  537. /*
  538. * There's one more mbox than there there is
  539. * ccb so there is always one free.
  540. */
  541. lock(&ctlr->mboxlock);
  542. mb = ctlr->mb;
  543. mb += ctlr->mbox;
  544. p = PADDR(ccb);
  545. mb->ccb[0] = p;
  546. mb->ccb[1] = p>>8;
  547. mb->ccb[2] = p>>16;
  548. mb->ccb[3] = p>>24;
  549. mb->code = Mbostart;
  550. ctlr->mbox++;
  551. if(ctlr->mbox >= NMbox)
  552. ctlr->mbox = 0;
  553. /*
  554. * This command does not require Hardy
  555. * and doesn't generate a Cmdc interrupt.
  556. */
  557. ccb->done = 0;
  558. outb(ctlr->port+Rcpr, Cstart);
  559. unlock(&ctlr->mboxlock);
  560. /*
  561. * Wait for the request to complete and return the status.
  562. * Since the buffer is not reference counted cannot return
  563. * until the DMA is done writing into the buffer so the caller
  564. * cannot free the buffer prematurely.
  565. */
  566. while(waserror())
  567. ;
  568. sleep(ccb, done32, ccb);
  569. poperror();
  570. /*
  571. * Save the status and patch up the number of
  572. * bytes actually transferred.
  573. * There's a firmware bug on some 956C controllers
  574. * which causes the return count from a successful
  575. * READ CAPACITY not to be updated, so fix it here.
  576. */
  577. sdstat = ccb->sdstat;
  578. btstat = ccb->btstat;
  579. d = ccb->datalen[0];
  580. d |= (ccb->datalen[1]<<8);
  581. d |= (ccb->datalen[2]<<16);
  582. d |= (ccb->datalen[3]<<24);
  583. if(ccb->cdb[0] == 0x25 && sdstat == SDok)
  584. d = 0;
  585. n -= d;
  586. r->rlen = n;
  587. /*
  588. * If there was a check-condition, save the
  589. * ccb for a possible request-sense command.
  590. */
  591. if(sdstat == SDcheck){
  592. if(r->flags & SDnosense){
  593. lock(&ctlr->cachelock);
  594. if(ctlr->cache[target])
  595. ccbfree(ctlr, ctlr->cache[target]);
  596. ctlr->cache[target] = (Ccb*)ccb;
  597. unlock(&ctlr->cachelock);
  598. return SDcheck;
  599. }
  600. n = 8+ccb->sense[7];
  601. if(n > sizeof(r->sense)-1)
  602. n = sizeof(r->sense)-1;
  603. memmove(r->sense, ccb->sense, n);
  604. r->flags |= SDvalidsense;
  605. }
  606. ccbfree(ctlr, (Ccb*)ccb);
  607. if(btstat){
  608. if(btstat == 0x11)
  609. return SDtimeout;
  610. return SDeio;
  611. }
  612. return sdstat;
  613. }
  614. static void
  615. mylex32interrupt(Ureg*, void* arg)
  616. {
  617. ulong pa;
  618. Ctlr *ctlr;
  619. Ccb32 *ccb;
  620. Mbox32 *mb, *mbox;
  621. int port, rinterrupt, rstatus;
  622. ctlr = arg;
  623. port = ctlr->port;
  624. /*
  625. * Save and clear the interrupt(s). The only
  626. * interrupts expected are Cmdc, which is ignored,
  627. * and Imbl which means something completed.
  628. * There's one spurious interrupt left over from
  629. * initialisation, ignore it.
  630. * In order to share PCI IRQs, just ignore spurious interrupts.
  631. */
  632. rinterrupt = inb(port+Rinterrupt);
  633. rstatus = inb(port+Rstatus);
  634. outb(port+Rcontrol, Rint);
  635. if(0 && (rinterrupt & ~(Cmdc|Imbl)) != Intv && ctlr->spurious++)
  636. print("%s: interrupt 0x%2.2ux\n",
  637. ctlr->sdev->name, rinterrupt);
  638. if((rinterrupt & Cmdc) && (rstatus & Cmdinv))
  639. print("%s: command invalid\n", ctlr->sdev->name);
  640. /*
  641. * Look for something in the mail.
  642. * If there is, free the mailbox and wakeup whoever.
  643. */
  644. mb = ctlr->mb;
  645. for(mbox = &mb[ctlr->mbix]; mbox->code; mbox = &mb[ctlr->mbix]){
  646. pa = (mbox->ccb[3]<<24)
  647. |(mbox->ccb[2]<<16)
  648. |(mbox->ccb[1]<<8)
  649. |mbox->ccb[0];
  650. if(ctlr->pcidev)
  651. ccb = BPA2K(pa, ctlr->pcidev->tbdf);
  652. else
  653. ccb = BPA2K(pa, BUSUNKNOWN);
  654. mbox->code = 0;
  655. ccb->done = 1;
  656. wakeup(ccb);
  657. ctlr->mbix++;
  658. if(ctlr->mbix >= NMbox+NMbox)
  659. ctlr->mbix = NMbox;
  660. }
  661. }
  662. static int
  663. mylexrio(SDreq* r)
  664. {
  665. int subno;
  666. Ctlr *ctlr;
  667. subno = r->unit->subno;
  668. ctlr = r->unit->dev->ctlr;
  669. if(subno == ctlr->id || (!ctlr->wide && subno >= 8))
  670. r->status = SDtimeout;
  671. else if(ctlr->bus == 24)
  672. r->status = mylex24rio(r);
  673. else
  674. r->status = mylex32rio(r);
  675. return r->status;
  676. }
  677. /*
  678. * Issue a command to a controller. The command and its length is
  679. * contained in cmd and cmdlen. If any data is to be
  680. * returned, datalen should be non-zero, and the returned data
  681. * will be placed in data.
  682. * If Cmdc is set, bail out, the invalid command will be handled
  683. * when the interrupt is processed.
  684. */
  685. static void
  686. issueio(int port, uchar* cmd, int cmdlen, uchar* data, int datalen)
  687. {
  688. int len;
  689. if(cmd[0] != Cstart && cmd[0] != Ceombri){
  690. while(!(inb(port+Rstatus) & Hardy))
  691. ;
  692. }
  693. outb(port+Rcpr, cmd[0]);
  694. len = 1;
  695. while(len < cmdlen){
  696. if(!(inb(port+Rstatus) & Cprbsy)){
  697. outb(port+Rcpr, cmd[len]);
  698. len++;
  699. }
  700. if(inb(port+Rinterrupt) & Cmdc)
  701. return;
  702. }
  703. if(datalen){
  704. len = 0;
  705. while(len < datalen){
  706. if(inb(port+Rstatus) & Dirrdy){
  707. data[len] = inb(port+Rdatain);
  708. len++;
  709. }
  710. if(inb(port+Rinterrupt) & Cmdc)
  711. return;
  712. }
  713. }
  714. }
  715. /*
  716. * Issue a command to a controller, wait for it to complete then
  717. * try to reset the interrupt. Should only be called at initialisation.
  718. */
  719. static int
  720. issue(Ctlr* ctlr, uchar* cmd, int cmdlen, uchar* data, int datalen)
  721. {
  722. int port;
  723. uchar rinterrupt, rstatus;
  724. static Lock mylexissuelock;
  725. port = ctlr->port;
  726. ilock(&ctlr->issuelock);
  727. issueio(port, cmd, cmdlen, data, datalen);
  728. while(!((rinterrupt = inb(port+Rinterrupt)) & Cmdc))
  729. ;
  730. rstatus = inb(port+Rstatus);
  731. outb(port+Rcontrol, Rint);
  732. iunlock(&ctlr->issuelock);
  733. if((rinterrupt & Cmdc) && (rstatus & Cmdinv))
  734. return 0;
  735. return 1;
  736. }
  737. static SDev*
  738. mylexprobe(int port, int irq)
  739. {
  740. SDev *sdev;
  741. Ctlr *ctlr;
  742. uchar cmd[6], data[256];
  743. int clen, dlen, timeo;
  744. static int count;
  745. if(ioalloc(port, 0x3, 0, "mylex") < 0)
  746. return nil;
  747. ctlr = nil;
  748. sdev = nil;
  749. /*
  750. * Attempt to hard-reset the board and reset
  751. * the SCSI bus. If the board state doesn't settle to
  752. * idle with mailbox initialisation required, either
  753. * it isn't a compatible board or it's broken.
  754. * If the controller has SCAM set this can take a while.
  755. */
  756. if(getconf("*noscsireset") != nil)
  757. outb(port+Rcontrol, Rhard);
  758. else
  759. outb(port+Rcontrol, Rhard|Rsbus);
  760. for(timeo = 0; timeo < 100; timeo++){
  761. if(inb(port+Rstatus) == (Inreq|Hardy))
  762. break;
  763. delay(100);
  764. }
  765. if(inb(port+Rstatus) != (Inreq|Hardy)){
  766. buggery:
  767. if(ctlr != nil)
  768. free(ctlr);
  769. if (sdev != nil)
  770. free(sdev);
  771. iofree(port);
  772. return nil;
  773. }
  774. if((ctlr = malloc(sizeof(Ctlr))) == nil)
  775. goto buggery;
  776. ctlr->port = port;
  777. ctlr->irq = irq;
  778. ctlr->bus = 24;
  779. ctlr->wide = 0;
  780. /*
  781. * Try to determine if this is a 32-bit MultiMaster controller
  782. * by attempting to obtain the extended inquiry information;
  783. * this command is not implemented on Adaptec 154xx
  784. * controllers. If successful, the first byte of the returned
  785. * data is the host adapter bus type, 'E' for 32-bit EISA,
  786. * PCI and VLB buses.
  787. */
  788. cmd[0] = Ciesi;
  789. cmd[1] = 14;
  790. clen = 2;
  791. dlen = 256;
  792. if(issue(ctlr, cmd, clen, data, dlen)){
  793. if(data[0] == 'E')
  794. ctlr->bus = 32;
  795. ctlr->wide = data[0x0D] & 0x01;
  796. /*
  797. * devsd doesn't pass us the `spec' argument, so
  798. * we'll assume that sd0 goes to the first scsi host
  799. * adapter found, etc.
  800. */
  801. print("#S/sd%d: mylex SCSI: port 0x%ux: %d-bit, ",
  802. count++, ctlr->port, ctlr->bus);
  803. if (ctlr->wide)
  804. print("wide\n");
  805. else
  806. print("narrow\n");
  807. }
  808. else{
  809. /*
  810. * Inconceivable though it may seem, a hard controller reset
  811. * is necessary here to clear out the command queue. Every
  812. * board seems to lock-up in a different way if you give an
  813. * invalid command and then try to clear out the
  814. * command/parameter and/or data-in register.
  815. * Soft reset doesn't do the job either. Fortunately no
  816. * serious initialisation has been done yet so there's nothing
  817. * to tidy up.
  818. */
  819. outb(port+Rcontrol, Rhard);
  820. for(timeo = 0; timeo < 100; timeo++){
  821. if(inb(port+Rstatus) == (Inreq|Hardy))
  822. break;
  823. delay(100);
  824. }
  825. if(inb(port+Rstatus) != (Inreq|Hardy))
  826. goto buggery;
  827. }
  828. /*
  829. * If the BIOS is enabled on the AHA-1542C/CF and BIOS options for
  830. * support of drives > 1Gb, dynamic scanning of the SCSI bus or more
  831. * than 2 drives under DOS 5.0 are enabled, the BIOS disables
  832. * accepting Cmbinit to protect against running with drivers which
  833. * don't support those options. In order to unlock the interface it
  834. * is necessary to read a lock-code using Cextbios and write it back
  835. * using Cmbienable; the lock-code is non-zero.
  836. */
  837. cmd[0] = Cinquiry;
  838. clen = 1;
  839. dlen = 4;
  840. if(issue(ctlr, cmd, clen, data, dlen) == 0)
  841. goto buggery;
  842. if(data[0] >= 0x43){
  843. cmd[0] = Cextbios;
  844. clen = 1;
  845. dlen = 2;
  846. if(issue(ctlr, cmd, clen, data, dlen) == 0)
  847. goto buggery;
  848. /*
  849. * Lock-code returned in data[1]. If it's non-zero write
  850. * it back along with bit 0 of byte 0 cleared to enable
  851. * mailbox initialisation.
  852. */
  853. if(data[1]){
  854. cmd[0] = Cmbienable;
  855. cmd[1] = 0;
  856. cmd[2] = data[1];
  857. clen = 3;
  858. if(issue(ctlr, cmd, clen, 0, 0) == 0)
  859. goto buggery;
  860. }
  861. }
  862. /*
  863. * Get the id, DMA and IRQ info from the board. This will
  864. * cause an interrupt which will hopefully not cause any
  865. * trouble because the interrupt number isn't known yet.
  866. * This is necessary as the DMA won't be set up if the
  867. * board has the BIOS disabled.
  868. *
  869. * If the IRQ is already known, this must be a 32-bit PCI
  870. * or EISA card, in which case the returned DMA and IRQ can
  871. * be ignored.
  872. */
  873. cmd[0] = Cinquire;
  874. clen = 1;
  875. dlen = 3;
  876. if(issue(ctlr, cmd, clen, data, dlen) == 0)
  877. goto buggery;
  878. ctlr->id = data[2] & 0x07;
  879. if(ctlr->irq < 0){
  880. switch(data[0]){ /* DMA Arbitration Priority */
  881. case 0x80: /* Channel 7 */
  882. outb(0xD6, 0xC3);
  883. outb(0xD4, 0x03);
  884. break;
  885. case 0x40: /* Channel 6 */
  886. outb(0xD6, 0xC2);
  887. outb(0xD4, 0x02);
  888. break;
  889. case 0x20: /* Channel 5 */
  890. outb(0xD6, 0xC1);
  891. outb(0xD4, 0x01);
  892. break;
  893. case 0x01: /* Channel 0 */
  894. outb(0x0B, 0xC0);
  895. outb(0x0A, 0x00);
  896. break;
  897. default:
  898. if(ctlr->bus == 24)
  899. goto buggery;
  900. break;
  901. }
  902. switch(data[1]){ /* Interrupt Channel */
  903. case 0x40:
  904. ctlr->irq = 15;
  905. break;
  906. case 0x20:
  907. ctlr->irq = 14;
  908. break;
  909. case 0x08:
  910. ctlr->irq = 12;
  911. break;
  912. case 0x04:
  913. ctlr->irq = 11;
  914. break;
  915. case 0x02:
  916. ctlr->irq = 10;
  917. break;
  918. case 0x01:
  919. ctlr->irq = 9;
  920. break;
  921. default:
  922. goto buggery;
  923. }
  924. }
  925. if((sdev = malloc(sizeof(SDev))) == nil)
  926. goto buggery;
  927. sdev->ifc = &sdmylexifc;
  928. sdev->ctlr = ctlr;
  929. sdev->idno = '0';
  930. ctlr->sdev = sdev;
  931. if(!ctlr->wide)
  932. sdev->nunit = 8;
  933. else
  934. sdev->nunit = 16;
  935. return sdev;
  936. }
  937. static int mylexport[8] = {
  938. 0x330, 0x334, 0x230, 0x234, 0x130, 0x134, 0x000, 0x000,
  939. };
  940. static SDev*
  941. mylexpnp(void)
  942. {
  943. Pcidev *p;
  944. Ctlr *ctlr;
  945. ISAConf isa;
  946. int cfg, ctlrno, i, x;
  947. SDev *sdev, *head, *tail;
  948. p = nil;
  949. head = tail = nil;
  950. while(p = pcimatch(p, 0x104B, 0)){
  951. if((sdev = mylexprobe(p->mem[0].bar & ~0x01, p->intl)) == nil)
  952. continue;
  953. ctlr = sdev->ctlr;
  954. ctlr->pcidev = p;
  955. if(head != nil)
  956. tail->next = sdev;
  957. else
  958. head = sdev;
  959. tail = sdev;
  960. }
  961. if(strncmp(KADDR(0xFFFD9), "EISA", 4) == 0){
  962. for(cfg = 0x1000; cfg < MaxEISA*0x1000; cfg += 0x1000){
  963. x = 0;
  964. for(i = 0; i < 4; i++)
  965. x |= inb(cfg+CfgEISA+i)<<(i*8);
  966. if(x != 0x0142B30A && x != 0x0242B30A)
  967. continue;
  968. x = inb(cfg+0xC8C);
  969. if((sdev = mylexprobe(mylexport[x & 0x07], -1)) == nil)
  970. continue;
  971. if(head != nil)
  972. tail->next = sdev;
  973. else
  974. head = sdev;
  975. tail = sdev;
  976. }
  977. }
  978. for(ctlrno = 0; ctlrno < 4; ctlrno++){
  979. memset(&isa, 0, sizeof(isa));
  980. if(!isaconfig("scsi", ctlrno, &isa))
  981. continue;
  982. if(strcmp(isa.type, "aha1542"))
  983. continue;
  984. if((sdev = mylexprobe(isa.port, -1)) == nil)
  985. continue;
  986. if(head != nil)
  987. tail->next = sdev;
  988. else
  989. head = sdev;
  990. tail = sdev;
  991. }
  992. return head;
  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. print("mylex32enable: port 0x%ux: scsi wide-mode setup "
  1057. "failed on wide host adapter", ctlr->port);
  1058. }
  1059. }
  1060. /*
  1061. * Initialise the software controller and
  1062. * set the board scanning the mailboxes.
  1063. */
  1064. ctlr->mbix = NMbox;
  1065. cmd[0] = Ciem;
  1066. cmd[1] = NMbox;
  1067. if(ctlr->pcidev)
  1068. p = K2BPA(ctlr->mb, ctlr->tbdf);
  1069. else
  1070. p = K2BPA(ctlr->mb, BUSUNKNOWN);
  1071. cmd[2] = p;
  1072. cmd[3] = p>>8;
  1073. cmd[4] = p>>16;
  1074. cmd[5] = p>>24;
  1075. return issue(ctlr, cmd, 6, 0, 0);
  1076. }
  1077. static int
  1078. mylexenable(SDev* sdev)
  1079. {
  1080. int tbdf;
  1081. Ctlr *ctlr;
  1082. void (*interrupt)(Ureg*, void*);
  1083. char name[32];
  1084. ctlr = sdev->ctlr;
  1085. if(ctlr->cache == nil){
  1086. if((ctlr->cache = malloc(sdev->nunit*sizeof(Ccb*))) == nil)
  1087. return 0;
  1088. }
  1089. tbdf = BUSUNKNOWN;
  1090. if(ctlr->bus == 32){
  1091. if(ctlr->pcidev){
  1092. tbdf = ctlr->pcidev->tbdf;
  1093. pcisetbme(ctlr->pcidev);
  1094. }
  1095. if(!mylex32enable(ctlr))
  1096. return 0;
  1097. interrupt = mylex32interrupt;
  1098. }
  1099. else if(mylex24enable(ctlr))
  1100. interrupt = mylex24interrupt;
  1101. else
  1102. return 0;
  1103. snprint(name, sizeof(name), "sd%c (%s)", sdev->idno, sdev->ifc->name);
  1104. intrenable(ctlr->irq, interrupt, ctlr, tbdf, name);
  1105. return 1;
  1106. }
  1107. SDifc sdmylexifc = {
  1108. "mylex", /* name */
  1109. mylexpnp, /* pnp */
  1110. nil, /* legacy */
  1111. mylexenable, /* enable */
  1112. nil, /* disable */
  1113. scsiverify, /* verify */
  1114. scsionline, /* online */
  1115. mylexrio, /* rio */
  1116. nil, /* rctl */
  1117. nil, /* wctl */
  1118. scsibio, /* bio */
  1119. nil, /* probe */
  1120. nil, /* clear */
  1121. nil, /* rtopctl */
  1122. nil, /* wtopctl */
  1123. };