diff -Naur 2.10.3/drivers/scsi/megaraid2.c 2.10.6/drivers/scsi/megaraid2.c --- 2.10.3/drivers/scsi/megaraid2.c 2004-05-18 00:36:59.671176480 -0400 +++ 2.10.6/drivers/scsi/megaraid2.c 2004-05-18 00:37:06.262174496 -0400 @@ -14,7 +14,7 @@ * - speed-ups (list handling fixes, issued_list, optimizations.) * - lots of cleanups. * - * Version : v2.10.3 (Apr 08, 2004) + * Version : v2.10.6 (May 14, 2004) * * Authors: Atul Mukker * Sreenivas Bagalkote @@ -90,10 +90,15 @@ static struct mega_hbas mega_hbas[MAX_CONTROLLERS]; /* + * Lock to protect access to IOCTL + */ +static struct semaphore megaraid_ioc_mtx; + +/* * The File Operations structure for the serial/ioctl interface of the driver */ static struct file_operations megadev_fops = { - .ioctl = megadev_ioctl, + .ioctl = megadev_ioctl_entry, .open = megadev_open, .release = megadev_close, .owner = THIS_MODULE, @@ -107,7 +112,7 @@ static struct mcontroller mcontroller[MAX_CONTROLLERS]; /* The current driver version */ -static u32 driver_ver = 0x02100000; +static u32 driver_ver = 0x02104000; /* major number used by the device for character interface */ static int major; @@ -189,6 +194,11 @@ */ mega_reorder_hosts(); + /* + * Initialize the IOCTL lock + */ + init_MUTEX( &megaraid_ioc_mtx ); + #ifdef CONFIG_PROC_FS mega_proc_dir_entry = proc_mkdir("megaraid", &proc_root); @@ -273,6 +283,8 @@ unsigned long tbase; unsigned long flag = 0; int i, j; + u8 did_int_pthru_f = 0; + u8 did_int_data_f = 0; while((pdev = pci_find_device(pci_vendor, pci_device, pdev))) { @@ -465,6 +477,33 @@ alloc_scb_f = 1; + /* + * Allocate memory for ioctls + */ + adapter->int_pthru = pci_alloc_consistent ( + adapter->dev, + sizeof(mega_passthru), + &adapter->int_pthru_dma_hndl ); + + if( adapter->int_pthru == NULL ) { + printk(KERN_WARNING "megaraid: out of RAM.\n"); + goto fail_attach; + } + else + did_int_pthru_f = 1; + + adapter->int_data = pci_alloc_consistent ( + adapter->dev, + INT_MEMBLK_SZ, + &adapter->int_data_dma_hndl ); + + if( adapter->int_data == NULL ) { + printk(KERN_WARNING "megaraid: out of RAM.\n"); + goto fail_attach; + } + else + did_int_data_f = 1; + /* Request our IRQ */ if( adapter->flag & BOARD_MEMMAP ) { if(request_irq(irq, megaraid_isr_memmapped, SA_SHIRQ, @@ -676,6 +715,19 @@ continue; fail_attach: + if( did_int_data_f ) { + pci_free_consistent( + adapter->dev, INT_MEMBLK_SZ, adapter->int_data, + adapter->int_data_dma_hndl ); + } + + if( did_int_pthru_f ) { + pci_free_consistent( + adapter->dev, sizeof(mega_passthru), + (void*) adapter->int_pthru, + adapter->int_pthru_dma_hndl ); + } + if( did_setup_mbox_f ) { pci_free_consistent(adapter->dev, sizeof(mbox64_t), (void *)adapter->una_mbox64, @@ -2568,6 +2620,13 @@ pci_free_consistent(adapter->dev, sizeof(mbox64_t), (void *)adapter->una_mbox64, adapter->una_mbox64_dma); + pci_free_consistent( adapter->dev, sizeof(mega_passthru), + (void*) adapter->int_pthru, + adapter->int_pthru_dma_hndl ); + + pci_free_consistent( adapter->dev, INT_MEMBLK_SZ, adapter->int_data, + adapter->int_data_dma_hndl ); + hba_count--; if( hba_count == 0 ) { @@ -4076,10 +4135,20 @@ { struct inode *inode = filep->f_dentry->d_inode; - return megadev_ioctl(inode, filep, cmd, arg); + return megadev_ioctl_entry(inode, filep, cmd, arg); } #endif +static int +megadev_ioctl_entry(struct inode *inode, struct file *filep, unsigned int cmd, + unsigned long arg) +{ + int rval; + down( &megaraid_ioc_mtx ); + rval = megadev_ioctl( inode, filep, cmd, arg ); + up( &megaraid_ioc_mtx ); + return rval; +} /** * megadev_ioctl() @@ -4103,9 +4172,8 @@ int rval; mega_passthru *upthru; /* user address for passthru */ mega_passthru *pthru; /* copy user passthru here */ - dma_addr_t pthru_dma_hndl; void *data = NULL; /* data to be transferred */ - dma_addr_t data_dma_hndl; /* dma handle for data xfer area */ + dma_addr_t data_dma_hndl = 0; megacmd_t mc; megastat_t *ustats; int num_ldrv; @@ -4221,7 +4289,7 @@ /* * Which adapter */ - if( (adapno = GETADAP(uioc.adapno)) >= hba_count ) + if( (adapno = GETADAP(uioc.adapno)) >= hba_count ) return (-ENODEV); adapter = hba_soft_state[adapno]; @@ -4277,13 +4345,7 @@ if( uioc.uioc_rmbox[0] == MEGA_MBOXCMD_PASSTHRU ) { /* Passthru commands */ - pthru = pci_alloc_consistent(pdev, - sizeof(mega_passthru), - &pthru_dma_hndl); - - if( pthru == NULL ) { - return (-ENOMEM); - } + pthru = adapter->int_pthru; /* * The user passthru structure @@ -4295,29 +4357,27 @@ */ if( copy_from_user(pthru, (char *)upthru, sizeof(mega_passthru)) ) { - - pci_free_consistent(pdev, - sizeof(mega_passthru), pthru, - pthru_dma_hndl); - return (-EFAULT); } /* - * Is there a data transfer + * Is there a data transfer; If the data transfer + * length is <= INT_MEMBLK_SZ, usr the buffer + * allocated at the load time. Otherwise, allocate it + * here. */ - if( pthru->dataxferlen ) { - data = pci_alloc_consistent(pdev, - pthru->dataxferlen, - &data_dma_hndl); - - if( data == NULL ) { - pci_free_consistent(pdev, - sizeof(mega_passthru), - pthru, - pthru_dma_hndl); + if (pthru->dataxferlen) { + if (pthru->dataxferlen > INT_MEMBLK_SZ) { + data = pci_alloc_consistent ( + pdev, + pthru->dataxferlen, + &data_dma_hndl ); - return (-ENOMEM); + if (data == NULL) + return (-ENOMEM); + } + else { + data = adapter->int_data; } /* @@ -4325,7 +4385,11 @@ * address at just allocated memory */ uxferaddr = pthru->dataxferaddr; - pthru->dataxferaddr = data_dma_hndl; + if (data_dma_hndl) + pthru->dataxferaddr = data_dma_hndl; + else + pthru->dataxferaddr = + adapter->int_data_dma_hndl; } @@ -4340,14 +4404,14 @@ (char *)((ulong)uxferaddr), pthru->dataxferlen) ) { rval = (-EFAULT); - goto freemem_and_return; + goto freedata_and_return; } } memset(&mc, 0, sizeof(megacmd_t)); mc.cmd = MEGA_MBOXCMD_PASSTHRU; - mc.xferaddr = (u32)pthru_dma_hndl; + mc.xferaddr = (u32)adapter->int_pthru_dma_hndl; /* * Issue the command @@ -4356,7 +4420,7 @@ rval = mega_n_to_m((void *)arg, &mc); - if( rval ) goto freemem_and_return; + if( rval ) goto freedata_and_return; /* @@ -4375,18 +4439,14 @@ */ copy_to_user(upthru->reqsensearea, pthru->reqsensearea, 14); - -freemem_and_return: - if( pthru->dataxferlen ) { - pci_free_consistent(pdev, - pthru->dataxferlen, data, - data_dma_hndl); +freedata_and_return: + if (data_dma_hndl) { + pci_free_consistent( pdev, pthru->dataxferlen, + data, data_dma_hndl ); } - pci_free_consistent(pdev, sizeof(mega_passthru), - pthru, pthru_dma_hndl); - return rval; + } else { /* DCMD commands */ @@ -4395,13 +4455,18 @@ * Is there a data transfer */ if( uioc.xferlen ) { - data = pci_alloc_consistent(pdev, - uioc.xferlen, &data_dma_hndl); + if (uioc.xferlen > INT_MEMBLK_SZ) { + data = pci_alloc_consistent( + pdev, + uioc.xferlen, + &data_dma_hndl ); - if( data == NULL ) { - return (-ENOMEM); + if (data == NULL) + return (-ENOMEM); + } + else { + data = adapter->int_data; } - uxferaddr = MBOX(uioc)->xferaddr; } @@ -4416,9 +4481,9 @@ (char *)((ulong)uxferaddr), uioc.xferlen) ) { - pci_free_consistent(pdev, - uioc.xferlen, data, - data_dma_hndl); + pci_free_consistent( + pdev, uioc.xferlen, + data, data_dma_hndl ); return (-EFAULT); } @@ -4426,7 +4491,10 @@ memcpy(&mc, MBOX(uioc), sizeof(megacmd_t)); - mc.xferaddr = (u32)data_dma_hndl; + if (data_dma_hndl ) + mc.xferaddr = (u32)data_dma_hndl; + else + mc.xferaddr = (u32)(adapter->int_data_dma_hndl); /* * Issue the command @@ -4436,12 +4504,10 @@ rval = mega_n_to_m((void *)arg, &mc); if( rval ) { - if( uioc.xferlen ) { - pci_free_consistent(pdev, - uioc.xferlen, data, - data_dma_hndl); + if (data_dma_hndl) { + pci_free_consistent( pdev, uioc.xferlen, + data, data_dma_hndl ); } - return rval; } @@ -4456,10 +4522,9 @@ } } - if( uioc.xferlen ) { - pci_free_consistent(pdev, - uioc.xferlen, data, - data_dma_hndl); + if (data_dma_hndl) { + pci_free_consistent( pdev, uioc.xferlen, + data, data_dma_hndl ); } return rval; @@ -4644,19 +4709,22 @@ else { uioc_mimd = (struct uioctl_t *)arg; - if( put_user(mc->status, (u8 *)&uioc_mimd->mbox[17]) ) + if( put_user(mc->status, (u8 *)&uioc_mimd->mbox[17]) ) { return (-EFAULT); + } if( mc->cmd == MEGA_MBOXCMD_PASSTHRU ) { umc = (megacmd_t *)uioc_mimd->mbox; - if (copy_from_user(&kmc, umc, sizeof(megacmd_t))) + if (copy_from_user(&kmc, umc, sizeof(megacmd_t))) { return -EFAULT; + } upthru = (mega_passthru *)((ulong)kmc.xferaddr); - if( put_user(mc->status, (u8 *)&upthru->scsistatus) ) + if( put_user(mc->status, (u8 *)&upthru->scsistatus) ){ return (-EFAULT); + } } } @@ -5116,13 +5184,7 @@ */ if (adapter->support_random_del && adapter->read_ldidmap ) - switch (cmd->cmnd[0]) { - case READ_6: /* fall through */ - case WRITE_6: /* fall through */ - case READ_10: /* fall through */ - case WRITE_10: - ldrv_num += 0x80; - } + ldrv_num += 0x80; return ldrv_num; } diff -Naur 2.10.3/drivers/scsi/megaraid2.h 2.10.6/drivers/scsi/megaraid2.h --- 2.10.3/drivers/scsi/megaraid2.h 2004-05-18 00:36:59.673176176 -0400 +++ 2.10.6/drivers/scsi/megaraid2.h 2004-05-18 00:37:06.264174192 -0400 @@ -6,7 +6,7 @@ #define MEGARAID_VERSION \ - "v2.10.3 (Release Date: Thu Apr 8 16:16:05 EDT 2004)\n" + "v2.10.6 (Release Date: Fri May 14 08:36:49 EDT 2004)\n" /* * Driver features - change the values to enable or disable features in the @@ -979,6 +979,13 @@ cmds */ int has_cluster; /* cluster support on this HBA */ + +#define INT_MEMBLK_SZ (28*1024) + mega_passthru *int_pthru; /*internal pthru*/ + dma_addr_t int_pthru_dma_hndl; + caddr_t int_data; /*internal data*/ + dma_addr_t int_data_dma_hndl; + }adapter_t; @@ -1136,6 +1143,8 @@ struct file *); #endif +static int megadev_ioctl_entry (struct inode *, struct file *, unsigned int, + unsigned long); static int megadev_ioctl (struct inode *, struct file *, unsigned int, unsigned long); static int mega_m_to_n(void *, nitioctl_t *);