17 #include <linux/sched.h>
18 #include <linux/slab.h>
25 static int mraid_mm_open(
struct inode *,
struct file *);
26 static long mraid_mm_unlocked_ioctl(
struct file *,
uint,
unsigned long);
30 static int mimd_to_kioc(mimd_t __user *,
mraid_mmadp_t *, uioc_t *);
31 static int kioc_to_mimd(uioc_t *, mimd_t __user *);
35 static int handle_drvrcmd(
void __user *,
uint8_t,
int *);
37 static void ioctl_done(uioc_t *);
38 static void lld_timedout(
unsigned long);
39 static void hinfo_to_cinfo(mraid_hba_info_t *, mcontroller_t *);
40 static mraid_mmadp_t *mraid_mm_get_adapter(mimd_t __user *,
int *);
43 static int mraid_mm_attach_buf(
mraid_mmadp_t *, uioc_t *,
int);
49 static long mraid_mm_compat_ioctl(
struct file *,
unsigned int,
unsigned long);
57 static int dbglevel =
CL_ANN;
65 static uint32_t drvr_ver = 0x02200207;
67 static int adapters_count_g;
73 .open = mraid_mm_open,
74 .unlocked_ioctl = mraid_mm_unlocked_ioctl,
76 .compat_ioctl = mraid_mm_compat_ioctl,
114 mraid_mm_ioctl(
struct file *filep,
unsigned int cmd,
unsigned long arg)
138 "megaraid cmm: copy from usr addr failed\n"));
157 rval = handle_drvrcmd(argp, old_ioctl, &drvrcmd_rval);
165 if ((adp = mraid_mm_get_adapter(argp, &rval)) ==
NULL) {
175 "megaraid cmm: controller cannot accept cmds due to "
176 "earlier errors\n" ));
183 kioc = mraid_mm_alloc_kioc(adp);
188 if ((rval = mimd_to_kioc(argp, adp, kioc))) {
189 mraid_mm_dealloc_kioc(adp, kioc);
193 kioc->done = ioctl_done;
200 if ((rval = lld_ioctl(adp, kioc))) {
203 mraid_mm_dealloc_kioc(adp, kioc);
211 rval = kioc_to_mimd(kioc, argp);
216 mraid_mm_dealloc_kioc(adp, kioc);
222 mraid_mm_unlocked_ioctl(
struct file *filep,
unsigned int cmd,
229 err = mraid_mm_ioctl(filep, cmd, arg);
243 mraid_mm_get_adapter(mimd_t __user *umimd,
int *rval)
256 adapno =
GETADAP(mimd.ui.fcs.adapno);
258 if (adapno >= adapters_count_g) {
267 if (iterator++ == adapno)
break;
285 handle_drvrcmd(
void __user *arg,
uint8_t old_ioctl,
int *rval)
307 opcode = kmimd.ui.fcs.opcode;
308 subopcode = kmimd.ui.fcs.subopcode;
329 *rval = adapters_count_g;
358 mimd_to_kioc(mimd_t __user *umimd,
mraid_mmadp_t *adp, uioc_t *kioc)
378 opcode = mimd.ui.fcs.opcode;
379 subopcode = mimd.ui.fcs.subopcode;
380 adapno =
GETADAP(mimd.ui.fcs.adapno);
382 if (adapno >= adapters_count_g)
397 kioc->xferlen =
sizeof(mraid_hba_info_t);
399 if (mraid_mm_attach_buf(adp, kioc, kioc->xferlen))
404 "megaraid cmm: Invalid subop\n"));
413 kioc->xferlen = mimd.ui.fcs.length;
414 kioc->user_data_len = kioc->xferlen;
415 kioc->user_data = mimd.ui.fcs.buffer;
417 if (mraid_mm_attach_buf(adp, kioc, kioc->xferlen))
420 if (mimd.outlen) kioc->data_dir =
UIOC_RD;
421 if (mimd.inlen) kioc->data_dir |=
UIOC_WR;
428 kioc->xferlen = (mimd.outlen > mimd.inlen) ?
429 mimd.outlen : mimd.inlen;
430 kioc->user_data_len = kioc->xferlen;
431 kioc->user_data = mimd.data;
433 if (mraid_mm_attach_buf(adp, kioc, kioc->xferlen))
436 if (mimd.outlen) kioc->data_dir =
UIOC_RD;
437 if (mimd.inlen) kioc->data_dir |=
UIOC_WR;
454 mbox64 = (mbox64_t *)((
unsigned long)kioc->cmdbuf);
455 mbox = &mbox64->mbox32;
456 memcpy(mbox, mimd.mbox, 14);
460 mbox->xferaddr = (
uint32_t)kioc->buf_paddr;
478 pthru32 = kioc->pthru32;
479 kioc->user_pthru = &umimd->pthru;
480 mbox->xferaddr = (
uint32_t)kioc->pthru32_h;
483 sizeof(mraid_passthru_t))) {
487 pthru32->dataxferaddr = kioc->buf_paddr;
488 if (kioc->data_dir &
UIOC_WR) {
490 pthru32->dataxferlen)) {
517 kioc->pool_index = -1;
518 kioc->buf_vaddr =
NULL;
534 if (right_pool == -1)
542 kioc->pool_index =
i;
543 kioc->buf_vaddr = pool->
vaddr;
544 kioc->buf_paddr = pool->
paddr;
546 spin_unlock_irqrestore(&pool->
lock, flags);
550 spin_unlock_irqrestore(&pool->
lock, flags);
558 if (right_pool == -1)
569 kioc->pool_index = right_pool;
573 spin_unlock_irqrestore(&pool->
lock, flags);
575 if (!kioc->buf_vaddr)
602 if (list_empty(head)) {
611 list_del_init(&kioc->list);
615 memset((
caddr_t)(
unsigned long)kioc->cmdbuf, 0,
sizeof(mbox64_t));
616 memset((
caddr_t) kioc->pthru32, 0,
sizeof(mraid_passthru_t));
618 kioc->buf_vaddr =
NULL;
620 kioc->pool_index =-1;
622 kioc->user_data =
NULL;
623 kioc->user_data_len = 0;
624 kioc->user_pthru =
NULL;
641 if (kioc->pool_index != -1) {
654 if (kioc->free_buf == 1)
655 pci_pool_free(pool->
handle, kioc->buf_vaddr,
660 spin_unlock_irqrestore(&pool->
lock, flags);
689 if (rval)
return rval;
718 if (kioc->timedout) {
731 ioctl_done(uioc_t *kioc)
742 if (kioc->status == -
ENODATA) {
744 "megaraid cmm: lld didn't change status!\n"));
754 if (kioc->timedout) {
757 adapno = kioc->adapno;
760 "ioctl that was timedout before\n"));
763 if (iterator++ == adapno)
break;
769 mraid_mm_dealloc_kioc( adapter, kioc );
783 lld_timedout(
unsigned long ptr)
785 uioc_t *kioc = (uioc_t *)ptr;
787 kioc->status = -
ETIME;
802 kioc_to_mimd(uioc_t *kioc, mimd_t __user *mimd)
809 mraid_passthru_t
__user *upthru32;
810 mraid_passthru_t *kpthru32;
812 mraid_hba_info_t *hinfo;
818 opcode = kmimd.ui.fcs.opcode;
819 subopcode = kmimd.ui.fcs.subopcode;
821 if (opcode == 0x82) {
826 hinfo = (mraid_hba_info_t *)(
unsigned long)
829 hinfo_to_cinfo(hinfo, &cinfo);
843 mbox64 = (mbox64_t *)(
unsigned long)kioc->cmdbuf;
845 if (kioc->user_pthru) {
847 upthru32 = kioc->user_pthru;
848 kpthru32 = kioc->pthru32;
851 &kpthru32->scsistatus,
857 if (kioc->user_data) {
859 kioc->user_data_len)) {
865 &mbox64->mbox32.status,
sizeof(
uint8_t))) {
879 hinfo_to_cinfo(mraid_hba_info_t *hinfo, mcontroller_t *cinfo)
881 if (!hinfo || !cinfo)
884 cinfo->base = hinfo->baseport;
885 cinfo->irq = hinfo->irq;
886 cinfo->numldrv = hinfo->num_ldrv;
887 cinfo->pcibus = hinfo->pci_bus;
888 cinfo->pcidev = hinfo->pci_slot;
889 cinfo->pcifun =
PCI_FUNC(hinfo->pci_dev_fn);
890 cinfo->pciid = hinfo->pci_device_id;
891 cinfo->pcivendor = hinfo->pci_vendor_id;
892 cinfo->pcislot = hinfo->pci_slot;
893 cinfo->uid = hinfo->unique_id;
937 adapter->
pthru_dma_pool = pci_pool_create(
"megaraid mm pthru pool",
939 sizeof(mraid_passthru_t),
946 "megaraid cmm: out of memory, %s %d\n", __func__,
961 mbox_list = (mbox64_t *)adapter->
mbox_list;
966 kioc->cmdbuf = (
uint64_t)(
unsigned long)(mbox_list +
i);
970 if (!kioc->pthru32) {
973 "megaraid cmm: out of memory, %s %d\n",
974 __func__, __LINE__));
978 goto pthru_dma_pool_error;
985 if ((rval = mraid_mm_setup_dma_pools(adapter)) != 0) {
998 pthru_dma_pool_error:
1000 for (i = 0; i < lld_adp->
max_kioc; i++) {
1002 if (kioc->pthru32) {
1083 pool->
handle = pci_pool_create(
"megaraid mm data buffer",
1084 adp->
pdev, bufsize, 16, 0);
1087 goto dma_pool_setup_error;
1094 goto dma_pool_setup_error;
1096 bufsize = bufsize * 2;
1101 dma_pool_setup_error:
1103 mraid_mm_teardown_dma_pools(adp);
1127 list_del_init(&adapter->
list);
1129 mraid_mm_free_adp_resources(adapter);
1134 "megaraid cmm: Unregistered one adapter:%#x\n",
1154 mraid_mm_teardown_dma_pools(adp);
1156 for (i = 0; i < adp->
max_kioc; i++) {
1194 pci_pool_destroy(pool->
handle);
1216 con_log(
CL_ANN, (
"megaraid cmm: cannot register misc device\n"));
1222 INIT_LIST_HEAD(&adapters_list_g);
1228 #ifdef CONFIG_COMPAT
1236 mraid_mm_compat_ioctl(
struct file *filep,
unsigned int cmd,
1241 err = mraid_mm_ioctl(filep, cmd, arg);