sdmv50xx.c 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941
  1. /*
  2. * Marvell 88SX[56]0[48][01] Serial ATA (SATA) driver
  3. *
  4. * See MV-S101357-00 Rev B Marvell PCI/PCI-X to 8-Port/4-Port
  5. * SATA Host Controller, ATA-5 ANSI NCITS 340-2000.
  6. *
  7. * This is a heavily-modified version of a driver written by Coraid, Inc.
  8. * The original copyright notice appears at the end of this file.
  9. */
  10. #ifdef FS
  11. #include "all.h"
  12. #include "io.h"
  13. #include "mem.h"
  14. #include "sd.h"
  15. #include "compat.h"
  16. #else
  17. #include "u.h"
  18. #include "../port/lib.h"
  19. #include "mem.h"
  20. #include "dat.h"
  21. #include "fns.h"
  22. #include "io.h"
  23. #include "../port/error.h"
  24. #include "../port/sd.h"
  25. #endif
  26. enum {
  27. DEBUGPR = 0,
  28. IDEBUG = 0,
  29. /* old stuff carried forward */
  30. NCtlr= 8,
  31. NCtlrdrv= 8,
  32. NDrive= NCtlr*NCtlrdrv,
  33. Maxxfer= 16*1024, /* maximum transfer size/cmd */
  34. Read = 0,
  35. Write,
  36. Drvmagic = 0xcafebabeUL,
  37. Ctlrmagic = 0xfeedfaceUL,
  38. };
  39. #define DPRINT if(DEBUGPR)print
  40. #define IDPRINT if(IDEBUG)print
  41. enum {
  42. SrbRing = 32,
  43. /* Addresses of ATA register */
  44. ARcmd = 027,
  45. ARdev = 026,
  46. ARerr = 021,
  47. ARfea = 021,
  48. ARlba2 = 025,
  49. ARlba1 = 024,
  50. ARlba0 = 023,
  51. ARseccnt = 022,
  52. ARstat = 027,
  53. ATAerr = (1<<0),
  54. ATAdrq = (1<<3),
  55. ATAdf = (1<<5),
  56. ATAdrdy = (1<<6),
  57. ATAbusy = (1<<7),
  58. ATAabort = (1<<2),
  59. ATAeIEN = (1<<1),
  60. ATAsrst = (1<<2),
  61. ATAhob = (1<<7),
  62. SFdone = (1<<0),
  63. SFerror = (1<<1),
  64. SRBident = 0,
  65. SRBread,
  66. SRBwrite,
  67. SRBsmart,
  68. SRBnodata = 0,
  69. SRBdatain,
  70. SRBdataout,
  71. RQread = 1, /* data coming IN from device */
  72. PRDeot = (1<<15),
  73. /* EDMA interrupt error cause register */
  74. ePrtDataErr = (1<<0),
  75. ePrtPRDErr = (1<<1),
  76. eDevErr = (1<<2),
  77. eDevDis = (1<<3),
  78. eDevCon = (1<<4),
  79. eOverrun = (1<<5),
  80. eUnderrun = (1<<6),
  81. eSelfDis = (1<<8),
  82. ePrtCRQBErr = (1<<9),
  83. ePrtCRPBErr = (1<<10),
  84. ePrtIntErr = (1<<11),
  85. eIORdyErr = (1<<12),
  86. /* EDMA Command Register */
  87. eEnEDMA = (1<<0),
  88. eDsEDMA = (1<<1),
  89. eAtaRst = (1<<2),
  90. /* Interrupt mask for errors we care about */
  91. IEM = (eDevDis | eDevCon | eSelfDis),
  92. /* drive states */
  93. Dnull = 0,
  94. Dnew,
  95. Dident,
  96. Dready,
  97. Derror,
  98. Dmissing,
  99. Dunconfig,
  100. /* drive flags */
  101. Dext = (1<<0), /* use ext commands */
  102. Dpio = (1<<1), /* doing pio */
  103. Dwanted = (1<<2), /* someone wants an srb entry */
  104. Dedma = (1<<3), /* device in edma mode */
  105. Dpiowant = (1<<4), /* some wants to use the pio mode */
  106. };
  107. static char* diskstates[] =
  108. {
  109. "null",
  110. "new",
  111. "ident",
  112. "ready",
  113. "error",
  114. "missing",
  115. "unconfigured",
  116. };
  117. extern SDifc sdmv50xxifc;
  118. typedef struct Arb Arb;
  119. typedef struct Bridge Bridge;
  120. typedef struct Chip Chip;
  121. typedef struct Ctlr Ctlr;
  122. typedef struct Drive Drive;
  123. typedef struct Edma Edma;
  124. typedef struct Prd Prd;
  125. typedef struct Rx Rx;
  126. typedef struct Srb Srb;
  127. typedef struct Tx Tx;
  128. struct Chip /* pointers to per-Chip mmio */
  129. {
  130. Arb *arb;
  131. Edma *edma; /* array of 4 */
  132. };
  133. struct Drive /* a single disk */
  134. {
  135. Lock;
  136. Ctlr *ctlr;
  137. SDunit *unit;
  138. // int subno;
  139. char name[10];
  140. ulong magic;
  141. Bridge *bridge;
  142. Edma *edma;
  143. Chip *chip;
  144. int chipx;
  145. int state;
  146. int flag;
  147. uvlong sectors;
  148. char serial[20+1];
  149. char firmware[8+1];
  150. char model[40+1];
  151. ushort info[256];
  152. Srb *srb[SrbRing-1];
  153. int nsrb;
  154. Prd *prd;
  155. Tx *tx;
  156. Rx *rx;
  157. Srb *srbhead;
  158. Srb *srbtail;
  159. /* added for file server */
  160. /* for ata* routines */
  161. int online;
  162. Devsize offset;
  163. int driveno; /* ctlr*NCtlrdrv + unit */
  164. /*
  165. * old stuff carried forward. it's in Drive not Ctlr to maximise
  166. * possible concurrency.
  167. */
  168. uchar buf[RBUFSIZE];
  169. };
  170. struct Ctlr /* a single PCI card */
  171. {
  172. Lock;
  173. int irq;
  174. int tbdf;
  175. ulong magic;
  176. int enabled;
  177. SDev *sdev;
  178. Pcidev *pcidev;
  179. uchar *mmio;
  180. Chip chip[2];
  181. int nchip;
  182. Drive drive[NCtlrdrv];
  183. int ndrive;
  184. Target target[NTarget]; /* contains filters for stats */
  185. /* old stuff carried forward */
  186. QLock idelock; /* make seek & i/o atomic in ide* routines */
  187. };
  188. struct Srb /* request buffer */
  189. {
  190. Lock;
  191. Rendez;
  192. Srb *next;
  193. Drive *drive;
  194. uvlong blockno;
  195. int count;
  196. int req;
  197. int flag;
  198. uchar *data;
  199. uchar cmd;
  200. uchar lba[6];
  201. uchar sectors;
  202. int sta;
  203. int err;
  204. };
  205. /*
  206. * Memory-mapped I/O registers in many forms.
  207. */
  208. struct Bridge /* memory-mapped per-Drive registers */
  209. {
  210. ulong status;
  211. ulong serror;
  212. ulong sctrl;
  213. ulong phyctrl;
  214. char fill1[0x2c];
  215. ulong ctrl;
  216. char fill2[0x34];
  217. ulong phymode;
  218. char fill3[0x88]; /* pad to 0x100 in length */
  219. };
  220. struct Arb /* memory-mapped per-Chip registers */
  221. {
  222. ulong fill0;
  223. ulong rqop; /* request queue out-pointer */
  224. ulong rqip; /* response queue in pointer */
  225. ulong ict; /* inerrupt caolescing threshold */
  226. ulong itt; /* interrupt timer threshold */
  227. ulong ic; /* interrupt cause */
  228. ulong btc; /* bridges test control */
  229. ulong bts; /* bridges test status */
  230. ulong bpc; /* bridges pin configuration */
  231. char fill1[0xdc];
  232. Bridge bridge[4];
  233. };
  234. struct Edma /* memory-mapped per-Drive DMA-related registers */
  235. {
  236. ulong config; /* configuration register */
  237. ulong timer;
  238. ulong iec; /* interrupt error cause */
  239. ulong iem; /* interrupt error mask */
  240. ulong txbasehi; /* request queue base address high */
  241. ulong txi; /* request queue in pointer */
  242. ulong txo; /* request queue out pointer */
  243. ulong rxbasehi; /* response queue base address high */
  244. ulong rxi; /* response queue in pointer */
  245. ulong rxo; /* response queue out pointer */
  246. ulong ctl; /* command register */
  247. ulong testctl; /* test control */
  248. ulong status;
  249. ulong iordyto; /* IORDY timeout */
  250. char fill[0xc8];
  251. ushort pio; /* data register */
  252. char pad0[2];
  253. uchar err; /* features and error */
  254. char pad1[3];
  255. uchar seccnt; /* sector count */
  256. char pad2[3];
  257. uchar lba0;
  258. char pad3[3];
  259. uchar lba1;
  260. char pad4[3];
  261. uchar lba2;
  262. char pad5[3];
  263. uchar lba3;
  264. char pad6[3];
  265. uchar cmdstat; /* cmd/status */
  266. char pad7[3];
  267. uchar altstat; /* alternate status */
  268. char fill2[0x1edc]; /* pad to 0x2000 bytes */
  269. };
  270. /*
  271. * Memory structures shared with card.
  272. */
  273. struct Prd /* physical region descriptor */
  274. {
  275. ulong pa; /* byte address of physical memory */
  276. ushort count; /* byte count (bit0 must be 0) */
  277. ushort flag;
  278. ulong zero; /* high long of 64 bit address */
  279. ulong reserved;
  280. };
  281. struct Tx /* command request block */
  282. {
  283. ulong prdpa; /* physical region descriptor table structures */
  284. ulong zero; /* must be zero (high long of prd address) */
  285. ushort flag; /* control flags */
  286. ushort regs[11];
  287. };
  288. struct Rx /* command response block */
  289. {
  290. ushort cid; /* cID of response */
  291. uchar cEdmaSts; /* EDMA status */
  292. uchar cDevSts; /* status from disk */
  293. ulong ts; /* time stamp */
  294. };
  295. /* file-server-specific data */
  296. static Ctlr *mvsatactlr[NCtlr];
  297. static SDev *sdevs[NCtlr];
  298. static Drive *mvsatadrive[NDrive];
  299. static SDunit *sdunits[NDrive];
  300. static Drive *mvsatadriveprobe(int driveno);
  301. static void statsinit(void);
  302. /*
  303. * Little-endian parsing for drive data.
  304. */
  305. static ushort
  306. lhgets(void *p)
  307. {
  308. uchar *a = p;
  309. return ((ushort) a[1] << 8) | a[0];
  310. }
  311. static ulong
  312. lhgetl(void *p)
  313. {
  314. uchar *a = p;
  315. return ((ulong) lhgets(a+2) << 16) | lhgets(a);
  316. }
  317. static uvlong
  318. lhgetv(void *p)
  319. {
  320. uchar *a = p;
  321. return ((uvlong) lhgetl(a+4) << 32) | lhgetl(a);
  322. }
  323. static void
  324. idmove(char *p, ushort *a, int n)
  325. {
  326. char *op;
  327. int i;
  328. op = p;
  329. for(i=0; i<n/2; i++){
  330. *p++ = a[i]>>8;
  331. *p++ = a[i];
  332. }
  333. while(p>op && *--p == ' ')
  334. *p = 0;
  335. }
  336. /*
  337. * Request buffers.
  338. */
  339. static struct
  340. {
  341. Lock;
  342. Srb *freechain;
  343. int nalloc;
  344. } srblist;
  345. static Srb*
  346. allocsrb(void)
  347. {
  348. Srb *p;
  349. ilock(&srblist);
  350. if((p = srblist.freechain) == nil){
  351. srblist.nalloc++;
  352. iunlock(&srblist);
  353. p = smalloc(sizeof *p);
  354. }else{
  355. srblist.freechain = p->next;
  356. iunlock(&srblist);
  357. }
  358. return p;
  359. }
  360. static void
  361. freesrb(Srb *p)
  362. {
  363. ilock(&srblist);
  364. p->next = srblist.freechain;
  365. srblist.freechain = p;
  366. iunlock(&srblist);
  367. }
  368. /*
  369. * Wait for a byte to be a particular value.
  370. */
  371. static int
  372. satawait(uchar *p, uchar mask, uchar v, int ms)
  373. {
  374. int i;
  375. // DPRINT("satawait %p %#x %#x %d...", p, mask, v, ms);
  376. // DPRINT("!%#x...", *p);
  377. for(i=0; i<ms && (*p & mask) != v; i++){
  378. if(i%1000 == 0)
  379. DPRINT("!%#x", *p);
  380. microdelay(1000);
  381. }
  382. return (*p & mask) == v;
  383. }
  384. /*
  385. * Drive initialization
  386. */
  387. static int
  388. configdrive(Ctlr *ctlr, Drive *d, SDunit *unit)
  389. {
  390. int i;
  391. ulong *r;
  392. DPRINT("%s: configdrive\n", unit->name);
  393. d->unit = unit;
  394. d->ctlr = ctlr;
  395. d->chipx = unit->subno%4;
  396. d->chip = &ctlr->chip[unit->subno/4];
  397. d->bridge = &d->chip->arb->bridge[d->chipx];
  398. d->edma = &d->chip->edma[d->chipx];
  399. if (d->driveno < 0)
  400. panic("mv50xx: configdrive: unset driveno\n");
  401. sdunits[d->driveno] = unit;
  402. if(d->tx == nil){
  403. d->tx = mallocalign(32*sizeof(Tx), 1024, 0, 0);
  404. d->rx = mallocalign(32*sizeof(Rx), 256, 0, 0);
  405. d->prd = mallocalign(32*sizeof(Prd), 32, 0, 0);
  406. if(d->tx == nil || d->rx == nil || d->prd == nil){
  407. iprint("%s: out of memory allocating ring buffers\n",
  408. unit->name);
  409. free(d->tx);
  410. d->tx = nil;
  411. free(d->rx);
  412. d->rx = nil;
  413. free(d->prd);
  414. d->prd = nil;
  415. d->state = Dunconfig;
  416. return 0;
  417. }
  418. for(i=0; i<32; i++)
  419. d->tx[i].prdpa = PADDR(&d->prd[i]);
  420. coherence();
  421. }
  422. /* leave disk interrupts turned off until we use it ... */
  423. d->edma->iem = 0;
  424. /* ... but enable them on the controller */
  425. r = (ulong*)(d->ctlr->mmio + 0x1D64);
  426. if(d->unit->subno < 4)
  427. *r |= 3 << (d->chipx*2);
  428. else
  429. *r |= 3 << (d->chipx*2+9);
  430. return 1;
  431. }
  432. static int
  433. enabledrive(Drive *d)
  434. {
  435. Edma *edma;
  436. DPRINT("%s: enabledrive\n", d->unit->name);
  437. if((d->bridge->status & 0xF) != 0x3){ /* Det */
  438. DPRINT("%s: not present\n", d->unit->name);
  439. d->state = Dmissing;
  440. return 0;
  441. }
  442. edma = d->edma;
  443. if(satawait(&edma->cmdstat, ATAbusy, 0, 10*1000) == 0){
  444. print("%s: busy timeout\n", d->unit->name);
  445. d->state = Dmissing;
  446. return 0;
  447. }
  448. edma->iec = 0;
  449. d->chip->arb->ic &= ~(0x101 << d->chipx);
  450. edma->config = 0x11F;
  451. edma->txi = PADDR(d->tx);
  452. edma->txo = (ulong)d->tx & 0x3E0;
  453. edma->rxi = (ulong)d->rx & 0xF8;
  454. edma->rxo = PADDR(d->rx);
  455. edma->ctl |= 1; /* enable dma */
  456. DPRINT("%s: enable interrupts\n", d->unit->name);
  457. if(d->bridge->status = 0x113)
  458. d->state = Dnew;
  459. d->edma->iem = IEM;
  460. return 1;
  461. }
  462. static void
  463. disabledrive(Drive *d)
  464. {
  465. int i;
  466. ulong *r;
  467. DPRINT("%s: disabledrive\n", d->unit->name);
  468. if(d->tx == nil) /* never enabled */
  469. return;
  470. d->edma->ctl = 0;
  471. d->edma->iem = 0;
  472. r = (ulong*)(d->ctlr->mmio + 0x1D64);
  473. i = d->chipx;
  474. if(d->chipx < 4)
  475. *r &= ~(3 << (i*2));
  476. else
  477. *r |= ~(3 << (i*2+9));
  478. }
  479. static int
  480. setudmamode(Drive *d, uchar mode)
  481. {
  482. Edma *edma;
  483. DPRINT("%s: setudmamode %d\n", d->unit->name, mode);
  484. edma = d->edma;
  485. if (edma == nil) {
  486. print("setudamode(m%d): zero d->edma\m", d->driveno);
  487. return 0;
  488. }
  489. if(satawait(&edma->cmdstat, ATAerr|ATAdrq|ATAdf|ATAdrdy|ATAbusy, ATAdrdy, 15*1000) == 0){
  490. iprint("%s: cmdstat 0x%.2ux ready timeout\n",
  491. d->unit->name, edma->cmdstat);
  492. return 0;
  493. }
  494. edma->altstat = ATAeIEN;
  495. edma->err = 3;
  496. edma->seccnt = 0x40 | mode;
  497. edma->cmdstat = 0xEF;
  498. microdelay(1);
  499. if(satawait(&edma->cmdstat, ATAbusy, 0, 15*1000) == 0){
  500. iprint("%s: cmdstat 0x%.2ux busy timeout\n",
  501. d->unit->name, edma->cmdstat);
  502. return 0;
  503. }
  504. return 1;
  505. }
  506. static void
  507. identifydrive(Drive *d)
  508. {
  509. int i;
  510. ushort *id;
  511. Edma *edma;
  512. SDunit *unit;
  513. DPRINT("%s: identifydrive\n", d->unit->name);
  514. if(setudmamode(d, 5) == 0) /* do all SATA support 5? */
  515. goto Error;
  516. id = d->info;
  517. memset(d->info, 0, sizeof d->info);
  518. edma = d->edma;
  519. if(satawait(&edma->cmdstat, 0xE9, 0x40, 15*1000) == 0)
  520. goto Error;
  521. edma->altstat = ATAeIEN; /* no interrupts */
  522. edma->cmdstat = 0xEC;
  523. microdelay(1);
  524. if(satawait(&edma->cmdstat, ATAbusy, 0, 15*1000) == 0)
  525. goto Error;
  526. for(i=0; i<256; i++)
  527. id[i] = edma->pio;
  528. if(edma->cmdstat & (ATAerr|ATAdf))
  529. goto Error;
  530. i = lhgets(id+83) | lhgets(id+86);
  531. if(i & (1<<10)){
  532. d->flag |= Dext;
  533. d->sectors = lhgetv(id+100);
  534. }else{
  535. d->flag &= ~Dext;
  536. d->sectors = lhgetl(id+60);
  537. }
  538. idmove(d->serial, id+10, 20);
  539. idmove(d->firmware, id+23, 8);
  540. idmove(d->model, id+27, 40);
  541. unit = d->unit;
  542. memset(unit->inquiry, 0, sizeof unit->inquiry);
  543. unit->inquiry[2] = 2;
  544. unit->inquiry[3] = 2;
  545. unit->inquiry[4] = sizeof(unit->inquiry)-4;
  546. idmove((char*)unit->inquiry+8, id+27, 40);
  547. if(enabledrive(d)) {
  548. d->state = Dready;
  549. print("mvsata: m%d: LLBA %lld sectors\n",
  550. d->driveno, (Wideoff)d->sectors);
  551. } else
  552. d->state = Derror;
  553. return;
  554. Error:
  555. DPRINT("error...");
  556. d->state = Derror;
  557. }
  558. static void abortallsrb(Drive*);
  559. /* NB: d->unit and d->edma can be nil, empirically */
  560. static void
  561. updatedrive(Drive *d, ulong cause)
  562. {
  563. int x;
  564. Edma *edma;
  565. if(cause == 0)
  566. return;
  567. /* can't check this, cuz we have to run before identifydrive() */
  568. if (0 && d->magic != Drvmagic) {
  569. print("updatedrive: bad drive magic 0x%lux\n", d->magic);
  570. return;
  571. }
  572. if (d == nil) {
  573. DPRINT("nil d: updatedrive %#lux\n", cause);
  574. return;
  575. } else if (d->unit == nil)
  576. DPRINT("nil d->unit: updatedrive %#lux\n", cause);
  577. else if (d->unit->name == nil)
  578. DPRINT("nil d->unit->name: updatedrive %#lux\n", cause);
  579. else
  580. DPRINT("%s: updatedrive %#lux\n", d->unit->name, cause);
  581. edma = d->edma;
  582. if (edma == nil)
  583. print("mv50xx: updatedrive(m%d): zero d->edma\n", d->driveno);
  584. if(cause & eDevDis){
  585. d->state = Dmissing;
  586. if (edma)
  587. edma->ctl |= eAtaRst;
  588. microdelay(25);
  589. if (edma)
  590. edma->ctl &= ~eAtaRst;
  591. microdelay(25);
  592. }
  593. if(cause & eDevCon){
  594. d->bridge->sctrl = (d->bridge->sctrl & ~0xF) | 1;
  595. d->state = Dnew;
  596. }
  597. if(cause & eSelfDis)
  598. d->state = Derror;
  599. if (edma)
  600. edma->iec = 0;
  601. d->sectors = 0;
  602. if (d->unit)
  603. d->unit->sectors = 0;
  604. abortallsrb(d);
  605. SET(x);
  606. if (edma)
  607. x = edma->cmdstat;
  608. USED(x);
  609. }
  610. /*
  611. * Requests
  612. */
  613. static Srb*
  614. srbrw(int req, Drive *d, uchar *data, uint sectors, uvlong lba)
  615. {
  616. int i;
  617. Srb *srb;
  618. static uchar cmd[2][2] = { 0xC8, 0x25, 0xCA, 0x35 };
  619. switch(req){
  620. case SRBread:
  621. case SRBwrite:
  622. break;
  623. default:
  624. return nil;
  625. }
  626. srb = allocsrb();
  627. srb->req = req;
  628. srb->drive = d;
  629. srb->blockno = lba;
  630. srb->sectors = sectors;
  631. srb->count = sectors*512;
  632. srb->flag = 0;
  633. srb->data = data;
  634. for(i=0; i<6; i++)
  635. srb->lba[i] = lba >> (8*i);
  636. srb->cmd = cmd[srb->req!=SRBread][(d->flag&Dext)!=0];
  637. return srb;
  638. }
  639. static uintptr
  640. advance(uintptr pa, int shift)
  641. {
  642. int n, mask;
  643. mask = 0x1F<<shift;
  644. n = (pa & mask) + (1<<shift);
  645. return (pa & ~mask) | (n & mask);
  646. }
  647. #define CMD(r, v) (((r)<<8) | ((v)&0xFF))
  648. static void
  649. mvsatarequest(ushort *cmd, Srb *srb, int ext)
  650. {
  651. *cmd++ = CMD(ARseccnt, 0);
  652. *cmd++ = CMD(ARseccnt, srb->sectors);
  653. *cmd++ = CMD(ARfea, 0);
  654. if(ext){
  655. *cmd++ = CMD(ARlba0, srb->lba[3]);
  656. *cmd++ = CMD(ARlba0, srb->lba[0]);
  657. *cmd++ = CMD(ARlba1, srb->lba[4]);
  658. *cmd++ = CMD(ARlba1, srb->lba[1]);
  659. *cmd++ = CMD(ARlba2, srb->lba[5]);
  660. *cmd++ = CMD(ARlba2, srb->lba[2]);
  661. *cmd++ = CMD(ARdev, 0xE0);
  662. }else{
  663. *cmd++ = CMD(ARlba0, srb->lba[0]);
  664. *cmd++ = CMD(ARlba1, srb->lba[1]);
  665. *cmd++ = CMD(ARlba2, srb->lba[2]);
  666. *cmd++ = CMD(ARdev, srb->lba[3] | 0xE0);
  667. }
  668. *cmd++ = CMD(ARcmd, srb->cmd) | (1<<15);
  669. USED(cmd);
  670. }
  671. static void
  672. startsrb(Drive *d, Srb *srb)
  673. {
  674. int i;
  675. Edma *edma;
  676. Prd *prd;
  677. Tx *tx;
  678. if(d->nsrb >= nelem(d->srb)){
  679. srb->next = nil;
  680. if(d->srbhead)
  681. d->srbtail->next = srb;
  682. else
  683. d->srbhead = srb;
  684. d->srbtail = srb;
  685. return;
  686. }
  687. d->nsrb++;
  688. for(i=0; i<nelem(d->srb); i++)
  689. if(d->srb[i] == nil)
  690. break;
  691. if(i == nelem(d->srb))
  692. panic("sdmv50xx: no free srbs");
  693. d->srb[i] = srb;
  694. edma = d->edma;
  695. tx = (Tx*)KADDR(edma->txi);
  696. tx->flag = (i<<1) | (srb->req == SRBread);
  697. prd = KADDR(tx->prdpa);
  698. prd->pa = PADDR(srb->data);
  699. prd->count = srb->count;
  700. prd->flag = PRDeot;
  701. mvsatarequest(tx->regs, srb, d->flag&Dext);
  702. coherence();
  703. edma->txi = advance(edma->txi, 5);
  704. }
  705. static void
  706. completesrb(Drive *d)
  707. {
  708. Edma *edma;
  709. Rx *rx;
  710. Srb *srb;
  711. edma = d->edma;
  712. if (edma == 0)
  713. print("mv50xx: completesrb(m%d): zero d->edma\n", d->driveno);
  714. if(edma == 0 || (edma->ctl & eEnEDMA) == 0)
  715. return;
  716. while((edma->rxo & (0x1F<<3)) != (edma->rxi & (0x1F<<3))){
  717. rx = (Rx*)KADDR(edma->rxo);
  718. if(srb = d->srb[rx->cid]){
  719. d->srb[rx->cid] = nil;
  720. d->nsrb--;
  721. if(rx->cDevSts & (ATAerr|ATAdf))
  722. srb->flag |= SFerror;
  723. srb->flag |= SFdone;
  724. srb->sta = rx->cDevSts;
  725. wakeup(srb);
  726. }else
  727. iprint("srb missing\n");
  728. edma->rxo = advance(edma->rxo, 3);
  729. if(srb = d->srbhead){
  730. d->srbhead = srb->next;
  731. startsrb(d, srb);
  732. }
  733. }
  734. }
  735. static void
  736. abortallsrb(Drive *d)
  737. {
  738. int i;
  739. Srb *srb;
  740. for(i=0; i<nelem(d->srb); i++){
  741. if(srb = d->srb[i]){
  742. d->srb[i] = nil;
  743. d->nsrb--;
  744. srb->flag |= SFerror|SFdone;
  745. wakeup(srb);
  746. }
  747. }
  748. while(srb = d->srbhead){
  749. d->srbhead = srb->next;
  750. srb->flag |= SFerror|SFdone;
  751. wakeup(srb);
  752. }
  753. }
  754. static int
  755. srbdone(void *v)
  756. {
  757. Srb *srb;
  758. srb = v;
  759. return srb->flag & SFdone;
  760. }
  761. /*
  762. * Interrupts
  763. */
  764. static void
  765. mv50interrupt(Ureg*, void *a)
  766. {
  767. int i;
  768. ulong cause;
  769. Ctlr *ctlr;
  770. Drive *drive;
  771. ctlr = a;
  772. if (ctlr == nil)
  773. panic("mv50interrupt: nil ctlr");
  774. if (ctlr->magic != Ctlrmagic)
  775. panic("mv50interrupt: ctlr %p: bad controller magic 0x%lux",
  776. ctlr, ctlr->magic);
  777. ilock(ctlr);
  778. cause = *(ulong*)(ctlr->mmio + 0x1D60);
  779. // DPRINT("sd%c: mv50interrupt: 0x%lux\n", ctlr->sdev->idno, cause);
  780. for(i=0; i<ctlr->ndrive; i++)
  781. if(cause & (3<<(i*2+i/4))){
  782. drive = &ctlr->drive[i];
  783. if (drive->magic != Drvmagic) {
  784. print("mv50xx: interrupt for unconfigured drive %d\n",
  785. i);
  786. // continue;
  787. }
  788. ilock(drive);
  789. updatedrive(drive, drive->edma->iec);
  790. while(ctlr->chip[i/4].arb->ic & (0x0101 << (i%4))){
  791. ctlr->chip[i/4].arb->ic = ~(0x101 << (i%4));
  792. completesrb(drive);
  793. }
  794. iunlock(drive);
  795. }
  796. iunlock(ctlr);
  797. }
  798. /* our Drives are statically allocated in the Ctlr */
  799. static Drive*
  800. mvsatagetdrive(Ctlr *ctlr, int subno, int driveno)
  801. {
  802. Drive *drive = &ctlr->drive[subno];
  803. memset(drive, 0, sizeof *drive);
  804. USED(driveno);
  805. drive->driveno = -1; /* unset */
  806. drive->sectors = 0;
  807. return drive;
  808. }
  809. /*
  810. * Device discovery
  811. */
  812. static SDev*
  813. mv50pnp(void)
  814. {
  815. int i, nunit;
  816. uchar *base;
  817. ulong io;
  818. void *mem;
  819. Ctlr *ctlr;
  820. Pcidev *p;
  821. SDev *head, *tail, *sdev;
  822. static int ctlrno, done;
  823. DPRINT("mv50pnp\n");
  824. if (done)
  825. return nil;
  826. done = 1;
  827. p = nil;
  828. head = nil;
  829. tail = nil;
  830. while((p = pcimatch(p, 0x11AB, 0)) != nil){
  831. switch(p->did){
  832. case 0x5040:
  833. case 0x5041:
  834. case 0x5080:
  835. case 0x5081:
  836. case 0x6041:
  837. case 0x6081:
  838. break;
  839. default:
  840. print("unknown Marvell controller %ux; ignoring\n",
  841. (ushort)p->did);
  842. continue;
  843. }
  844. if (ctlrno >= NCtlr) {
  845. print("mv50pnp: too many controllers\n");
  846. break;
  847. }
  848. nunit = (p->did&0xf0) >> 4;
  849. print("Marvell 88SX%ux: %d SATA-%s ports with%s flash\n",
  850. (ushort)p->did, nunit,
  851. ((p->did&0xf000)==0x6000? "II": "I"),
  852. (p->did&1? "": "out"));
  853. if((sdev = malloc(sizeof(SDev))) == nil)
  854. continue;
  855. if((ctlr = malloc(sizeof(Ctlr))) == nil){
  856. free(sdev);
  857. continue;
  858. }
  859. io = p->mem[0].bar & ~0x0F;
  860. mem = (void *)vmap(io, p->mem[0].size);
  861. if(mem == 0){
  862. print("sdmv50xx: address 0x%luX in use\n", io);
  863. free(sdev);
  864. free(ctlr);
  865. continue;
  866. }
  867. sdev->ifc = &sdmv50xxifc;
  868. sdev->ctlr = ctlr;
  869. sdev->nunit = nunit;
  870. sdev->idno = 'E' + ctlrno;
  871. sdevs[ctlrno] = sdev;
  872. ctlr->sdev = sdev;
  873. ctlr->irq = p->intl;
  874. ctlr->tbdf = p->tbdf;
  875. ctlr->pcidev = p;
  876. ctlr->mmio = mem;
  877. ctlr->nchip = (nunit+3)/4;
  878. ctlr->ndrive = nunit;
  879. ctlr->magic = Ctlrmagic;
  880. ctlr->enabled = 0;
  881. for(i=0; i<ctlr->nchip; i++){
  882. base = ctlr->mmio+0x20000+0x10000*i;
  883. ctlr->chip[i].arb = (Arb*)base;
  884. ctlr->chip[i].edma = (Edma*)(base + 0x2000);
  885. }
  886. for (i = 0; i < nunit; i++) {
  887. Drive *drive =
  888. mvsatagetdrive(ctlr, i, ctlrno*NCtlrdrv +i);
  889. if(drive == nil)
  890. continue;
  891. drive->ctlr = ctlr;
  892. drive->driveno = ctlrno*NCtlrdrv + i;
  893. mvsatactlr[ctlrno] = ctlr;
  894. mvsatadrive[drive->driveno] = drive;
  895. drive->magic = Drvmagic;
  896. }
  897. ctlrno++;
  898. if(head)
  899. tail->next = sdev;
  900. else
  901. head = sdev;
  902. tail = sdev;
  903. }
  904. return head;
  905. }
  906. /*
  907. * Enable the controller. Each disk has its own interrupt mask,
  908. * and those get enabled as the disks are brought online.
  909. */
  910. static int
  911. mv50enable(SDev *sdev)
  912. {
  913. char name[32];
  914. Ctlr *ctlr;
  915. DPRINT("sd%c: enable\n", sdev->idno);
  916. ctlr = sdev->ctlr;
  917. if (ctlr == nil)
  918. panic("mv50enable: nil sdev->ctlr");
  919. if (ctlr->enabled)
  920. return 1;
  921. snprint(name, sizeof name, "%s (%s)", sdev->name, sdev->ifc->name);
  922. DPRINT("sd%c: irq %d\n", sdev->idno, ctlr->irq);
  923. if (ctlr->magic != Ctlrmagic)
  924. panic("mv50enable: bad controller magic 0x%lux", ctlr->magic);
  925. intrenable(ctlr->irq, mv50interrupt, ctlr, ctlr->tbdf, name);
  926. ctlr->enabled = 1;
  927. return 1;
  928. }
  929. /*
  930. * Disable the controller.
  931. */
  932. static int
  933. mv50disable(SDev *sdev)
  934. {
  935. char name[32];
  936. int i;
  937. Ctlr *ctlr;
  938. Drive *drive;
  939. DPRINT("sd%c: disable\n", sdev->idno);
  940. ctlr = sdev->ctlr;
  941. ilock(ctlr);
  942. for(i=0; i<ctlr->sdev->nunit; i++){
  943. drive = &ctlr->drive[i];
  944. ilock(drive);
  945. disabledrive(drive);
  946. iunlock(drive);
  947. }
  948. iunlock(ctlr);
  949. snprint(name, sizeof name, "%s (%s)", sdev->name, sdev->ifc->name);
  950. intrdisable(ctlr->irq, mv50interrupt, ctlr, ctlr->tbdf, name);
  951. return 0;
  952. }
  953. /*
  954. * Clean up all disk structures. Already disabled.
  955. * Could keep count of number of allocated controllers
  956. * and free the srblist when it drops to zero.
  957. */
  958. static void
  959. mv50clear(SDev *sdev)
  960. {
  961. int i;
  962. Ctlr *ctlr;
  963. Drive *d;
  964. DPRINT("sd%c: clear\n", sdev->idno);
  965. ctlr = sdev->ctlr;
  966. for(i=0; i<ctlr->ndrive; i++){
  967. d = &ctlr->drive[i];
  968. free(d->tx);
  969. free(d->rx);
  970. free(d->prd);
  971. }
  972. free(ctlr);
  973. }
  974. /*
  975. * Check that there is a disk or at least a hot swap bay in the drive.
  976. */
  977. static int
  978. mv50verify(SDunit *unit)
  979. {
  980. Ctlr *ctlr;
  981. Drive *drive;
  982. DPRINT("%s: verify\n", unit->name);
  983. /*
  984. * First access of unit.
  985. */
  986. ctlr = unit->dev->ctlr;
  987. drive = &ctlr->drive[unit->subno];
  988. ilock(ctlr);
  989. ilock(drive);
  990. if(!configdrive(ctlr, drive, unit) || !enabledrive(drive)){
  991. iunlock(drive);
  992. iunlock(ctlr);
  993. return 0;
  994. }
  995. /*
  996. * Need to reset the drive before the first call to
  997. * identifydrive, or else the satawait in setudma will
  998. * freeze the machine when accessing edma->cmdstat.
  999. * I do not understand this. -rsc
  1000. */
  1001. updatedrive(drive, eDevDis);
  1002. iunlock(drive);
  1003. iunlock(ctlr);
  1004. return 1;
  1005. }
  1006. /*
  1007. * Check whether the disk is online.
  1008. */
  1009. static int
  1010. mv50online(SDunit *unit)
  1011. {
  1012. Ctlr *ctlr;
  1013. Drive *drive;
  1014. ctlr = unit->dev->ctlr;
  1015. drive = &ctlr->drive[unit->subno];
  1016. if (drive->magic != Drvmagic)
  1017. print("mv50online: bad drive magic 0x%lux\n", drive->magic);
  1018. ilock(drive);
  1019. if(drive->state == Dready){
  1020. unit->sectors = drive->sectors;
  1021. unit->secsize = 512;
  1022. iunlock(drive);
  1023. return 1;
  1024. }
  1025. DPRINT("%s: online %s\n", unit->name, diskstates[drive->state]);
  1026. if(drive->state == Dnew || drive->state == Dmissing){
  1027. identifydrive(drive);
  1028. if(drive->state == Dready){
  1029. unit->sectors = drive->sectors;
  1030. unit->secsize = 512;
  1031. iunlock(drive);
  1032. return 2; /* media changed */
  1033. }
  1034. else
  1035. print("mv50online: %s did not come ready, now %s\n",
  1036. unit->name, diskstates[drive->state]);
  1037. }
  1038. iunlock(drive);
  1039. return 0;
  1040. }
  1041. /*
  1042. * Register dumps
  1043. */
  1044. typedef struct Regs Regs;
  1045. struct Regs
  1046. {
  1047. ulong offset;
  1048. char *name;
  1049. };
  1050. static Regs regsctlr[] =
  1051. {
  1052. 0x0C28, "pci serr# mask",
  1053. 0x1D40, "pci err addr low",
  1054. 0x1D44, "pci err addr hi",
  1055. 0x1D48, "pci err attr",
  1056. 0x1D50, "pci err cmd",
  1057. 0x1D58, "pci intr cause",
  1058. 0x1D5C, "pci mask cause",
  1059. 0x1D60, "device micr",
  1060. 0x1D64, "device mimr",
  1061. };
  1062. static Regs regsarb[] =
  1063. {
  1064. 0x0004, "arb rqop",
  1065. 0x0008, "arb rqip",
  1066. 0x000C, "arb ict",
  1067. 0x0010, "arb itt",
  1068. 0x0014, "arb ic",
  1069. 0x0018, "arb btc",
  1070. 0x001C, "arb bts",
  1071. 0x0020, "arb bpc",
  1072. };
  1073. static Regs regsbridge[] =
  1074. {
  1075. 0x0000, "bridge status",
  1076. 0x0004, "bridge serror",
  1077. 0x0008, "bridge sctrl",
  1078. 0x000C, "bridge phyctrl",
  1079. 0x003C, "bridge ctrl",
  1080. 0x0074, "bridge phymode",
  1081. };
  1082. static Regs regsedma[] =
  1083. {
  1084. 0x0000, "edma config",
  1085. 0x0004, "edma timer",
  1086. 0x0008, "edma iec",
  1087. 0x000C, "edma iem",
  1088. 0x0010, "edma txbasehi",
  1089. 0x0014, "edma txi",
  1090. 0x0018, "edma txo",
  1091. 0x001C, "edma rxbasehi",
  1092. 0x0020, "edma rxi",
  1093. 0x0024, "edma rxo",
  1094. 0x0028, "edma c",
  1095. 0x002C, "edma tc",
  1096. 0x0030, "edma status",
  1097. 0x0034, "edma iordyto",
  1098. /* 0x0100, "edma pio",
  1099. 0x0104, "edma err",
  1100. 0x0108, "edma sectors",
  1101. 0x010C, "edma lba0",
  1102. 0x0110, "edma lba1",
  1103. 0x0114, "edma lba2",
  1104. 0x0118, "edma lba3",
  1105. 0x011C, "edma cmdstat",
  1106. 0x0120, "edma altstat",
  1107. */
  1108. };
  1109. static char*
  1110. rdregs(char *p, char *e, void *base, Regs *r, int n, char *prefix)
  1111. {
  1112. int i;
  1113. for(i=0; i<n; i++)
  1114. p = seprint(p, e, "%s%s%-19s %.8ux\n",
  1115. prefix ? prefix : "", prefix ? ": " : "",
  1116. r[i].name, *(u32int*)((uchar*)base+r[i].offset));
  1117. return p;
  1118. }
  1119. static char*
  1120. rdinfo(char *p, char *e, ushort *info)
  1121. {
  1122. int i;
  1123. p = seprint(p, e, "info");
  1124. for(i=0; i<256; i++){
  1125. p = seprint(p, e, "%s%.4ux%s",
  1126. i%8==0 ? "\t" : "",
  1127. info[i],
  1128. i%8==7 ? "\n" : "");
  1129. }
  1130. return p;
  1131. }
  1132. #ifndef FS
  1133. static int
  1134. mv50rctl(SDunit *unit, char *p, int l)
  1135. {
  1136. char *e, *op;
  1137. Ctlr *ctlr;
  1138. Drive *drive;
  1139. if((ctlr = unit->dev->ctlr) == nil)
  1140. return 0;
  1141. drive = &ctlr->drive[unit->subno];
  1142. e = p+l;
  1143. op = p;
  1144. if(drive->state == Dready){
  1145. p = seprint(p, e, "model %s\n", drive->model);
  1146. p = seprint(p, e, "serial %s\n", drive->serial);
  1147. p = seprint(p, e, "firmware %s\n", drive->firmware);
  1148. }else
  1149. p = seprint(p, e, "no disk present\n");
  1150. p = seprint(p, e, "geometry %llud 512\n", drive->sectors);
  1151. p = rdinfo(p, e, drive->info);
  1152. p = rdregs(p, e, drive->chip->arb, regsarb, nelem(regsarb), nil);
  1153. p = rdregs(p, e, drive->bridge, regsbridge, nelem(regsbridge), nil);
  1154. p = rdregs(p, e, drive->edma, regsedma, nelem(regsedma), nil);
  1155. return p-op;
  1156. }
  1157. static int
  1158. mv50wctl(SDunit *unit, Cmdbuf *cb)
  1159. {
  1160. Ctlr *ctlr;
  1161. Drive *drive;
  1162. USED(unit);
  1163. if(strcmp(cb->f[0], "reset") == 0){
  1164. ctlr = unit->dev->ctlr;
  1165. drive = &ctlr->drive[unit->subno];
  1166. ilock(drive);
  1167. updatedrive(drive, eDevDis);
  1168. iunlock(drive);
  1169. return 0;
  1170. }
  1171. cmderror(cb, Ebadctl);
  1172. return -1;
  1173. }
  1174. static char*
  1175. mv50rtopctl(SDev *sdev, char *p, char *e)
  1176. {
  1177. char name[10];
  1178. Ctlr *ctlr;
  1179. ctlr = sdev->ctlr;
  1180. if(ctlr == nil)
  1181. return p;
  1182. snprint(name, sizeof name, "sd%c", sdev->idno);
  1183. p = rdregs(p, e, ctlr->mmio, regsctlr, nelem(regsctlr), name);
  1184. /* info for first disk */
  1185. p = rdregs(p, e, ctlr->chip[0].arb, regsarb, nelem(regsarb), name);
  1186. p = rdregs(p, e, &ctlr->chip[0].arb->bridge[0], regsbridge, nelem(regsbridge), name);
  1187. p = rdregs(p, e, &ctlr->chip[0].edma[0], regsedma, nelem(regsedma), name);
  1188. return p;
  1189. }
  1190. #endif
  1191. static int
  1192. mv50rio(SDreq *r)
  1193. {
  1194. int count, max, n, status;
  1195. uchar *cmd, *data;
  1196. uvlong lba;
  1197. Ctlr *ctlr;
  1198. Drive *drive;
  1199. SDunit *unit;
  1200. Srb *srb;
  1201. unit = r->unit;
  1202. ctlr = unit->dev->ctlr;
  1203. drive = &ctlr->drive[unit->subno];
  1204. cmd = r->cmd;
  1205. if((status = sdfakescsi(r, drive->info, sizeof drive->info)) != SDnostatus){
  1206. /* XXX check for SDcheck here */
  1207. r->status = status;
  1208. return status;
  1209. }
  1210. switch(cmd[0]){
  1211. case 0x28: /* read */
  1212. case 0x2A: /* write */
  1213. break;
  1214. default:
  1215. print("sdmv50xx: bad cmd 0x%.2ux\n", cmd[0]);
  1216. r->status = SDcheck;
  1217. return SDcheck;
  1218. }
  1219. lba = (cmd[2]<<24)|(cmd[3]<<16)|(cmd[4]<<8)|cmd[5];
  1220. count = (cmd[7]<<8)|cmd[8];
  1221. if(r->data == nil)
  1222. return SDok;
  1223. if(r->dlen < count*unit->secsize)
  1224. count = r->dlen/unit->secsize;
  1225. /*
  1226. * Could arrange here to have an Srb always outstanding:
  1227. *
  1228. * lsrb = nil;
  1229. * while(count > 0 || lsrb != nil){
  1230. * srb = nil;
  1231. * if(count > 0){
  1232. * srb = issue next srb;
  1233. * }
  1234. * if(lsrb){
  1235. * sleep on lsrb and handle it
  1236. * }
  1237. * }
  1238. *
  1239. * On the disks I tried, this didn't help. If anything,
  1240. * it's a little slower. -rsc
  1241. */
  1242. data = r->data;
  1243. while(count > 0){
  1244. /*
  1245. * Max is 128 sectors (64kB) because prd->count is 16 bits.
  1246. */
  1247. max = 128;
  1248. n = count;
  1249. if(n > max)
  1250. n = max;
  1251. srb = srbrw(cmd[0]==0x28 ? SRBread : SRBwrite, drive, data, n, lba);
  1252. ilock(drive);
  1253. startsrb(drive, srb);
  1254. iunlock(drive);
  1255. /*
  1256. * Cannot let user interrupt the DMA.
  1257. */
  1258. while(waserror())
  1259. ;
  1260. tsleep(srb, srbdone, srb, 60*1000);
  1261. poperror();
  1262. if(!(srb->flag & SFdone)){
  1263. ilock(drive);
  1264. if(!(srb->flag & SFdone)){
  1265. /*
  1266. * DMA didn't finish but we have to let go of
  1267. * the data buffer. Reset the drive to (try to) keep it
  1268. * from using the buffer after we're gone.
  1269. */
  1270. iprint("%s: i/o timeout\n", unit->name);
  1271. updatedrive(drive, eDevDis);
  1272. enabledrive(drive);
  1273. freesrb(srb);
  1274. iunlock(drive);
  1275. error("i/o timeout");
  1276. }
  1277. iunlock(drive);
  1278. }
  1279. if(srb->flag & SFerror){
  1280. freesrb(srb);
  1281. error("i/o error");
  1282. }
  1283. freesrb(srb);
  1284. count -= n;
  1285. lba += n;
  1286. data += n*unit->secsize;
  1287. }
  1288. r->rlen = data - (uchar*)r->data;
  1289. return SDok;
  1290. err:
  1291. return SDeio;
  1292. }
  1293. SDifc sdmv50xxifc = {
  1294. "mv50xx", /* name */
  1295. mv50pnp, /* pnp */
  1296. nil, /* legacy */
  1297. #ifdef FS
  1298. nil, /* id */
  1299. #endif
  1300. mv50enable, /* enable */
  1301. mv50disable, /* disable */
  1302. mv50verify, /* verify */
  1303. mv50online, /* online */
  1304. mv50rio, /* rio */
  1305. #ifdef FS
  1306. nil,
  1307. nil,
  1308. #else
  1309. mv50rctl, /* rctl */
  1310. mv50wctl, /* wctl */
  1311. #endif
  1312. scsibio, /* bio */
  1313. #ifndef FS
  1314. nil, /* probe */
  1315. mv50clear, /* clear */
  1316. mv50rtopctl, /* rtopctl */
  1317. #endif
  1318. };
  1319. /*
  1320. * file-server-specific routines
  1321. *
  1322. * mvide* routines implement the `m' device and call the mvsata* routines.
  1323. */
  1324. static Drive*
  1325. mvsatapart(Drive *dp)
  1326. {
  1327. return dp;
  1328. }
  1329. static Drive*
  1330. mvsatadriveprobe(int driveno)
  1331. {
  1332. Drive *drive;
  1333. drive = mvsatadrive[driveno];
  1334. if (drive == nil)
  1335. return nil;
  1336. if (drive->magic != Drvmagic)
  1337. print("mv50xx: mvsatadriveprobe(m%d): bad drive magic 0x%lux\n",
  1338. driveno, drive->magic);
  1339. drive->driveno = driveno;
  1340. if(drive->online == 0){
  1341. /* LBA assumed */
  1342. print("m%d: LBA %,llud sectors\n",
  1343. drive->driveno, (Wideoff)drive->sectors);
  1344. drive->online = 1;
  1345. }
  1346. return mvsatapart(drive);
  1347. }
  1348. /* find all the controllers, enable interrupts, set up SDevs & SDunits */
  1349. int
  1350. mvsatainit(void)
  1351. {
  1352. unsigned i;
  1353. SDev *sdp;
  1354. SDev **sdpp;
  1355. SDunit *sup;
  1356. SDunit **supp;
  1357. static int first = 1;
  1358. if (first)
  1359. first = 0;
  1360. else
  1361. return 0xFF;
  1362. mv50pnp();
  1363. for (sdpp = sdevs; sdpp < sdevs + nelem(sdevs); sdpp++) {
  1364. sdp = *sdpp;
  1365. if (sdp == nil)
  1366. continue;
  1367. i = sdpp - sdevs;
  1368. sdp->ifc = &sdmv50xxifc;
  1369. sdp->nunit = NCtlrdrv;
  1370. sdp->index = i;
  1371. sdp->idno = 'E' + i;
  1372. sdp->ctlr = mvsatactlr[i];
  1373. if (sdp->ctlr != nil)
  1374. mv50enable(sdp);
  1375. }
  1376. for (supp = sdunits; supp < sdunits + nelem(sdunits); supp++) {
  1377. sup = *supp;
  1378. if (sup == nil)
  1379. continue;
  1380. i = supp - sdunits;
  1381. sup->dev = sdevs[i/NCtlrdrv]; /* controller */
  1382. sup->subno = i%NCtlrdrv; /* drive within controller */
  1383. snprint(sup->name, sizeof sup->name, "m%d", i);
  1384. }
  1385. statsinit();
  1386. return 0xFF;
  1387. }
  1388. Devsize
  1389. mvsataseek(int driveno, Devsize offset)
  1390. {
  1391. Drive *drive = mvsatadrive[driveno];
  1392. if (drive == nil || !drive->online)
  1393. return -1;
  1394. drive->offset = offset;
  1395. return offset;
  1396. }
  1397. /* zero indicates failure; only otherinit() cares */
  1398. int
  1399. setmv50part(int driveno, char *)
  1400. {
  1401. /* mvsatadriveprobe() sets drive->online */
  1402. if(mvsatadriveprobe(driveno) == nil)
  1403. return 0;
  1404. return 1;
  1405. }
  1406. static void
  1407. keepstats(SDunit *unit, int dbytes)
  1408. {
  1409. Ctlr *ctlr = unit->dev->ctlr;
  1410. Target *tp = &ctlr->target[unit->subno];
  1411. qlock(tp);
  1412. if(tp->fflag == 0) {
  1413. dofilter(tp->work+0, C0a, C0b, 1); /* was , 1000); */
  1414. dofilter(tp->work+1, C1a, C1b, 1); /* was , 1000); */
  1415. dofilter(tp->work+2, C2a, C2b, 1); /* was , 1000); */
  1416. dofilter(tp->rate+0, C0a, C0b, 1);
  1417. dofilter(tp->rate+1, C1a, C1b, 1);
  1418. dofilter(tp->rate+2, C2a, C2b, 1);
  1419. tp->fflag = 1;
  1420. }
  1421. tp->work[0].count++;
  1422. tp->work[1].count++;
  1423. tp->work[2].count++;
  1424. tp->rate[0].count += dbytes;
  1425. tp->rate[1].count += dbytes;
  1426. tp->rate[2].count += dbytes;
  1427. qunlock(tp);
  1428. }
  1429. static long
  1430. mvsataxfer(Drive *dp, void *, int inout, Devsize start, long bytes)
  1431. {
  1432. unsigned driveno = dp->driveno;
  1433. ulong secsize = dp->unit->secsize, sects;
  1434. SDunit *unit;
  1435. SDunit **unitp = sdunits + driveno;
  1436. static int beenhere;
  1437. DPRINT("%s: mvsataxfer\n", dp->unit->name);
  1438. unit = *unitp;
  1439. if (unit == nil) {
  1440. print("mvsataxfer: nil unit\n");
  1441. return -1;
  1442. }
  1443. if (!beenhere && dp->unit != unit) {
  1444. beenhere = 1;
  1445. print("mvsataxfer: units differ: dp->unit %p unit %p\n",
  1446. dp->unit, unit);
  1447. }
  1448. if (dp->driveno == -1)
  1449. panic("mvsataxfer: dp->driveno unset");
  1450. if (unit->dev != sdevs[driveno/NCtlrdrv])
  1451. panic("mvsataxfer: SDunit[%d].dev is wrong controller", driveno);
  1452. if (unit->subno != driveno%NCtlrdrv)
  1453. panic("mvsataxfer: SDunit[%d].subno is %d, not %d",
  1454. driveno, unit->subno, driveno%NCtlrdrv);
  1455. if (unit->sectors == 0) {
  1456. unit->sectors = dp->sectors;
  1457. unit->secsize = secsize;
  1458. }
  1459. keepstats(unit, bytes);
  1460. sects = (bytes + secsize - 1) / secsize; /* round up */
  1461. if (start%secsize != 0)
  1462. print("mvsataxfer: start offset not on sector boundary\n");
  1463. return scsibio(unit, 0, inout, dp->buf, sects, start/secsize);
  1464. }
  1465. /*
  1466. * mvsataread & mvsatawrite do the real work;
  1467. * mvideread & mvidewrite just call them.
  1468. * mvsataread & mvsatawrite are called by the nvram routines.
  1469. * mvideread & mvidewrite are called for normal file server I/O.
  1470. */
  1471. Off
  1472. mvsataread(int driveno, void *a, long n)
  1473. {
  1474. int skip;
  1475. Off rv, i;
  1476. uchar *aa = a;
  1477. // Ctlr *cp;
  1478. Drive *dp;
  1479. DPRINT("m%d: mvsataread\n", driveno);
  1480. dp = mvsatadrive[driveno];
  1481. if(dp == nil || !dp->online)
  1482. return 0;
  1483. DPRINT("%s: mvsataread drive=%p\n", dp->unit->name, dp);
  1484. // cp = dp->ctlr;
  1485. if (dp->unit->secsize == 0)
  1486. panic("mvsataread: %s: sector size of zero", dp->unit->name);
  1487. skip = dp->offset % dp->unit->secsize;
  1488. for(rv = 0; rv < n; rv += i){
  1489. i = mvsataxfer(dp, nil, Read, dp->offset+rv-skip, n-rv+skip);
  1490. if(i == 0)
  1491. break;
  1492. if(i < 0) {
  1493. return -1;
  1494. }
  1495. i -= skip;
  1496. if(i > n - rv)
  1497. i = n - rv;
  1498. memmove(aa+rv, dp->buf + skip, i);
  1499. skip = 0;
  1500. }
  1501. dp->offset += rv;
  1502. return rv;
  1503. }
  1504. Off
  1505. mvsatawrite(int driveno, void *a, long n)
  1506. {
  1507. Off rv, i, partial;
  1508. uchar *aa = a;
  1509. // Ctlr *cp;
  1510. Drive *dp;
  1511. DPRINT("m%d: mvsatawrite\n", driveno);
  1512. dp = mvsatadrive[driveno];
  1513. if(dp == nil || !dp->online)
  1514. return 0;
  1515. DPRINT("%s: mvsatawrite drive=%p\n", dp->unit->name, dp);
  1516. // cp = dp->ctlr;
  1517. /*
  1518. * if not starting on a sector boundary,
  1519. * read in the first sector before writing it out.
  1520. */
  1521. if (dp->unit->secsize == 0)
  1522. panic("mvsatawrite: %s: sector size of zero", dp->unit->name);
  1523. partial = dp->offset % dp->unit->secsize;
  1524. if(partial){
  1525. if (mvsataxfer(dp, nil, Read, dp->offset-partial,
  1526. dp->unit->secsize) < 0)
  1527. return -1;
  1528. if(partial+n > dp->unit->secsize)
  1529. rv = dp->unit->secsize - partial;
  1530. else
  1531. rv = n;
  1532. memmove(dp->buf+partial, aa, rv);
  1533. if (mvsataxfer(dp, nil, Write, dp->offset-partial,
  1534. dp->unit->secsize) < 0)
  1535. return -1;
  1536. } else
  1537. rv = 0;
  1538. /*
  1539. * write out the full sectors (common case)
  1540. */
  1541. partial = (n - rv) % dp->unit->secsize;
  1542. n -= partial;
  1543. for(; rv < n; rv += i){
  1544. i = n - rv;
  1545. if(i > Maxxfer)
  1546. i = Maxxfer;
  1547. memmove(dp->buf, aa+rv, i);
  1548. i = mvsataxfer(dp, nil, Write, dp->offset+rv, i);
  1549. if(i == 0)
  1550. break;
  1551. if(i < 0)
  1552. return -1;
  1553. }
  1554. /*
  1555. * if not ending on a sector boundary,
  1556. * read in the last sector before writing it out.
  1557. */
  1558. if(partial){
  1559. if (mvsataxfer(dp, nil, Read, dp->offset+rv, dp->unit->secsize)
  1560. < 0)
  1561. return -1;
  1562. memmove(dp->buf, aa+rv, partial);
  1563. if (mvsataxfer(dp, nil, Write, dp->offset+rv, dp->unit->secsize)
  1564. < 0)
  1565. return -1;
  1566. rv += partial;
  1567. }
  1568. dp->offset += rv;
  1569. return rv;
  1570. }
  1571. /*
  1572. * normal file server I/O interface
  1573. */
  1574. /* result is size of d in blocks of RBUFSIZE bytes */
  1575. Devsize
  1576. mvidesize(Device *d)
  1577. {
  1578. Drive *dp = d->private;
  1579. if (dp == nil)
  1580. return 0;
  1581. /*
  1582. * dividing first is sloppy but reduces the range of intermediate
  1583. * values, avoiding possible overflow.
  1584. */
  1585. return (dp->sectors / RBUFSIZE) * dp->unit->secsize;
  1586. }
  1587. void
  1588. mvideinit(Device *d)
  1589. {
  1590. int driveno;
  1591. Drive *dp;
  1592. DPRINT("mvideinit\n");
  1593. mvsatainit();
  1594. if (d->private)
  1595. return;
  1596. /* call setmv50part() first in case we didn't boot off this drive */
  1597. driveno = d->wren.ctrl*NCtlrdrv + d->wren.targ;
  1598. DPRINT("%Z: mvideinit\n", d);
  1599. setmv50part(driveno, "disk");
  1600. dp = mvsatadriveprobe(driveno);
  1601. if (dp) {
  1602. print("mvideinit(ctrl %d targ %d) driveno %d\n",
  1603. d->wren.ctrl, d->wren.targ, dp->driveno);
  1604. if (dp->driveno != driveno)
  1605. panic("mvideinit: dp->dev != driveno");
  1606. if (dp->magic != Drvmagic)
  1607. panic("mvideinit: %Z: bad drive magic", d);
  1608. d->private = dp;
  1609. if (dp->unit == nil)
  1610. panic("mvideinit: %Z: nil dp->unit", d);
  1611. /* print the sizes now, not later */
  1612. print(
  1613. " mvidesize(driveno %d): %llud %lud-byte sectors -> %llud blocks\n",
  1614. dp->driveno, (Wideoff)dp->sectors, dp->unit->secsize,
  1615. (Wideoff)mvidesize(d));
  1616. if (dp->unit->secsize == 0)
  1617. panic("%Z: zero sector size", d);
  1618. if (dp->sectors == 0)
  1619. panic("%Z: zero sectors", d);
  1620. }
  1621. }
  1622. int
  1623. mvideread(Device *d, Devsize b, void *c)
  1624. {
  1625. int x, driveno;
  1626. Drive *dp;
  1627. Ctlr *cp;
  1628. if (d == nil || d->private == nil) {
  1629. print("mvideread: %Z: nil d or d->private == nil\n", d);
  1630. return 1;
  1631. }
  1632. dp = d->private;
  1633. cp = dp->ctlr;
  1634. if (cp == nil)
  1635. panic("mvideread: no controller for drive");
  1636. qlock(&cp->idelock);
  1637. cp->idelock.name = "mvideio";
  1638. driveno = dp->driveno;
  1639. if (driveno == -1)
  1640. panic("mvideread: dp->driveno unset");
  1641. IDPRINT("mvideread(dev %lux, %lld, %lux, %d): %lux\n",
  1642. (ulong)d, (Wideoff)b, (ulong)c, driveno, (ulong)dp);
  1643. mvsataseek(driveno, b * RBUFSIZE);
  1644. x = mvsataread(driveno, c, RBUFSIZE) != RBUFSIZE;
  1645. qunlock(&cp->idelock);
  1646. return x;
  1647. }
  1648. int
  1649. mvidewrite(Device *d, Devsize b, void *c)
  1650. {
  1651. int x, driveno;
  1652. Drive *dp;
  1653. Ctlr *cp;
  1654. if (d == nil || d->private == nil) {
  1655. print("mvidewrite: %Z: nil d or d->private == nil\n", d);
  1656. return 1;
  1657. }
  1658. dp = d->private;
  1659. cp = dp->ctlr;
  1660. if (cp == nil)
  1661. panic("mvidewrite: no controller for drive");
  1662. qlock(&cp->idelock);
  1663. cp->idelock.name = "mvideio";
  1664. driveno = dp->driveno;
  1665. if (driveno == -1)
  1666. panic("mvidewrite: dp->driveno unset");
  1667. IDPRINT("mvidewrite(%ux, %lld, %ux): driveno %d\n",
  1668. (int)d, (Wideoff)b, (int)c, driveno);
  1669. mvsataseek(driveno, b * RBUFSIZE);
  1670. x = mvsatawrite(driveno, c, RBUFSIZE) != RBUFSIZE;
  1671. qunlock(&cp->idelock);
  1672. return x;
  1673. }
  1674. static void
  1675. cmd_stat(int, char*[])
  1676. {
  1677. Ctlr *ctlr;
  1678. int ctlrno, targetno;
  1679. Target *tp;
  1680. for(ctlrno = 0; ctlrno < nelem(mvsatactlr); ctlrno++){
  1681. ctlr = mvsatactlr[ctlrno];
  1682. if(ctlr == nil || ctlr->sdev == nil)
  1683. continue;
  1684. for(targetno = 0; targetno < NTarget; targetno++){
  1685. tp = &ctlr->target[targetno];
  1686. if(tp->fflag == 0)
  1687. continue;
  1688. print("\t%d.%d work =%7W%7W%7W xfrs\n",
  1689. ctlrno, targetno,
  1690. tp->work+0, tp->work+1, tp->work+2);
  1691. print("\t rate =%7W%7W%7W tBps\n",
  1692. tp->rate+0, tp->rate+1, tp->rate+2);
  1693. }
  1694. }
  1695. }
  1696. static void
  1697. statsinit(void)
  1698. {
  1699. cmd_install("statm", "-- marvell sata stats", cmd_stat);
  1700. }
  1701. /* Tab 4 Font
  1702. * Copyright 2005
  1703. * Coraid, Inc.
  1704. *
  1705. * This software is provided `as-is,' without any express or implied
  1706. * warranty. In no event will the author be held liable for any damages
  1707. * arising from the use of this software.
  1708. *
  1709. * Permission is granted to anyone to use this software for any purpose,
  1710. * including commercial applications, and to alter it and redistribute it
  1711. * freely, subject to the following restrictions:
  1712. *
  1713. * 1. The origin of this software must not be misrepresented; you must
  1714. * not claim that you wrote the original software. If you use this
  1715. * software in a product, an acknowledgment in the product documentation
  1716. * would be appreciated but is not required.
  1717. *
  1718. * 2. Altered source versions must be plainly marked as such, and must
  1719. * not be misrepresented as being the original software.
  1720. *
  1721. * 3. This notice may not be removed or altered from any source
  1722. * distribution.
  1723. */