sdmylex.c 28 KB

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