megaraid_mm.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248
  1. /*
  2. *
  3. * Linux MegaRAID device driver
  4. *
  5. * Copyright (c) 2003-2004 LSI Logic Corporation.
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License
  9. * as published by the Free Software Foundation; either version
  10. * 2 of the License, or (at your option) any later version.
  11. *
  12. * FILE : megaraid_mm.c
  13. * Version : v2.20.2.7 (Jul 16 2006)
  14. *
  15. * Common management module
  16. */
  17. #include <linux/sched.h>
  18. #include <linux/slab.h>
  19. #include <linux/smp_lock.h>
  20. #include "megaraid_mm.h"
  21. // Entry points for char node driver
  22. static int mraid_mm_open(struct inode *, struct file *);
  23. static int mraid_mm_ioctl(struct inode *, struct file *, uint, unsigned long);
  24. // routines to convert to and from the old the format
  25. static int mimd_to_kioc(mimd_t __user *, mraid_mmadp_t *, uioc_t *);
  26. static int kioc_to_mimd(uioc_t *, mimd_t __user *);
  27. // Helper functions
  28. static int handle_drvrcmd(void __user *, uint8_t, int *);
  29. static int lld_ioctl(mraid_mmadp_t *, uioc_t *);
  30. static void ioctl_done(uioc_t *);
  31. static void lld_timedout(unsigned long);
  32. static void hinfo_to_cinfo(mraid_hba_info_t *, mcontroller_t *);
  33. static mraid_mmadp_t *mraid_mm_get_adapter(mimd_t __user *, int *);
  34. static uioc_t *mraid_mm_alloc_kioc(mraid_mmadp_t *);
  35. static void mraid_mm_dealloc_kioc(mraid_mmadp_t *, uioc_t *);
  36. static int mraid_mm_attach_buf(mraid_mmadp_t *, uioc_t *, int);
  37. static int mraid_mm_setup_dma_pools(mraid_mmadp_t *);
  38. static void mraid_mm_free_adp_resources(mraid_mmadp_t *);
  39. static void mraid_mm_teardown_dma_pools(mraid_mmadp_t *);
  40. #ifdef CONFIG_COMPAT
  41. static long mraid_mm_compat_ioctl(struct file *, unsigned int, unsigned long);
  42. #endif
  43. MODULE_AUTHOR("LSI Logic Corporation");
  44. MODULE_DESCRIPTION("LSI Logic Management Module");
  45. MODULE_LICENSE("GPL");
  46. MODULE_VERSION(LSI_COMMON_MOD_VERSION);
  47. static int dbglevel = CL_ANN;
  48. module_param_named(dlevel, dbglevel, int, 0);
  49. MODULE_PARM_DESC(dlevel, "Debug level (default=0)");
  50. EXPORT_SYMBOL(mraid_mm_register_adp);
  51. EXPORT_SYMBOL(mraid_mm_unregister_adp);
  52. EXPORT_SYMBOL(mraid_mm_adapter_app_handle);
  53. static uint32_t drvr_ver = 0x02200207;
  54. static int adapters_count_g;
  55. static struct list_head adapters_list_g;
  56. static wait_queue_head_t wait_q;
  57. static const struct file_operations lsi_fops = {
  58. .open = mraid_mm_open,
  59. .ioctl = mraid_mm_ioctl,
  60. #ifdef CONFIG_COMPAT
  61. .compat_ioctl = mraid_mm_compat_ioctl,
  62. #endif
  63. .owner = THIS_MODULE,
  64. };
  65. static struct miscdevice megaraid_mm_dev = {
  66. .minor = MISC_DYNAMIC_MINOR,
  67. .name = "megadev0",
  68. .fops = &lsi_fops,
  69. };
  70. /**
  71. * mraid_mm_open - open routine for char node interface
  72. * @inode : unused
  73. * @filep : unused
  74. *
  75. * Allow ioctl operations by apps only if they have superuser privilege.
  76. */
  77. static int
  78. mraid_mm_open(struct inode *inode, struct file *filep)
  79. {
  80. /*
  81. * Only allow superuser to access private ioctl interface
  82. */
  83. if (!capable(CAP_SYS_ADMIN)) return (-EACCES);
  84. cycle_kernel_lock();
  85. return 0;
  86. }
  87. /**
  88. * mraid_mm_ioctl - module entry-point for ioctls
  89. * @inode : inode (ignored)
  90. * @filep : file operations pointer (ignored)
  91. * @cmd : ioctl command
  92. * @arg : user ioctl packet
  93. */
  94. static int
  95. mraid_mm_ioctl(struct inode *inode, struct file *filep, unsigned int cmd,
  96. unsigned long arg)
  97. {
  98. uioc_t *kioc;
  99. char signature[EXT_IOCTL_SIGN_SZ] = {0};
  100. int rval;
  101. mraid_mmadp_t *adp;
  102. uint8_t old_ioctl;
  103. int drvrcmd_rval;
  104. void __user *argp = (void __user *)arg;
  105. /*
  106. * Make sure only USCSICMD are issued through this interface.
  107. * MIMD application would still fire different command.
  108. */
  109. if ((_IOC_TYPE(cmd) != MEGAIOC_MAGIC) && (cmd != USCSICMD)) {
  110. return (-EINVAL);
  111. }
  112. /*
  113. * Look for signature to see if this is the new or old ioctl format.
  114. */
  115. if (copy_from_user(signature, argp, EXT_IOCTL_SIGN_SZ)) {
  116. con_log(CL_ANN, (KERN_WARNING
  117. "megaraid cmm: copy from usr addr failed\n"));
  118. return (-EFAULT);
  119. }
  120. if (memcmp(signature, EXT_IOCTL_SIGN, EXT_IOCTL_SIGN_SZ) == 0)
  121. old_ioctl = 0;
  122. else
  123. old_ioctl = 1;
  124. /*
  125. * At present, we don't support the new ioctl packet
  126. */
  127. if (!old_ioctl )
  128. return (-EINVAL);
  129. /*
  130. * If it is a driver ioctl (as opposed to fw ioctls), then we can
  131. * handle the command locally. rval > 0 means it is not a drvr cmd
  132. */
  133. rval = handle_drvrcmd(argp, old_ioctl, &drvrcmd_rval);
  134. if (rval < 0)
  135. return rval;
  136. else if (rval == 0)
  137. return drvrcmd_rval;
  138. rval = 0;
  139. if ((adp = mraid_mm_get_adapter(argp, &rval)) == NULL) {
  140. return rval;
  141. }
  142. /*
  143. * Check if adapter can accept ioctl. We may have marked it offline
  144. * if any previous kioc had timedout on this controller.
  145. */
  146. if (!adp->quiescent) {
  147. con_log(CL_ANN, (KERN_WARNING
  148. "megaraid cmm: controller cannot accept cmds due to "
  149. "earlier errors\n" ));
  150. return -EFAULT;
  151. }
  152. /*
  153. * The following call will block till a kioc is available
  154. */
  155. kioc = mraid_mm_alloc_kioc(adp);
  156. /*
  157. * User sent the old mimd_t ioctl packet. Convert it to uioc_t.
  158. */
  159. if ((rval = mimd_to_kioc(argp, adp, kioc))) {
  160. mraid_mm_dealloc_kioc(adp, kioc);
  161. return rval;
  162. }
  163. kioc->done = ioctl_done;
  164. /*
  165. * Issue the IOCTL to the low level driver. After the IOCTL completes
  166. * release the kioc if and only if it was _not_ timedout. If it was
  167. * timedout, that means that resources are still with low level driver.
  168. */
  169. if ((rval = lld_ioctl(adp, kioc))) {
  170. if (!kioc->timedout)
  171. mraid_mm_dealloc_kioc(adp, kioc);
  172. return rval;
  173. }
  174. /*
  175. * Convert the kioc back to user space
  176. */
  177. rval = kioc_to_mimd(kioc, argp);
  178. /*
  179. * Return the kioc to free pool
  180. */
  181. mraid_mm_dealloc_kioc(adp, kioc);
  182. return rval;
  183. }
  184. /**
  185. * mraid_mm_get_adapter - Returns corresponding adapters for the mimd packet
  186. * @umimd : User space mimd_t ioctl packet
  187. * @rval : returned success/error status
  188. *
  189. * The function return value is a pointer to the located @adapter.
  190. */
  191. static mraid_mmadp_t *
  192. mraid_mm_get_adapter(mimd_t __user *umimd, int *rval)
  193. {
  194. mraid_mmadp_t *adapter;
  195. mimd_t mimd;
  196. uint32_t adapno;
  197. int iterator;
  198. if (copy_from_user(&mimd, umimd, sizeof(mimd_t))) {
  199. *rval = -EFAULT;
  200. return NULL;
  201. }
  202. adapno = GETADAP(mimd.ui.fcs.adapno);
  203. if (adapno >= adapters_count_g) {
  204. *rval = -ENODEV;
  205. return NULL;
  206. }
  207. adapter = NULL;
  208. iterator = 0;
  209. list_for_each_entry(adapter, &adapters_list_g, list) {
  210. if (iterator++ == adapno) break;
  211. }
  212. if (!adapter) {
  213. *rval = -ENODEV;
  214. return NULL;
  215. }
  216. return adapter;
  217. }
  218. /**
  219. * handle_drvrcmd - Checks if the opcode is a driver cmd and if it is, handles it.
  220. * @arg : packet sent by the user app
  221. * @old_ioctl : mimd if 1; uioc otherwise
  222. * @rval : pointer for command's returned value (not function status)
  223. */
  224. static int
  225. handle_drvrcmd(void __user *arg, uint8_t old_ioctl, int *rval)
  226. {
  227. mimd_t __user *umimd;
  228. mimd_t kmimd;
  229. uint8_t opcode;
  230. uint8_t subopcode;
  231. if (old_ioctl)
  232. goto old_packet;
  233. else
  234. goto new_packet;
  235. new_packet:
  236. return (-ENOTSUPP);
  237. old_packet:
  238. *rval = 0;
  239. umimd = arg;
  240. if (copy_from_user(&kmimd, umimd, sizeof(mimd_t)))
  241. return (-EFAULT);
  242. opcode = kmimd.ui.fcs.opcode;
  243. subopcode = kmimd.ui.fcs.subopcode;
  244. /*
  245. * If the opcode is 0x82 and the subopcode is either GET_DRVRVER or
  246. * GET_NUMADP, then we can handle. Otherwise we should return 1 to
  247. * indicate that we cannot handle this.
  248. */
  249. if (opcode != 0x82)
  250. return 1;
  251. switch (subopcode) {
  252. case MEGAIOC_QDRVRVER:
  253. if (copy_to_user(kmimd.data, &drvr_ver, sizeof(uint32_t)))
  254. return (-EFAULT);
  255. return 0;
  256. case MEGAIOC_QNADAP:
  257. *rval = adapters_count_g;
  258. if (copy_to_user(kmimd.data, &adapters_count_g,
  259. sizeof(uint32_t)))
  260. return (-EFAULT);
  261. return 0;
  262. default:
  263. /* cannot handle */
  264. return 1;
  265. }
  266. return 0;
  267. }
  268. /**
  269. * mimd_to_kioc - Converter from old to new ioctl format
  270. * @umimd : user space old MIMD IOCTL
  271. * @adp : adapter softstate
  272. * @kioc : kernel space new format IOCTL
  273. *
  274. * Routine to convert MIMD interface IOCTL to new interface IOCTL packet. The
  275. * new packet is in kernel space so that driver can perform operations on it
  276. * freely.
  277. */
  278. static int
  279. mimd_to_kioc(mimd_t __user *umimd, mraid_mmadp_t *adp, uioc_t *kioc)
  280. {
  281. mbox64_t *mbox64;
  282. mbox_t *mbox;
  283. mraid_passthru_t *pthru32;
  284. uint32_t adapno;
  285. uint8_t opcode;
  286. uint8_t subopcode;
  287. mimd_t mimd;
  288. if (copy_from_user(&mimd, umimd, sizeof(mimd_t)))
  289. return (-EFAULT);
  290. /*
  291. * Applications are not allowed to send extd pthru
  292. */
  293. if ((mimd.mbox[0] == MBOXCMD_PASSTHRU64) ||
  294. (mimd.mbox[0] == MBOXCMD_EXTPTHRU))
  295. return (-EINVAL);
  296. opcode = mimd.ui.fcs.opcode;
  297. subopcode = mimd.ui.fcs.subopcode;
  298. adapno = GETADAP(mimd.ui.fcs.adapno);
  299. if (adapno >= adapters_count_g)
  300. return (-ENODEV);
  301. kioc->adapno = adapno;
  302. kioc->mb_type = MBOX_LEGACY;
  303. kioc->app_type = APPTYPE_MIMD;
  304. switch (opcode) {
  305. case 0x82:
  306. if (subopcode == MEGAIOC_QADAPINFO) {
  307. kioc->opcode = GET_ADAP_INFO;
  308. kioc->data_dir = UIOC_RD;
  309. kioc->xferlen = sizeof(mraid_hba_info_t);
  310. if (mraid_mm_attach_buf(adp, kioc, kioc->xferlen))
  311. return (-ENOMEM);
  312. }
  313. else {
  314. con_log(CL_ANN, (KERN_WARNING
  315. "megaraid cmm: Invalid subop\n"));
  316. return (-EINVAL);
  317. }
  318. break;
  319. case 0x81:
  320. kioc->opcode = MBOX_CMD;
  321. kioc->xferlen = mimd.ui.fcs.length;
  322. kioc->user_data_len = kioc->xferlen;
  323. kioc->user_data = mimd.ui.fcs.buffer;
  324. if (mraid_mm_attach_buf(adp, kioc, kioc->xferlen))
  325. return (-ENOMEM);
  326. if (mimd.outlen) kioc->data_dir = UIOC_RD;
  327. if (mimd.inlen) kioc->data_dir |= UIOC_WR;
  328. break;
  329. case 0x80:
  330. kioc->opcode = MBOX_CMD;
  331. kioc->xferlen = (mimd.outlen > mimd.inlen) ?
  332. mimd.outlen : mimd.inlen;
  333. kioc->user_data_len = kioc->xferlen;
  334. kioc->user_data = mimd.data;
  335. if (mraid_mm_attach_buf(adp, kioc, kioc->xferlen))
  336. return (-ENOMEM);
  337. if (mimd.outlen) kioc->data_dir = UIOC_RD;
  338. if (mimd.inlen) kioc->data_dir |= UIOC_WR;
  339. break;
  340. default:
  341. return (-EINVAL);
  342. }
  343. /*
  344. * If driver command, nothing else to do
  345. */
  346. if (opcode == 0x82)
  347. return 0;
  348. /*
  349. * This is a mailbox cmd; copy the mailbox from mimd
  350. */
  351. mbox64 = (mbox64_t *)((unsigned long)kioc->cmdbuf);
  352. mbox = &mbox64->mbox32;
  353. memcpy(mbox, mimd.mbox, 14);
  354. if (mbox->cmd != MBOXCMD_PASSTHRU) { // regular DCMD
  355. mbox->xferaddr = (uint32_t)kioc->buf_paddr;
  356. if (kioc->data_dir & UIOC_WR) {
  357. if (copy_from_user(kioc->buf_vaddr, kioc->user_data,
  358. kioc->xferlen)) {
  359. return (-EFAULT);
  360. }
  361. }
  362. return 0;
  363. }
  364. /*
  365. * This is a regular 32-bit pthru cmd; mbox points to pthru struct.
  366. * Just like in above case, the beginning for memblk is treated as
  367. * a mailbox. The passthru will begin at next 1K boundary. And the
  368. * data will start 1K after that.
  369. */
  370. pthru32 = kioc->pthru32;
  371. kioc->user_pthru = &umimd->pthru;
  372. mbox->xferaddr = (uint32_t)kioc->pthru32_h;
  373. if (copy_from_user(pthru32, kioc->user_pthru,
  374. sizeof(mraid_passthru_t))) {
  375. return (-EFAULT);
  376. }
  377. pthru32->dataxferaddr = kioc->buf_paddr;
  378. if (kioc->data_dir & UIOC_WR) {
  379. if (copy_from_user(kioc->buf_vaddr, kioc->user_data,
  380. pthru32->dataxferlen)) {
  381. return (-EFAULT);
  382. }
  383. }
  384. return 0;
  385. }
  386. /**
  387. * mraid_mm_attch_buf - Attach a free dma buffer for required size
  388. * @adp : Adapter softstate
  389. * @kioc : kioc that the buffer needs to be attached to
  390. * @xferlen : required length for buffer
  391. *
  392. * First we search for a pool with smallest buffer that is >= @xferlen. If
  393. * that pool has no free buffer, we will try for the next bigger size. If none
  394. * is available, we will try to allocate the smallest buffer that is >=
  395. * @xferlen and attach it the pool.
  396. */
  397. static int
  398. mraid_mm_attach_buf(mraid_mmadp_t *adp, uioc_t *kioc, int xferlen)
  399. {
  400. mm_dmapool_t *pool;
  401. int right_pool = -1;
  402. unsigned long flags;
  403. int i;
  404. kioc->pool_index = -1;
  405. kioc->buf_vaddr = NULL;
  406. kioc->buf_paddr = 0;
  407. kioc->free_buf = 0;
  408. /*
  409. * We need xferlen amount of memory. See if we can get it from our
  410. * dma pools. If we don't get exact size, we will try bigger buffer
  411. */
  412. for (i = 0; i < MAX_DMA_POOLS; i++) {
  413. pool = &adp->dma_pool_list[i];
  414. if (xferlen > pool->buf_size)
  415. continue;
  416. if (right_pool == -1)
  417. right_pool = i;
  418. spin_lock_irqsave(&pool->lock, flags);
  419. if (!pool->in_use) {
  420. pool->in_use = 1;
  421. kioc->pool_index = i;
  422. kioc->buf_vaddr = pool->vaddr;
  423. kioc->buf_paddr = pool->paddr;
  424. spin_unlock_irqrestore(&pool->lock, flags);
  425. return 0;
  426. }
  427. else {
  428. spin_unlock_irqrestore(&pool->lock, flags);
  429. continue;
  430. }
  431. }
  432. /*
  433. * If xferlen doesn't match any of our pools, return error
  434. */
  435. if (right_pool == -1)
  436. return -EINVAL;
  437. /*
  438. * We did not get any buffer from the preallocated pool. Let us try
  439. * to allocate one new buffer. NOTE: This is a blocking call.
  440. */
  441. pool = &adp->dma_pool_list[right_pool];
  442. spin_lock_irqsave(&pool->lock, flags);
  443. kioc->pool_index = right_pool;
  444. kioc->free_buf = 1;
  445. kioc->buf_vaddr = pci_pool_alloc(pool->handle, GFP_KERNEL,
  446. &kioc->buf_paddr);
  447. spin_unlock_irqrestore(&pool->lock, flags);
  448. if (!kioc->buf_vaddr)
  449. return -ENOMEM;
  450. return 0;
  451. }
  452. /**
  453. * mraid_mm_alloc_kioc - Returns a uioc_t from free list
  454. * @adp : Adapter softstate for this module
  455. *
  456. * The kioc_semaphore is initialized with number of kioc nodes in the
  457. * free kioc pool. If the kioc pool is empty, this function blocks till
  458. * a kioc becomes free.
  459. */
  460. static uioc_t *
  461. mraid_mm_alloc_kioc(mraid_mmadp_t *adp)
  462. {
  463. uioc_t *kioc;
  464. struct list_head* head;
  465. unsigned long flags;
  466. down(&adp->kioc_semaphore);
  467. spin_lock_irqsave(&adp->kioc_pool_lock, flags);
  468. head = &adp->kioc_pool;
  469. if (list_empty(head)) {
  470. up(&adp->kioc_semaphore);
  471. spin_unlock_irqrestore(&adp->kioc_pool_lock, flags);
  472. con_log(CL_ANN, ("megaraid cmm: kioc list empty!\n"));
  473. return NULL;
  474. }
  475. kioc = list_entry(head->next, uioc_t, list);
  476. list_del_init(&kioc->list);
  477. spin_unlock_irqrestore(&adp->kioc_pool_lock, flags);
  478. memset((caddr_t)(unsigned long)kioc->cmdbuf, 0, sizeof(mbox64_t));
  479. memset((caddr_t) kioc->pthru32, 0, sizeof(mraid_passthru_t));
  480. kioc->buf_vaddr = NULL;
  481. kioc->buf_paddr = 0;
  482. kioc->pool_index =-1;
  483. kioc->free_buf = 0;
  484. kioc->user_data = NULL;
  485. kioc->user_data_len = 0;
  486. kioc->user_pthru = NULL;
  487. kioc->timedout = 0;
  488. return kioc;
  489. }
  490. /**
  491. * mraid_mm_dealloc_kioc - Return kioc to free pool
  492. * @adp : Adapter softstate
  493. * @kioc : uioc_t node to be returned to free pool
  494. */
  495. static void
  496. mraid_mm_dealloc_kioc(mraid_mmadp_t *adp, uioc_t *kioc)
  497. {
  498. mm_dmapool_t *pool;
  499. unsigned long flags;
  500. if (kioc->pool_index != -1) {
  501. pool = &adp->dma_pool_list[kioc->pool_index];
  502. /* This routine may be called in non-isr context also */
  503. spin_lock_irqsave(&pool->lock, flags);
  504. /*
  505. * While attaching the dma buffer, if we didn't get the
  506. * required buffer from the pool, we would have allocated
  507. * it at the run time and set the free_buf flag. We must
  508. * free that buffer. Otherwise, just mark that the buffer is
  509. * not in use
  510. */
  511. if (kioc->free_buf == 1)
  512. pci_pool_free(pool->handle, kioc->buf_vaddr,
  513. kioc->buf_paddr);
  514. else
  515. pool->in_use = 0;
  516. spin_unlock_irqrestore(&pool->lock, flags);
  517. }
  518. /* Return the kioc to the free pool */
  519. spin_lock_irqsave(&adp->kioc_pool_lock, flags);
  520. list_add(&kioc->list, &adp->kioc_pool);
  521. spin_unlock_irqrestore(&adp->kioc_pool_lock, flags);
  522. /* increment the free kioc count */
  523. up(&adp->kioc_semaphore);
  524. return;
  525. }
  526. /**
  527. * lld_ioctl - Routine to issue ioctl to low level drvr
  528. * @adp : The adapter handle
  529. * @kioc : The ioctl packet with kernel addresses
  530. */
  531. static int
  532. lld_ioctl(mraid_mmadp_t *adp, uioc_t *kioc)
  533. {
  534. int rval;
  535. struct timer_list timer;
  536. struct timer_list *tp = NULL;
  537. kioc->status = -ENODATA;
  538. rval = adp->issue_uioc(adp->drvr_data, kioc, IOCTL_ISSUE);
  539. if (rval) return rval;
  540. /*
  541. * Start the timer
  542. */
  543. if (adp->timeout > 0) {
  544. tp = &timer;
  545. init_timer(tp);
  546. tp->function = lld_timedout;
  547. tp->data = (unsigned long)kioc;
  548. tp->expires = jiffies + adp->timeout * HZ;
  549. add_timer(tp);
  550. }
  551. /*
  552. * Wait till the low level driver completes the ioctl. After this
  553. * call, the ioctl either completed successfully or timedout.
  554. */
  555. wait_event(wait_q, (kioc->status != -ENODATA));
  556. if (tp) {
  557. del_timer_sync(tp);
  558. }
  559. /*
  560. * If the command had timedout, we mark the controller offline
  561. * before returning
  562. */
  563. if (kioc->timedout) {
  564. adp->quiescent = 0;
  565. }
  566. return kioc->status;
  567. }
  568. /**
  569. * ioctl_done - callback from the low level driver
  570. * @kioc : completed ioctl packet
  571. */
  572. static void
  573. ioctl_done(uioc_t *kioc)
  574. {
  575. uint32_t adapno;
  576. int iterator;
  577. mraid_mmadp_t* adapter;
  578. /*
  579. * When the kioc returns from driver, make sure it still doesn't
  580. * have ENODATA in status. Otherwise, driver will hang on wait_event
  581. * forever
  582. */
  583. if (kioc->status == -ENODATA) {
  584. con_log(CL_ANN, (KERN_WARNING
  585. "megaraid cmm: lld didn't change status!\n"));
  586. kioc->status = -EINVAL;
  587. }
  588. /*
  589. * Check if this kioc was timedout before. If so, nobody is waiting
  590. * on this kioc. We don't have to wake up anybody. Instead, we just
  591. * have to free the kioc
  592. */
  593. if (kioc->timedout) {
  594. iterator = 0;
  595. adapter = NULL;
  596. adapno = kioc->adapno;
  597. con_log(CL_ANN, ( KERN_WARNING "megaraid cmm: completed "
  598. "ioctl that was timedout before\n"));
  599. list_for_each_entry(adapter, &adapters_list_g, list) {
  600. if (iterator++ == adapno) break;
  601. }
  602. kioc->timedout = 0;
  603. if (adapter) {
  604. mraid_mm_dealloc_kioc( adapter, kioc );
  605. }
  606. }
  607. else {
  608. wake_up(&wait_q);
  609. }
  610. }
  611. /**
  612. * lld_timedout - callback from the expired timer
  613. * @ptr : ioctl packet that timed out
  614. */
  615. static void
  616. lld_timedout(unsigned long ptr)
  617. {
  618. uioc_t *kioc = (uioc_t *)ptr;
  619. kioc->status = -ETIME;
  620. kioc->timedout = 1;
  621. con_log(CL_ANN, (KERN_WARNING "megaraid cmm: ioctl timed out\n"));
  622. wake_up(&wait_q);
  623. }
  624. /**
  625. * kioc_to_mimd - Converter from new back to old format
  626. * @kioc : Kernel space IOCTL packet (successfully issued)
  627. * @mimd : User space MIMD packet
  628. */
  629. static int
  630. kioc_to_mimd(uioc_t *kioc, mimd_t __user *mimd)
  631. {
  632. mimd_t kmimd;
  633. uint8_t opcode;
  634. uint8_t subopcode;
  635. mbox64_t *mbox64;
  636. mraid_passthru_t __user *upthru32;
  637. mraid_passthru_t *kpthru32;
  638. mcontroller_t cinfo;
  639. mraid_hba_info_t *hinfo;
  640. if (copy_from_user(&kmimd, mimd, sizeof(mimd_t)))
  641. return (-EFAULT);
  642. opcode = kmimd.ui.fcs.opcode;
  643. subopcode = kmimd.ui.fcs.subopcode;
  644. if (opcode == 0x82) {
  645. switch (subopcode) {
  646. case MEGAIOC_QADAPINFO:
  647. hinfo = (mraid_hba_info_t *)(unsigned long)
  648. kioc->buf_vaddr;
  649. hinfo_to_cinfo(hinfo, &cinfo);
  650. if (copy_to_user(kmimd.data, &cinfo, sizeof(cinfo)))
  651. return (-EFAULT);
  652. return 0;
  653. default:
  654. return (-EINVAL);
  655. }
  656. return 0;
  657. }
  658. mbox64 = (mbox64_t *)(unsigned long)kioc->cmdbuf;
  659. if (kioc->user_pthru) {
  660. upthru32 = kioc->user_pthru;
  661. kpthru32 = kioc->pthru32;
  662. if (copy_to_user(&upthru32->scsistatus,
  663. &kpthru32->scsistatus,
  664. sizeof(uint8_t))) {
  665. return (-EFAULT);
  666. }
  667. }
  668. if (kioc->user_data) {
  669. if (copy_to_user(kioc->user_data, kioc->buf_vaddr,
  670. kioc->user_data_len)) {
  671. return (-EFAULT);
  672. }
  673. }
  674. if (copy_to_user(&mimd->mbox[17],
  675. &mbox64->mbox32.status, sizeof(uint8_t))) {
  676. return (-EFAULT);
  677. }
  678. return 0;
  679. }
  680. /**
  681. * hinfo_to_cinfo - Convert new format hba info into old format
  682. * @hinfo : New format, more comprehensive adapter info
  683. * @cinfo : Old format adapter info to support mimd_t apps
  684. */
  685. static void
  686. hinfo_to_cinfo(mraid_hba_info_t *hinfo, mcontroller_t *cinfo)
  687. {
  688. if (!hinfo || !cinfo)
  689. return;
  690. cinfo->base = hinfo->baseport;
  691. cinfo->irq = hinfo->irq;
  692. cinfo->numldrv = hinfo->num_ldrv;
  693. cinfo->pcibus = hinfo->pci_bus;
  694. cinfo->pcidev = hinfo->pci_slot;
  695. cinfo->pcifun = PCI_FUNC(hinfo->pci_dev_fn);
  696. cinfo->pciid = hinfo->pci_device_id;
  697. cinfo->pcivendor = hinfo->pci_vendor_id;
  698. cinfo->pcislot = hinfo->pci_slot;
  699. cinfo->uid = hinfo->unique_id;
  700. }
  701. /**
  702. * mraid_mm_register_adp - Registration routine for low level drivers
  703. * @lld_adp : Adapter objejct
  704. */
  705. int
  706. mraid_mm_register_adp(mraid_mmadp_t *lld_adp)
  707. {
  708. mraid_mmadp_t *adapter;
  709. mbox64_t *mbox_list;
  710. uioc_t *kioc;
  711. uint32_t rval;
  712. int i;
  713. if (lld_adp->drvr_type != DRVRTYPE_MBOX)
  714. return (-EINVAL);
  715. adapter = kzalloc(sizeof(mraid_mmadp_t), GFP_KERNEL);
  716. if (!adapter)
  717. return -ENOMEM;
  718. adapter->unique_id = lld_adp->unique_id;
  719. adapter->drvr_type = lld_adp->drvr_type;
  720. adapter->drvr_data = lld_adp->drvr_data;
  721. adapter->pdev = lld_adp->pdev;
  722. adapter->issue_uioc = lld_adp->issue_uioc;
  723. adapter->timeout = lld_adp->timeout;
  724. adapter->max_kioc = lld_adp->max_kioc;
  725. adapter->quiescent = 1;
  726. /*
  727. * Allocate single blocks of memory for all required kiocs,
  728. * mailboxes and passthru structures.
  729. */
  730. adapter->kioc_list = kmalloc(sizeof(uioc_t) * lld_adp->max_kioc,
  731. GFP_KERNEL);
  732. adapter->mbox_list = kmalloc(sizeof(mbox64_t) * lld_adp->max_kioc,
  733. GFP_KERNEL);
  734. adapter->pthru_dma_pool = pci_pool_create("megaraid mm pthru pool",
  735. adapter->pdev,
  736. sizeof(mraid_passthru_t),
  737. 16, 0);
  738. if (!adapter->kioc_list || !adapter->mbox_list ||
  739. !adapter->pthru_dma_pool) {
  740. con_log(CL_ANN, (KERN_WARNING
  741. "megaraid cmm: out of memory, %s %d\n", __func__,
  742. __LINE__));
  743. rval = (-ENOMEM);
  744. goto memalloc_error;
  745. }
  746. /*
  747. * Slice kioc_list and make a kioc_pool with the individiual kiocs
  748. */
  749. INIT_LIST_HEAD(&adapter->kioc_pool);
  750. spin_lock_init(&adapter->kioc_pool_lock);
  751. sema_init(&adapter->kioc_semaphore, lld_adp->max_kioc);
  752. mbox_list = (mbox64_t *)adapter->mbox_list;
  753. for (i = 0; i < lld_adp->max_kioc; i++) {
  754. kioc = adapter->kioc_list + i;
  755. kioc->cmdbuf = (uint64_t)(unsigned long)(mbox_list + i);
  756. kioc->pthru32 = pci_pool_alloc(adapter->pthru_dma_pool,
  757. GFP_KERNEL, &kioc->pthru32_h);
  758. if (!kioc->pthru32) {
  759. con_log(CL_ANN, (KERN_WARNING
  760. "megaraid cmm: out of memory, %s %d\n",
  761. __func__, __LINE__));
  762. rval = (-ENOMEM);
  763. goto pthru_dma_pool_error;
  764. }
  765. list_add_tail(&kioc->list, &adapter->kioc_pool);
  766. }
  767. // Setup the dma pools for data buffers
  768. if ((rval = mraid_mm_setup_dma_pools(adapter)) != 0) {
  769. goto dma_pool_error;
  770. }
  771. list_add_tail(&adapter->list, &adapters_list_g);
  772. adapters_count_g++;
  773. return 0;
  774. dma_pool_error:
  775. /* Do nothing */
  776. pthru_dma_pool_error:
  777. for (i = 0; i < lld_adp->max_kioc; i++) {
  778. kioc = adapter->kioc_list + i;
  779. if (kioc->pthru32) {
  780. pci_pool_free(adapter->pthru_dma_pool, kioc->pthru32,
  781. kioc->pthru32_h);
  782. }
  783. }
  784. memalloc_error:
  785. kfree(adapter->kioc_list);
  786. kfree(adapter->mbox_list);
  787. if (adapter->pthru_dma_pool)
  788. pci_pool_destroy(adapter->pthru_dma_pool);
  789. kfree(adapter);
  790. return rval;
  791. }
  792. /**
  793. * mraid_mm_adapter_app_handle - return the application handle for this adapter
  794. * @unique_id : adapter unique identifier
  795. *
  796. * For the given driver data, locate the adapter in our global list and
  797. * return the corresponding handle, which is also used by applications to
  798. * uniquely identify an adapter.
  799. *
  800. * Return adapter handle if found in the list.
  801. * Return 0 if adapter could not be located, should never happen though.
  802. */
  803. uint32_t
  804. mraid_mm_adapter_app_handle(uint32_t unique_id)
  805. {
  806. mraid_mmadp_t *adapter;
  807. mraid_mmadp_t *tmp;
  808. int index = 0;
  809. list_for_each_entry_safe(adapter, tmp, &adapters_list_g, list) {
  810. if (adapter->unique_id == unique_id) {
  811. return MKADAP(index);
  812. }
  813. index++;
  814. }
  815. return 0;
  816. }
  817. /**
  818. * mraid_mm_setup_dma_pools - Set up dma buffer pools per adapter
  819. * @adp : Adapter softstate
  820. *
  821. * We maintain a pool of dma buffers per each adapter. Each pool has one
  822. * buffer. E.g, we may have 5 dma pools - one each for 4k, 8k ... 64k buffers.
  823. * We have just one 4k buffer in 4k pool, one 8k buffer in 8k pool etc. We
  824. * dont' want to waste too much memory by allocating more buffers per each
  825. * pool.
  826. */
  827. static int
  828. mraid_mm_setup_dma_pools(mraid_mmadp_t *adp)
  829. {
  830. mm_dmapool_t *pool;
  831. int bufsize;
  832. int i;
  833. /*
  834. * Create MAX_DMA_POOLS number of pools
  835. */
  836. bufsize = MRAID_MM_INIT_BUFF_SIZE;
  837. for (i = 0; i < MAX_DMA_POOLS; i++){
  838. pool = &adp->dma_pool_list[i];
  839. pool->buf_size = bufsize;
  840. spin_lock_init(&pool->lock);
  841. pool->handle = pci_pool_create("megaraid mm data buffer",
  842. adp->pdev, bufsize, 16, 0);
  843. if (!pool->handle) {
  844. goto dma_pool_setup_error;
  845. }
  846. pool->vaddr = pci_pool_alloc(pool->handle, GFP_KERNEL,
  847. &pool->paddr);
  848. if (!pool->vaddr)
  849. goto dma_pool_setup_error;
  850. bufsize = bufsize * 2;
  851. }
  852. return 0;
  853. dma_pool_setup_error:
  854. mraid_mm_teardown_dma_pools(adp);
  855. return (-ENOMEM);
  856. }
  857. /**
  858. * mraid_mm_unregister_adp - Unregister routine for low level drivers
  859. * @unique_id : UID of the adpater
  860. *
  861. * Assumes no outstanding ioctls to llds.
  862. */
  863. int
  864. mraid_mm_unregister_adp(uint32_t unique_id)
  865. {
  866. mraid_mmadp_t *adapter;
  867. mraid_mmadp_t *tmp;
  868. list_for_each_entry_safe(adapter, tmp, &adapters_list_g, list) {
  869. if (adapter->unique_id == unique_id) {
  870. adapters_count_g--;
  871. list_del_init(&adapter->list);
  872. mraid_mm_free_adp_resources(adapter);
  873. kfree(adapter);
  874. con_log(CL_ANN, (
  875. "megaraid cmm: Unregistered one adapter:%#x\n",
  876. unique_id));
  877. return 0;
  878. }
  879. }
  880. return (-ENODEV);
  881. }
  882. /**
  883. * mraid_mm_free_adp_resources - Free adapter softstate
  884. * @adp : Adapter softstate
  885. */
  886. static void
  887. mraid_mm_free_adp_resources(mraid_mmadp_t *adp)
  888. {
  889. uioc_t *kioc;
  890. int i;
  891. mraid_mm_teardown_dma_pools(adp);
  892. for (i = 0; i < adp->max_kioc; i++) {
  893. kioc = adp->kioc_list + i;
  894. pci_pool_free(adp->pthru_dma_pool, kioc->pthru32,
  895. kioc->pthru32_h);
  896. }
  897. kfree(adp->kioc_list);
  898. kfree(adp->mbox_list);
  899. pci_pool_destroy(adp->pthru_dma_pool);
  900. return;
  901. }
  902. /**
  903. * mraid_mm_teardown_dma_pools - Free all per adapter dma buffers
  904. * @adp : Adapter softstate
  905. */
  906. static void
  907. mraid_mm_teardown_dma_pools(mraid_mmadp_t *adp)
  908. {
  909. int i;
  910. mm_dmapool_t *pool;
  911. for (i = 0; i < MAX_DMA_POOLS; i++) {
  912. pool = &adp->dma_pool_list[i];
  913. if (pool->handle) {
  914. if (pool->vaddr)
  915. pci_pool_free(pool->handle, pool->vaddr,
  916. pool->paddr);
  917. pci_pool_destroy(pool->handle);
  918. pool->handle = NULL;
  919. }
  920. }
  921. return;
  922. }
  923. /**
  924. * mraid_mm_init - Module entry point
  925. */
  926. static int __init
  927. mraid_mm_init(void)
  928. {
  929. int err;
  930. // Announce the driver version
  931. con_log(CL_ANN, (KERN_INFO "megaraid cmm: %s %s\n",
  932. LSI_COMMON_MOD_VERSION, LSI_COMMON_MOD_EXT_VERSION));
  933. err = misc_register(&megaraid_mm_dev);
  934. if (err < 0) {
  935. con_log(CL_ANN, ("megaraid cmm: cannot register misc device\n"));
  936. return err;
  937. }
  938. init_waitqueue_head(&wait_q);
  939. INIT_LIST_HEAD(&adapters_list_g);
  940. return 0;
  941. }
  942. #ifdef CONFIG_COMPAT
  943. /**
  944. * mraid_mm_compat_ioctl - 32bit to 64bit ioctl conversion routine
  945. * @filep : file operations pointer (ignored)
  946. * @cmd : ioctl command
  947. * @arg : user ioctl packet
  948. */
  949. static long
  950. mraid_mm_compat_ioctl(struct file *filep, unsigned int cmd,
  951. unsigned long arg)
  952. {
  953. int err;
  954. err = mraid_mm_ioctl(NULL, filep, cmd, arg);
  955. return err;
  956. }
  957. #endif
  958. /**
  959. * mraid_mm_exit - Module exit point
  960. */
  961. static void __exit
  962. mraid_mm_exit(void)
  963. {
  964. con_log(CL_DLEVEL1 , ("exiting common mod\n"));
  965. misc_deregister(&megaraid_mm_dev);
  966. }
  967. module_init(mraid_mm_init);
  968. module_exit(mraid_mm_exit);
  969. /* vi: set ts=8 sw=8 tw=78: */