Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  *
0004  *          Linux MegaRAID device driver
0005  *
0006  * Copyright (c) 2003-2004  LSI Logic Corporation.
0007  *
0008  * FILE     : megaraid_mm.c
0009  * Version  : v2.20.2.7 (Jul 16 2006)
0010  *
0011  * Common management module
0012  */
0013 #include <linux/sched.h>
0014 #include <linux/slab.h>
0015 #include <linux/mutex.h>
0016 #include "megaraid_mm.h"
0017 
0018 
0019 // Entry points for char node driver
0020 static DEFINE_MUTEX(mraid_mm_mutex);
0021 static int mraid_mm_open(struct inode *, struct file *);
0022 static long mraid_mm_unlocked_ioctl(struct file *, uint, unsigned long);
0023 
0024 
0025 // routines to convert to and from the old the format
0026 static int mimd_to_kioc(mimd_t __user *, mraid_mmadp_t *, uioc_t *);
0027 static int kioc_to_mimd(uioc_t *, mimd_t __user *);
0028 
0029 
0030 // Helper functions
0031 static int handle_drvrcmd(void __user *, uint8_t, int *);
0032 static int lld_ioctl(mraid_mmadp_t *, uioc_t *);
0033 static void ioctl_done(uioc_t *);
0034 static void lld_timedout(struct timer_list *);
0035 static void hinfo_to_cinfo(mraid_hba_info_t *, mcontroller_t *);
0036 static mraid_mmadp_t *mraid_mm_get_adapter(mimd_t __user *, int *);
0037 static uioc_t *mraid_mm_alloc_kioc(mraid_mmadp_t *);
0038 static void mraid_mm_dealloc_kioc(mraid_mmadp_t *, uioc_t *);
0039 static int mraid_mm_attach_buf(mraid_mmadp_t *, uioc_t *, int);
0040 static int mraid_mm_setup_dma_pools(mraid_mmadp_t *);
0041 static void mraid_mm_free_adp_resources(mraid_mmadp_t *);
0042 static void mraid_mm_teardown_dma_pools(mraid_mmadp_t *);
0043 
0044 MODULE_AUTHOR("LSI Logic Corporation");
0045 MODULE_DESCRIPTION("LSI Logic Management Module");
0046 MODULE_LICENSE("GPL");
0047 MODULE_VERSION(LSI_COMMON_MOD_VERSION);
0048 
0049 static int dbglevel = CL_ANN;
0050 module_param_named(dlevel, dbglevel, int, 0);
0051 MODULE_PARM_DESC(dlevel, "Debug level (default=0)");
0052 
0053 EXPORT_SYMBOL(mraid_mm_register_adp);
0054 EXPORT_SYMBOL(mraid_mm_unregister_adp);
0055 EXPORT_SYMBOL(mraid_mm_adapter_app_handle);
0056 
0057 static uint32_t drvr_ver    = 0x02200207;
0058 
0059 static int adapters_count_g;
0060 static struct list_head adapters_list_g;
0061 
0062 static wait_queue_head_t wait_q;
0063 
0064 static const struct file_operations lsi_fops = {
0065     .open   = mraid_mm_open,
0066     .unlocked_ioctl = mraid_mm_unlocked_ioctl,
0067     .compat_ioctl = compat_ptr_ioctl,
0068     .owner  = THIS_MODULE,
0069     .llseek = noop_llseek,
0070 };
0071 
0072 static struct miscdevice megaraid_mm_dev = {
0073     .minor  = MISC_DYNAMIC_MINOR,
0074     .name   = "megadev0",
0075     .fops   = &lsi_fops,
0076 };
0077 
0078 /**
0079  * mraid_mm_open - open routine for char node interface
0080  * @inode   : unused
0081  * @filep   : unused
0082  *
0083  * Allow ioctl operations by apps only if they have superuser privilege.
0084  */
0085 static int
0086 mraid_mm_open(struct inode *inode, struct file *filep)
0087 {
0088     /*
0089      * Only allow superuser to access private ioctl interface
0090      */
0091     if (!capable(CAP_SYS_ADMIN)) return (-EACCES);
0092 
0093     return 0;
0094 }
0095 
0096 /**
0097  * mraid_mm_ioctl - module entry-point for ioctls
0098  * @filep   : file operations pointer (ignored)
0099  * @cmd     : ioctl command
0100  * @arg     : user ioctl packet
0101  */
0102 static int
0103 mraid_mm_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
0104 {
0105     uioc_t      *kioc;
0106     char        signature[EXT_IOCTL_SIGN_SZ]    = {0};
0107     int     rval;
0108     mraid_mmadp_t   *adp;
0109     uint8_t     old_ioctl;
0110     int     drvrcmd_rval;
0111     void __user *argp = (void __user *)arg;
0112 
0113     /*
0114      * Make sure only USCSICMD are issued through this interface.
0115      * MIMD application would still fire different command.
0116      */
0117 
0118     if ((_IOC_TYPE(cmd) != MEGAIOC_MAGIC) && (cmd != USCSICMD)) {
0119         return (-EINVAL);
0120     }
0121 
0122     /*
0123      * Look for signature to see if this is the new or old ioctl format.
0124      */
0125     if (copy_from_user(signature, argp, EXT_IOCTL_SIGN_SZ)) {
0126         con_log(CL_ANN, (KERN_WARNING
0127             "megaraid cmm: copy from usr addr failed\n"));
0128         return (-EFAULT);
0129     }
0130 
0131     if (memcmp(signature, EXT_IOCTL_SIGN, EXT_IOCTL_SIGN_SZ) == 0)
0132         old_ioctl = 0;
0133     else
0134         old_ioctl = 1;
0135 
0136     /*
0137      * At present, we don't support the new ioctl packet
0138      */
0139     if (!old_ioctl )
0140         return (-EINVAL);
0141 
0142     /*
0143      * If it is a driver ioctl (as opposed to fw ioctls), then we can
0144      * handle the command locally. rval > 0 means it is not a drvr cmd
0145      */
0146     rval = handle_drvrcmd(argp, old_ioctl, &drvrcmd_rval);
0147 
0148     if (rval < 0)
0149         return rval;
0150     else if (rval == 0)
0151         return drvrcmd_rval;
0152 
0153     rval = 0;
0154     if ((adp = mraid_mm_get_adapter(argp, &rval)) == NULL) {
0155         return rval;
0156     }
0157 
0158     /*
0159      * Check if adapter can accept ioctl. We may have marked it offline
0160      * if any previous kioc had timedout on this controller.
0161      */
0162     if (!adp->quiescent) {
0163         con_log(CL_ANN, (KERN_WARNING
0164             "megaraid cmm: controller cannot accept cmds due to "
0165             "earlier errors\n" ));
0166         return -EFAULT;
0167     }
0168 
0169     /*
0170      * The following call will block till a kioc is available
0171      * or return NULL if the list head is empty for the pointer
0172      * of type mraid_mmapt passed to mraid_mm_alloc_kioc
0173      */
0174     kioc = mraid_mm_alloc_kioc(adp);
0175     if (!kioc)
0176         return -ENXIO;
0177 
0178     /*
0179      * User sent the old mimd_t ioctl packet. Convert it to uioc_t.
0180      */
0181     if ((rval = mimd_to_kioc(argp, adp, kioc))) {
0182         mraid_mm_dealloc_kioc(adp, kioc);
0183         return rval;
0184     }
0185 
0186     kioc->done = ioctl_done;
0187 
0188     /*
0189      * Issue the IOCTL to the low level driver. After the IOCTL completes
0190      * release the kioc if and only if it was _not_ timedout. If it was
0191      * timedout, that means that resources are still with low level driver.
0192      */
0193     if ((rval = lld_ioctl(adp, kioc))) {
0194 
0195         if (!kioc->timedout)
0196             mraid_mm_dealloc_kioc(adp, kioc);
0197 
0198         return rval;
0199     }
0200 
0201     /*
0202      * Convert the kioc back to user space
0203      */
0204     rval = kioc_to_mimd(kioc, argp);
0205 
0206     /*
0207      * Return the kioc to free pool
0208      */
0209     mraid_mm_dealloc_kioc(adp, kioc);
0210 
0211     return rval;
0212 }
0213 
0214 static long
0215 mraid_mm_unlocked_ioctl(struct file *filep, unsigned int cmd,
0216                 unsigned long arg)
0217 {
0218     int err;
0219 
0220     mutex_lock(&mraid_mm_mutex);
0221     err = mraid_mm_ioctl(filep, cmd, arg);
0222     mutex_unlock(&mraid_mm_mutex);
0223 
0224     return err;
0225 }
0226 
0227 /**
0228  * mraid_mm_get_adapter - Returns corresponding adapters for the mimd packet
0229  * @umimd   : User space mimd_t ioctl packet
0230  * @rval    : returned success/error status
0231  *
0232  * The function return value is a pointer to the located @adapter.
0233  */
0234 static mraid_mmadp_t *
0235 mraid_mm_get_adapter(mimd_t __user *umimd, int *rval)
0236 {
0237     mraid_mmadp_t   *adapter;
0238     mimd_t      mimd;
0239     uint32_t    adapno;
0240     int     iterator;
0241     bool        is_found;
0242 
0243     if (copy_from_user(&mimd, umimd, sizeof(mimd_t))) {
0244         *rval = -EFAULT;
0245         return NULL;
0246     }
0247 
0248     adapno = GETADAP(mimd.ui.fcs.adapno);
0249 
0250     if (adapno >= adapters_count_g) {
0251         *rval = -ENODEV;
0252         return NULL;
0253     }
0254 
0255     adapter = NULL;
0256     iterator = 0;
0257     is_found = false;
0258 
0259     list_for_each_entry(adapter, &adapters_list_g, list) {
0260         if (iterator++ == adapno) {
0261             is_found = true;
0262             break;
0263         }
0264     }
0265 
0266     if (!is_found) {
0267         *rval = -ENODEV;
0268         return NULL;
0269     }
0270 
0271     return adapter;
0272 }
0273 
0274 /**
0275  * handle_drvrcmd - Checks if the opcode is a driver cmd and if it is, handles it.
0276  * @arg     : packet sent by the user app
0277  * @old_ioctl   : mimd if 1; uioc otherwise
0278  * @rval    : pointer for command's returned value (not function status)
0279  */
0280 static int
0281 handle_drvrcmd(void __user *arg, uint8_t old_ioctl, int *rval)
0282 {
0283     mimd_t      __user *umimd;
0284     mimd_t      kmimd;
0285     uint8_t     opcode;
0286     uint8_t     subopcode;
0287 
0288     if (old_ioctl)
0289         goto old_packet;
0290     else
0291         goto new_packet;
0292 
0293 new_packet:
0294     return (-ENOTSUPP);
0295 
0296 old_packet:
0297     *rval = 0;
0298     umimd = arg;
0299 
0300     if (copy_from_user(&kmimd, umimd, sizeof(mimd_t)))
0301         return (-EFAULT);
0302 
0303     opcode      = kmimd.ui.fcs.opcode;
0304     subopcode   = kmimd.ui.fcs.subopcode;
0305 
0306     /*
0307      * If the opcode is 0x82 and the subopcode is either GET_DRVRVER or
0308      * GET_NUMADP, then we can handle. Otherwise we should return 1 to
0309      * indicate that we cannot handle this.
0310      */
0311     if (opcode != 0x82)
0312         return 1;
0313 
0314     switch (subopcode) {
0315 
0316     case MEGAIOC_QDRVRVER:
0317 
0318         if (copy_to_user(kmimd.data, &drvr_ver, sizeof(uint32_t)))
0319             return (-EFAULT);
0320 
0321         return 0;
0322 
0323     case MEGAIOC_QNADAP:
0324 
0325         *rval = adapters_count_g;
0326 
0327         if (copy_to_user(kmimd.data, &adapters_count_g,
0328                 sizeof(uint32_t)))
0329             return (-EFAULT);
0330 
0331         return 0;
0332 
0333     default:
0334         /* cannot handle */
0335         return 1;
0336     }
0337 
0338     return 0;
0339 }
0340 
0341 
0342 /**
0343  * mimd_to_kioc - Converter from old to new ioctl format
0344  * @umimd   : user space old MIMD IOCTL
0345  * @adp     : adapter softstate
0346  * @kioc    : kernel space new format IOCTL
0347  *
0348  * Routine to convert MIMD interface IOCTL to new interface IOCTL packet. The
0349  * new packet is in kernel space so that driver can perform operations on it
0350  * freely.
0351  */
0352 
0353 static int
0354 mimd_to_kioc(mimd_t __user *umimd, mraid_mmadp_t *adp, uioc_t *kioc)
0355 {
0356     mbox64_t        *mbox64;
0357     mbox_t          *mbox;
0358     mraid_passthru_t    *pthru32;
0359     uint32_t        adapno;
0360     uint8_t         opcode;
0361     uint8_t         subopcode;
0362     mimd_t          mimd;
0363 
0364     if (copy_from_user(&mimd, umimd, sizeof(mimd_t)))
0365         return (-EFAULT);
0366 
0367     /*
0368      * Applications are not allowed to send extd pthru
0369      */
0370     if ((mimd.mbox[0] == MBOXCMD_PASSTHRU64) ||
0371             (mimd.mbox[0] == MBOXCMD_EXTPTHRU))
0372         return (-EINVAL);
0373 
0374     opcode      = mimd.ui.fcs.opcode;
0375     subopcode   = mimd.ui.fcs.subopcode;
0376     adapno      = GETADAP(mimd.ui.fcs.adapno);
0377 
0378     if (adapno >= adapters_count_g)
0379         return (-ENODEV);
0380 
0381     kioc->adapno    = adapno;
0382     kioc->mb_type   = MBOX_LEGACY;
0383     kioc->app_type  = APPTYPE_MIMD;
0384 
0385     switch (opcode) {
0386 
0387     case 0x82:
0388 
0389         if (subopcode == MEGAIOC_QADAPINFO) {
0390 
0391             kioc->opcode    = GET_ADAP_INFO;
0392             kioc->data_dir  = UIOC_RD;
0393             kioc->xferlen   = sizeof(mraid_hba_info_t);
0394 
0395             if (mraid_mm_attach_buf(adp, kioc, kioc->xferlen))
0396                 return (-ENOMEM);
0397         }
0398         else {
0399             con_log(CL_ANN, (KERN_WARNING
0400                     "megaraid cmm: Invalid subop\n"));
0401             return (-EINVAL);
0402         }
0403 
0404         break;
0405 
0406     case 0x81:
0407 
0408         kioc->opcode        = MBOX_CMD;
0409         kioc->xferlen       = mimd.ui.fcs.length;
0410         kioc->user_data_len = kioc->xferlen;
0411         kioc->user_data     = mimd.ui.fcs.buffer;
0412 
0413         if (mraid_mm_attach_buf(adp, kioc, kioc->xferlen))
0414             return (-ENOMEM);
0415 
0416         if (mimd.outlen) kioc->data_dir  = UIOC_RD;
0417         if (mimd.inlen) kioc->data_dir |= UIOC_WR;
0418 
0419         break;
0420 
0421     case 0x80:
0422 
0423         kioc->opcode        = MBOX_CMD;
0424         kioc->xferlen       = (mimd.outlen > mimd.inlen) ?
0425                         mimd.outlen : mimd.inlen;
0426         kioc->user_data_len = kioc->xferlen;
0427         kioc->user_data     = mimd.data;
0428 
0429         if (mraid_mm_attach_buf(adp, kioc, kioc->xferlen))
0430             return (-ENOMEM);
0431 
0432         if (mimd.outlen) kioc->data_dir  = UIOC_RD;
0433         if (mimd.inlen) kioc->data_dir |= UIOC_WR;
0434 
0435         break;
0436 
0437     default:
0438         return (-EINVAL);
0439     }
0440 
0441     /*
0442      * If driver command, nothing else to do
0443      */
0444     if (opcode == 0x82)
0445         return 0;
0446 
0447     /*
0448      * This is a mailbox cmd; copy the mailbox from mimd
0449      */
0450     mbox64  = (mbox64_t *)((unsigned long)kioc->cmdbuf);
0451     mbox    = &mbox64->mbox32;
0452     memcpy(mbox, mimd.mbox, 14);
0453 
0454     if (mbox->cmd != MBOXCMD_PASSTHRU) {    // regular DCMD
0455 
0456         mbox->xferaddr  = (uint32_t)kioc->buf_paddr;
0457 
0458         if (kioc->data_dir & UIOC_WR) {
0459             if (copy_from_user(kioc->buf_vaddr, kioc->user_data,
0460                             kioc->xferlen)) {
0461                 return (-EFAULT);
0462             }
0463         }
0464 
0465         return 0;
0466     }
0467 
0468     /*
0469      * This is a regular 32-bit pthru cmd; mbox points to pthru struct.
0470      * Just like in above case, the beginning for memblk is treated as
0471      * a mailbox. The passthru will begin at next 1K boundary. And the
0472      * data will start 1K after that.
0473      */
0474     pthru32         = kioc->pthru32;
0475     kioc->user_pthru    = &umimd->pthru;
0476     mbox->xferaddr      = (uint32_t)kioc->pthru32_h;
0477 
0478     if (copy_from_user(pthru32, kioc->user_pthru,
0479             sizeof(mraid_passthru_t))) {
0480         return (-EFAULT);
0481     }
0482 
0483     pthru32->dataxferaddr   = kioc->buf_paddr;
0484     if (kioc->data_dir & UIOC_WR) {
0485         if (pthru32->dataxferlen > kioc->xferlen)
0486             return -EINVAL;
0487         if (copy_from_user(kioc->buf_vaddr, kioc->user_data,
0488                         pthru32->dataxferlen)) {
0489             return (-EFAULT);
0490         }
0491     }
0492 
0493     return 0;
0494 }
0495 
0496 /**
0497  * mraid_mm_attach_buf - Attach a free dma buffer for required size
0498  * @adp     : Adapter softstate
0499  * @kioc    : kioc that the buffer needs to be attached to
0500  * @xferlen : required length for buffer
0501  *
0502  * First we search for a pool with smallest buffer that is >= @xferlen. If
0503  * that pool has no free buffer, we will try for the next bigger size. If none
0504  * is available, we will try to allocate the smallest buffer that is >=
0505  * @xferlen and attach it the pool.
0506  */
0507 static int
0508 mraid_mm_attach_buf(mraid_mmadp_t *adp, uioc_t *kioc, int xferlen)
0509 {
0510     mm_dmapool_t    *pool;
0511     int     right_pool = -1;
0512     unsigned long   flags;
0513     int     i;
0514 
0515     kioc->pool_index    = -1;
0516     kioc->buf_vaddr     = NULL;
0517     kioc->buf_paddr     = 0;
0518     kioc->free_buf      = 0;
0519 
0520     /*
0521      * We need xferlen amount of memory. See if we can get it from our
0522      * dma pools. If we don't get exact size, we will try bigger buffer
0523      */
0524 
0525     for (i = 0; i < MAX_DMA_POOLS; i++) {
0526 
0527         pool = &adp->dma_pool_list[i];
0528 
0529         if (xferlen > pool->buf_size)
0530             continue;
0531 
0532         if (right_pool == -1)
0533             right_pool = i;
0534 
0535         spin_lock_irqsave(&pool->lock, flags);
0536 
0537         if (!pool->in_use) {
0538 
0539             pool->in_use        = 1;
0540             kioc->pool_index    = i;
0541             kioc->buf_vaddr     = pool->vaddr;
0542             kioc->buf_paddr     = pool->paddr;
0543 
0544             spin_unlock_irqrestore(&pool->lock, flags);
0545             return 0;
0546         }
0547         else {
0548             spin_unlock_irqrestore(&pool->lock, flags);
0549             continue;
0550         }
0551     }
0552 
0553     /*
0554      * If xferlen doesn't match any of our pools, return error
0555      */
0556     if (right_pool == -1)
0557         return -EINVAL;
0558 
0559     /*
0560      * We did not get any buffer from the preallocated pool. Let us try
0561      * to allocate one new buffer. NOTE: This is a blocking call.
0562      */
0563     pool = &adp->dma_pool_list[right_pool];
0564 
0565     spin_lock_irqsave(&pool->lock, flags);
0566 
0567     kioc->pool_index    = right_pool;
0568     kioc->free_buf      = 1;
0569     kioc->buf_vaddr     = dma_pool_alloc(pool->handle, GFP_ATOMIC,
0570                             &kioc->buf_paddr);
0571     spin_unlock_irqrestore(&pool->lock, flags);
0572 
0573     if (!kioc->buf_vaddr)
0574         return -ENOMEM;
0575 
0576     return 0;
0577 }
0578 
0579 /**
0580  * mraid_mm_alloc_kioc - Returns a uioc_t from free list
0581  * @adp : Adapter softstate for this module
0582  *
0583  * The kioc_semaphore is initialized with number of kioc nodes in the
0584  * free kioc pool. If the kioc pool is empty, this function blocks till
0585  * a kioc becomes free.
0586  */
0587 static uioc_t *
0588 mraid_mm_alloc_kioc(mraid_mmadp_t *adp)
0589 {
0590     uioc_t          *kioc;
0591     struct list_head*   head;
0592     unsigned long       flags;
0593 
0594     down(&adp->kioc_semaphore);
0595 
0596     spin_lock_irqsave(&adp->kioc_pool_lock, flags);
0597 
0598     head = &adp->kioc_pool;
0599 
0600     if (list_empty(head)) {
0601         up(&adp->kioc_semaphore);
0602         spin_unlock_irqrestore(&adp->kioc_pool_lock, flags);
0603 
0604         con_log(CL_ANN, ("megaraid cmm: kioc list empty!\n"));
0605         return NULL;
0606     }
0607 
0608     kioc = list_entry(head->next, uioc_t, list);
0609     list_del_init(&kioc->list);
0610 
0611     spin_unlock_irqrestore(&adp->kioc_pool_lock, flags);
0612 
0613     memset((caddr_t)(unsigned long)kioc->cmdbuf, 0, sizeof(mbox64_t));
0614     memset((caddr_t) kioc->pthru32, 0, sizeof(mraid_passthru_t));
0615 
0616     kioc->buf_vaddr     = NULL;
0617     kioc->buf_paddr     = 0;
0618     kioc->pool_index    =-1;
0619     kioc->free_buf      = 0;
0620     kioc->user_data     = NULL;
0621     kioc->user_data_len = 0;
0622     kioc->user_pthru    = NULL;
0623     kioc->timedout      = 0;
0624 
0625     return kioc;
0626 }
0627 
0628 /**
0629  * mraid_mm_dealloc_kioc - Return kioc to free pool
0630  * @adp     : Adapter softstate
0631  * @kioc    : uioc_t node to be returned to free pool
0632  */
0633 static void
0634 mraid_mm_dealloc_kioc(mraid_mmadp_t *adp, uioc_t *kioc)
0635 {
0636     mm_dmapool_t    *pool;
0637     unsigned long   flags;
0638 
0639     if (kioc->pool_index != -1) {
0640         pool = &adp->dma_pool_list[kioc->pool_index];
0641 
0642         /* This routine may be called in non-isr context also */
0643         spin_lock_irqsave(&pool->lock, flags);
0644 
0645         /*
0646          * While attaching the dma buffer, if we didn't get the 
0647          * required buffer from the pool, we would have allocated 
0648          * it at the run time and set the free_buf flag. We must 
0649          * free that buffer. Otherwise, just mark that the buffer is 
0650          * not in use
0651          */
0652         if (kioc->free_buf == 1)
0653             dma_pool_free(pool->handle, kioc->buf_vaddr, 
0654                             kioc->buf_paddr);
0655         else
0656             pool->in_use = 0;
0657 
0658         spin_unlock_irqrestore(&pool->lock, flags);
0659     }
0660 
0661     /* Return the kioc to the free pool */
0662     spin_lock_irqsave(&adp->kioc_pool_lock, flags);
0663     list_add(&kioc->list, &adp->kioc_pool);
0664     spin_unlock_irqrestore(&adp->kioc_pool_lock, flags);
0665 
0666     /* increment the free kioc count */
0667     up(&adp->kioc_semaphore);
0668 
0669     return;
0670 }
0671 
0672 /**
0673  * lld_ioctl - Routine to issue ioctl to low level drvr
0674  * @adp     : The adapter handle
0675  * @kioc    : The ioctl packet with kernel addresses
0676  */
0677 static int
0678 lld_ioctl(mraid_mmadp_t *adp, uioc_t *kioc)
0679 {
0680     int         rval;
0681     struct uioc_timeout timeout = { };
0682 
0683     kioc->status    = -ENODATA;
0684     rval        = adp->issue_uioc(adp->drvr_data, kioc, IOCTL_ISSUE);
0685 
0686     if (rval) return rval;
0687 
0688     /*
0689      * Start the timer
0690      */
0691     if (adp->timeout > 0) {
0692         timeout.uioc = kioc;
0693         timer_setup_on_stack(&timeout.timer, lld_timedout, 0);
0694 
0695         timeout.timer.expires   = jiffies + adp->timeout * HZ;
0696 
0697         add_timer(&timeout.timer);
0698     }
0699 
0700     /*
0701      * Wait till the low level driver completes the ioctl. After this
0702      * call, the ioctl either completed successfully or timedout.
0703      */
0704     wait_event(wait_q, (kioc->status != -ENODATA));
0705     if (timeout.timer.function) {
0706         del_timer_sync(&timeout.timer);
0707         destroy_timer_on_stack(&timeout.timer);
0708     }
0709 
0710     /*
0711      * If the command had timedout, we mark the controller offline
0712      * before returning
0713      */
0714     if (kioc->timedout) {
0715         adp->quiescent = 0;
0716     }
0717 
0718     return kioc->status;
0719 }
0720 
0721 
0722 /**
0723  * ioctl_done - callback from the low level driver
0724  * @kioc    : completed ioctl packet
0725  */
0726 static void
0727 ioctl_done(uioc_t *kioc)
0728 {
0729     uint32_t    adapno;
0730     int     iterator;
0731     mraid_mmadp_t*  adapter;
0732     bool        is_found;
0733 
0734     /*
0735      * When the kioc returns from driver, make sure it still doesn't
0736      * have ENODATA in status. Otherwise, driver will hang on wait_event
0737      * forever
0738      */
0739     if (kioc->status == -ENODATA) {
0740         con_log(CL_ANN, (KERN_WARNING
0741             "megaraid cmm: lld didn't change status!\n"));
0742 
0743         kioc->status = -EINVAL;
0744     }
0745 
0746     /*
0747      * Check if this kioc was timedout before. If so, nobody is waiting
0748      * on this kioc. We don't have to wake up anybody. Instead, we just
0749      * have to free the kioc
0750      */
0751     if (kioc->timedout) {
0752         iterator    = 0;
0753         adapter     = NULL;
0754         adapno      = kioc->adapno;
0755         is_found    = false;
0756 
0757         con_log(CL_ANN, ( KERN_WARNING "megaraid cmm: completed "
0758                     "ioctl that was timedout before\n"));
0759 
0760         list_for_each_entry(adapter, &adapters_list_g, list) {
0761             if (iterator++ == adapno) {
0762                 is_found = true;
0763                 break;
0764             }
0765         }
0766 
0767         kioc->timedout = 0;
0768 
0769         if (is_found)
0770             mraid_mm_dealloc_kioc( adapter, kioc );
0771 
0772     }
0773     else {
0774         wake_up(&wait_q);
0775     }
0776 }
0777 
0778 
0779 /**
0780  * lld_timedout - callback from the expired timer
0781  * @t       : timer that timed out
0782  */
0783 static void
0784 lld_timedout(struct timer_list *t)
0785 {
0786     struct uioc_timeout *timeout = from_timer(timeout, t, timer);
0787     uioc_t *kioc    = timeout->uioc;
0788 
0789     kioc->status    = -ETIME;
0790     kioc->timedout  = 1;
0791 
0792     con_log(CL_ANN, (KERN_WARNING "megaraid cmm: ioctl timed out\n"));
0793 
0794     wake_up(&wait_q);
0795 }
0796 
0797 
0798 /**
0799  * kioc_to_mimd - Converter from new back to old format
0800  * @kioc    : Kernel space IOCTL packet (successfully issued)
0801  * @mimd    : User space MIMD packet
0802  */
0803 static int
0804 kioc_to_mimd(uioc_t *kioc, mimd_t __user *mimd)
0805 {
0806     mimd_t          kmimd;
0807     uint8_t         opcode;
0808     uint8_t         subopcode;
0809 
0810     mbox64_t        *mbox64;
0811     mraid_passthru_t    __user *upthru32;
0812     mraid_passthru_t    *kpthru32;
0813     mcontroller_t       cinfo;
0814     mraid_hba_info_t    *hinfo;
0815 
0816 
0817     if (copy_from_user(&kmimd, mimd, sizeof(mimd_t)))
0818         return (-EFAULT);
0819 
0820     opcode      = kmimd.ui.fcs.opcode;
0821     subopcode   = kmimd.ui.fcs.subopcode;
0822 
0823     if (opcode == 0x82) {
0824         switch (subopcode) {
0825 
0826         case MEGAIOC_QADAPINFO:
0827 
0828             hinfo = (mraid_hba_info_t *)(unsigned long)
0829                     kioc->buf_vaddr;
0830 
0831             hinfo_to_cinfo(hinfo, &cinfo);
0832 
0833             if (copy_to_user(kmimd.data, &cinfo, sizeof(cinfo)))
0834                 return (-EFAULT);
0835 
0836             return 0;
0837 
0838         default:
0839             return (-EINVAL);
0840         }
0841 
0842         return 0;
0843     }
0844 
0845     mbox64 = (mbox64_t *)(unsigned long)kioc->cmdbuf;
0846 
0847     if (kioc->user_pthru) {
0848 
0849         upthru32 = kioc->user_pthru;
0850         kpthru32 = kioc->pthru32;
0851 
0852         if (copy_to_user(&upthru32->scsistatus,
0853                     &kpthru32->scsistatus,
0854                     sizeof(uint8_t))) {
0855             return (-EFAULT);
0856         }
0857     }
0858 
0859     if (kioc->user_data) {
0860         if (copy_to_user(kioc->user_data, kioc->buf_vaddr,
0861                     kioc->user_data_len)) {
0862             return (-EFAULT);
0863         }
0864     }
0865 
0866     if (copy_to_user(&mimd->mbox[17],
0867             &mbox64->mbox32.status, sizeof(uint8_t))) {
0868         return (-EFAULT);
0869     }
0870 
0871     return 0;
0872 }
0873 
0874 
0875 /**
0876  * hinfo_to_cinfo - Convert new format hba info into old format
0877  * @hinfo   : New format, more comprehensive adapter info
0878  * @cinfo   : Old format adapter info to support mimd_t apps
0879  */
0880 static void
0881 hinfo_to_cinfo(mraid_hba_info_t *hinfo, mcontroller_t *cinfo)
0882 {
0883     if (!hinfo || !cinfo)
0884         return;
0885 
0886     cinfo->base     = hinfo->baseport;
0887     cinfo->irq      = hinfo->irq;
0888     cinfo->numldrv      = hinfo->num_ldrv;
0889     cinfo->pcibus       = hinfo->pci_bus;
0890     cinfo->pcidev       = hinfo->pci_slot;
0891     cinfo->pcifun       = PCI_FUNC(hinfo->pci_dev_fn);
0892     cinfo->pciid        = hinfo->pci_device_id;
0893     cinfo->pcivendor    = hinfo->pci_vendor_id;
0894     cinfo->pcislot      = hinfo->pci_slot;
0895     cinfo->uid      = hinfo->unique_id;
0896 }
0897 
0898 
0899 /**
0900  * mraid_mm_register_adp - Registration routine for low level drivers
0901  * @lld_adp : Adapter object
0902  */
0903 int
0904 mraid_mm_register_adp(mraid_mmadp_t *lld_adp)
0905 {
0906     mraid_mmadp_t   *adapter;
0907     mbox64_t    *mbox_list;
0908     uioc_t      *kioc;
0909     uint32_t    rval;
0910     int     i;
0911 
0912 
0913     if (lld_adp->drvr_type != DRVRTYPE_MBOX)
0914         return (-EINVAL);
0915 
0916     adapter = kzalloc(sizeof(mraid_mmadp_t), GFP_KERNEL);
0917 
0918     if (!adapter)
0919         return -ENOMEM;
0920 
0921 
0922     adapter->unique_id  = lld_adp->unique_id;
0923     adapter->drvr_type  = lld_adp->drvr_type;
0924     adapter->drvr_data  = lld_adp->drvr_data;
0925     adapter->pdev       = lld_adp->pdev;
0926     adapter->issue_uioc = lld_adp->issue_uioc;
0927     adapter->timeout    = lld_adp->timeout;
0928     adapter->max_kioc   = lld_adp->max_kioc;
0929     adapter->quiescent  = 1;
0930 
0931     /*
0932      * Allocate single blocks of memory for all required kiocs,
0933      * mailboxes and passthru structures.
0934      */
0935     adapter->kioc_list  = kmalloc_array(lld_adp->max_kioc,
0936                           sizeof(uioc_t),
0937                           GFP_KERNEL);
0938     adapter->mbox_list  = kmalloc_array(lld_adp->max_kioc,
0939                           sizeof(mbox64_t),
0940                           GFP_KERNEL);
0941     adapter->pthru_dma_pool = dma_pool_create("megaraid mm pthru pool",
0942                         &adapter->pdev->dev,
0943                         sizeof(mraid_passthru_t),
0944                         16, 0);
0945 
0946     if (!adapter->kioc_list || !adapter->mbox_list ||
0947             !adapter->pthru_dma_pool) {
0948 
0949         con_log(CL_ANN, (KERN_WARNING
0950             "megaraid cmm: out of memory, %s %d\n", __func__,
0951             __LINE__));
0952 
0953         rval = (-ENOMEM);
0954 
0955         goto memalloc_error;
0956     }
0957 
0958     /*
0959      * Slice kioc_list and make a kioc_pool with the individiual kiocs
0960      */
0961     INIT_LIST_HEAD(&adapter->kioc_pool);
0962     spin_lock_init(&adapter->kioc_pool_lock);
0963     sema_init(&adapter->kioc_semaphore, lld_adp->max_kioc);
0964 
0965     mbox_list   = (mbox64_t *)adapter->mbox_list;
0966 
0967     for (i = 0; i < lld_adp->max_kioc; i++) {
0968 
0969         kioc        = adapter->kioc_list + i;
0970         kioc->cmdbuf    = (uint64_t)(unsigned long)(mbox_list + i);
0971         kioc->pthru32   = dma_pool_alloc(adapter->pthru_dma_pool,
0972                         GFP_KERNEL, &kioc->pthru32_h);
0973 
0974         if (!kioc->pthru32) {
0975 
0976             con_log(CL_ANN, (KERN_WARNING
0977                 "megaraid cmm: out of memory, %s %d\n",
0978                     __func__, __LINE__));
0979 
0980             rval = (-ENOMEM);
0981 
0982             goto pthru_dma_pool_error;
0983         }
0984 
0985         list_add_tail(&kioc->list, &adapter->kioc_pool);
0986     }
0987 
0988     // Setup the dma pools for data buffers
0989     if ((rval = mraid_mm_setup_dma_pools(adapter)) != 0) {
0990         goto dma_pool_error;
0991     }
0992 
0993     list_add_tail(&adapter->list, &adapters_list_g);
0994 
0995     adapters_count_g++;
0996 
0997     return 0;
0998 
0999 dma_pool_error:
1000     /* Do nothing */
1001 
1002 pthru_dma_pool_error:
1003 
1004     for (i = 0; i < lld_adp->max_kioc; i++) {
1005         kioc = adapter->kioc_list + i;
1006         if (kioc->pthru32) {
1007             dma_pool_free(adapter->pthru_dma_pool, kioc->pthru32,
1008                 kioc->pthru32_h);
1009         }
1010     }
1011 
1012 memalloc_error:
1013 
1014     kfree(adapter->kioc_list);
1015     kfree(adapter->mbox_list);
1016 
1017     dma_pool_destroy(adapter->pthru_dma_pool);
1018 
1019     kfree(adapter);
1020 
1021     return rval;
1022 }
1023 
1024 
1025 /**
1026  * mraid_mm_adapter_app_handle - return the application handle for this adapter
1027  * @unique_id   : adapter unique identifier
1028  *
1029  * For the given driver data, locate the adapter in our global list and
1030  * return the corresponding handle, which is also used by applications to
1031  * uniquely identify an adapter.
1032  *
1033  * Return adapter handle if found in the list.
1034  * Return 0 if adapter could not be located, should never happen though.
1035  */
1036 uint32_t
1037 mraid_mm_adapter_app_handle(uint32_t unique_id)
1038 {
1039     mraid_mmadp_t   *adapter;
1040     mraid_mmadp_t   *tmp;
1041     int     index = 0;
1042 
1043     list_for_each_entry_safe(adapter, tmp, &adapters_list_g, list) {
1044 
1045         if (adapter->unique_id == unique_id) {
1046 
1047             return MKADAP(index);
1048         }
1049 
1050         index++;
1051     }
1052 
1053     return 0;
1054 }
1055 
1056 
1057 /**
1058  * mraid_mm_setup_dma_pools - Set up dma buffer pools per adapter
1059  * @adp : Adapter softstate
1060  *
1061  * We maintain a pool of dma buffers per each adapter. Each pool has one
1062  * buffer. E.g, we may have 5 dma pools - one each for 4k, 8k ... 64k buffers.
1063  * We have just one 4k buffer in 4k pool, one 8k buffer in 8k pool etc. We
1064  * dont' want to waste too much memory by allocating more buffers per each
1065  * pool.
1066  */
1067 static int
1068 mraid_mm_setup_dma_pools(mraid_mmadp_t *adp)
1069 {
1070     mm_dmapool_t    *pool;
1071     int     bufsize;
1072     int     i;
1073 
1074     /*
1075      * Create MAX_DMA_POOLS number of pools
1076      */
1077     bufsize = MRAID_MM_INIT_BUFF_SIZE;
1078 
1079     for (i = 0; i < MAX_DMA_POOLS; i++){
1080 
1081         pool = &adp->dma_pool_list[i];
1082 
1083         pool->buf_size = bufsize;
1084         spin_lock_init(&pool->lock);
1085 
1086         pool->handle = dma_pool_create("megaraid mm data buffer",
1087                         &adp->pdev->dev, bufsize,
1088                         16, 0);
1089 
1090         if (!pool->handle) {
1091             goto dma_pool_setup_error;
1092         }
1093 
1094         pool->vaddr = dma_pool_alloc(pool->handle, GFP_KERNEL,
1095                             &pool->paddr);
1096 
1097         if (!pool->vaddr)
1098             goto dma_pool_setup_error;
1099 
1100         bufsize = bufsize * 2;
1101     }
1102 
1103     return 0;
1104 
1105 dma_pool_setup_error:
1106 
1107     mraid_mm_teardown_dma_pools(adp);
1108     return (-ENOMEM);
1109 }
1110 
1111 
1112 /**
1113  * mraid_mm_unregister_adp - Unregister routine for low level drivers
1114  * @unique_id   : UID of the adpater
1115  *
1116  * Assumes no outstanding ioctls to llds.
1117  */
1118 int
1119 mraid_mm_unregister_adp(uint32_t unique_id)
1120 {
1121     mraid_mmadp_t   *adapter;
1122     mraid_mmadp_t   *tmp;
1123 
1124     list_for_each_entry_safe(adapter, tmp, &adapters_list_g, list) {
1125 
1126 
1127         if (adapter->unique_id == unique_id) {
1128 
1129             adapters_count_g--;
1130 
1131             list_del_init(&adapter->list);
1132 
1133             mraid_mm_free_adp_resources(adapter);
1134 
1135             kfree(adapter);
1136 
1137             con_log(CL_ANN, (
1138                 "megaraid cmm: Unregistered one adapter:%#x\n",
1139                 unique_id));
1140 
1141             return 0;
1142         }
1143     }
1144 
1145     return (-ENODEV);
1146 }
1147 
1148 /**
1149  * mraid_mm_free_adp_resources - Free adapter softstate
1150  * @adp : Adapter softstate
1151  */
1152 static void
1153 mraid_mm_free_adp_resources(mraid_mmadp_t *adp)
1154 {
1155     uioc_t  *kioc;
1156     int i;
1157 
1158     mraid_mm_teardown_dma_pools(adp);
1159 
1160     for (i = 0; i < adp->max_kioc; i++) {
1161 
1162         kioc = adp->kioc_list + i;
1163 
1164         dma_pool_free(adp->pthru_dma_pool, kioc->pthru32,
1165                 kioc->pthru32_h);
1166     }
1167 
1168     kfree(adp->kioc_list);
1169     kfree(adp->mbox_list);
1170 
1171     dma_pool_destroy(adp->pthru_dma_pool);
1172 
1173 
1174     return;
1175 }
1176 
1177 
1178 /**
1179  * mraid_mm_teardown_dma_pools - Free all per adapter dma buffers
1180  * @adp : Adapter softstate
1181  */
1182 static void
1183 mraid_mm_teardown_dma_pools(mraid_mmadp_t *adp)
1184 {
1185     int     i;
1186     mm_dmapool_t    *pool;
1187 
1188     for (i = 0; i < MAX_DMA_POOLS; i++) {
1189 
1190         pool = &adp->dma_pool_list[i];
1191 
1192         if (pool->handle) {
1193 
1194             if (pool->vaddr)
1195                 dma_pool_free(pool->handle, pool->vaddr,
1196                             pool->paddr);
1197 
1198             dma_pool_destroy(pool->handle);
1199             pool->handle = NULL;
1200         }
1201     }
1202 
1203     return;
1204 }
1205 
1206 /**
1207  * mraid_mm_init    - Module entry point
1208  */
1209 static int __init
1210 mraid_mm_init(void)
1211 {
1212     int err;
1213 
1214     // Announce the driver version
1215     con_log(CL_ANN, (KERN_INFO "megaraid cmm: %s %s\n",
1216         LSI_COMMON_MOD_VERSION, LSI_COMMON_MOD_EXT_VERSION));
1217 
1218     err = misc_register(&megaraid_mm_dev);
1219     if (err < 0) {
1220         con_log(CL_ANN, ("megaraid cmm: cannot register misc device\n"));
1221         return err;
1222     }
1223 
1224     init_waitqueue_head(&wait_q);
1225 
1226     INIT_LIST_HEAD(&adapters_list_g);
1227 
1228     return 0;
1229 }
1230 
1231 
1232 /**
1233  * mraid_mm_exit    - Module exit point
1234  */
1235 static void __exit
1236 mraid_mm_exit(void)
1237 {
1238     con_log(CL_DLEVEL1 , ("exiting common mod\n"));
1239 
1240     misc_deregister(&megaraid_mm_dev);
1241 }
1242 
1243 module_init(mraid_mm_init);
1244 module_exit(mraid_mm_exit);
1245 
1246 /* vi: set ts=8 sw=8 tw=78: */