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