This patch contains accumulated changes over the time. Description of the changes. ### Version 2.10.10.1 Thu Jan 27 15:59:59 EDT 2005 - Seokmann Ju <sju@xxxxxxxx> 1. There was a bug in the 'megadev_ioctl()' function that cause random deletion error and has been fixed. ### Version 2.10.10.0 Fri Jan 21 15:59:59 EDT 2005 - Seokmann Ju <sju@xxxxxxxx> 1. Fixed Tape drive issue : For any Direct CDB command to physical device including tape, timeout value set by driver was 10 minutes. With this value, most of command will return within timeout. However, for those command like ERASE or FORMAT, it takes more than an hour depends on capacity of the device and the command could be terminated before it completes. To address this issue, the 'timeout' field in the DCDB command will have NO TIMEOUT (i.e., 4) value as its timeout on DCDB command. 2. Added NEC ROMB support : NEC MegaRAID PCI Express ROMB controller ### Version 2.10.9.0 Fri Aug 13 15:59:59 EDT 2004 - Rajesh Prabhakaran <rajeshpr@xxxxxxxx> 1. Added Support for 64-applications : mega_ioctl function and nitioctl_t struct where changed to accomadate 64-bit addressing. Signed-off-by: Seokmann Ju <seokmann.ju@xxxxxxxx> --- diff -Naur old/drivers/scsi/megaraid2.c new/drivers/scsi/megaraid2.c --- old/drivers/scsi/megaraid2.c 2005-07-15 07:52:27.555937432 -0400 +++ new/drivers/scsi/megaraid2.c 2005-07-15 07:52:18.564304368 -0400 @@ -14,7 +14,7 @@ * - speed-ups (list handling fixes, issued_list, optimizations.) * - lots of cleanups. * - * Version : v2.10.8.2 (July 26, 2004) + * Version : v2.10.10.1 (January 27, 2005) * * Authors: Atul Mukker <Atul.Mukker@xxxxxxxx> * Sreenivas Bagalkote <Sreenivas.Bagalkote@xxxxxxxx> @@ -46,7 +46,7 @@ #include "megaraid2.h" -#if defined(__x86_64__) +#ifdef LSI_CONFIG_COMPAT #include <asm/ioctl32.h> #endif @@ -233,7 +233,7 @@ "MegaRAID Shutdown routine not registered!!\n"); } -#if defined(__x86_64__) +#ifdef LSI_CONFIG_COMPAT /* * Register the 32-bit ioctl conversion */ @@ -341,6 +341,7 @@ (subsysvid != INTEL_SUBSYS_VID) && (subsysvid != FSC_SUBSYS_VID) && (subsysvid != ACER_SUBSYS_VID) && + (subsysvid != NEC_SUBSYS_VID) && (subsysvid != LSI_SUBSYS_VID) ) continue; @@ -989,268 +990,6 @@ } -/** - * issue_scb() - * @adapter - pointer to our soft state - * @scb - scsi control block - * - * Post a command to the card if the mailbox is available, otherwise return - * busy. We also take the scb from the pending list if the mailbox is - * available. - */ -static inline int -issue_scb(adapter_t *adapter, scb_t *scb) -{ - volatile mbox64_t *mbox64 = adapter->mbox64; - volatile mbox_t *mbox = adapter->mbox; - unsigned int i = 0; - - if(unlikely(mbox->busy)) { - do { - udelay(1); - i++; - } while( mbox->busy && (i < max_mbox_busy_wait) ); - - if(mbox->busy) return -1; - } - - /* Copy mailbox data into host structure */ - memcpy((char *)mbox, (char *)scb->raw_mbox, 16); - - mbox->cmdid = scb->idx; /* Set cmdid */ - mbox->busy = 1; /* Set busy */ - - - /* - * Increment the pending queue counter - */ - atomic_inc(&adapter->pend_cmds); - - switch (mbox->cmd) { - case MEGA_MBOXCMD_EXTPTHRU: - if( !adapter->has_64bit_addr ) break; - // else fall through - case MEGA_MBOXCMD_LREAD64: - case MEGA_MBOXCMD_LWRITE64: - case MEGA_MBOXCMD_PASSTHRU64: - mbox64->xfer_segment_lo = mbox->xferaddr; - mbox64->xfer_segment_hi = 0; - mbox->xferaddr = 0xFFFFFFFF; - break; - default: - mbox64->xfer_segment_lo = 0; - mbox64->xfer_segment_hi = 0; - } - - /* - * post the command - */ - scb->state |= SCB_ISSUED; - - if( likely(adapter->flag & BOARD_MEMMAP) ) { - mbox->poll = 0; - mbox->ack = 0; - WRINDOOR(adapter, adapter->mbox_dma | 0x1); - } - else { - irq_enable(adapter); - issue_command(adapter); - } - - return 0; -} - - -/** - * mega_runpendq() - * @adapter - pointer to our soft state - * - * Runs through the list of pending requests. - */ -static inline void -mega_runpendq(adapter_t *adapter) -{ - if(!list_empty(&adapter->pending_list)) - __mega_runpendq(adapter); -} - - -static void -__mega_runpendq(adapter_t *adapter) -{ - scb_t *scb; - struct list_head *pos, *next; - - /* Issue any pending commands to the card */ - list_for_each_safe(pos, next, &adapter->pending_list) { - - scb = list_entry(pos, scb_t, list); - - if( !(scb->state & SCB_ISSUED) ) { - - if( issue_scb(adapter, scb) != 0 ) - return; - } - } - - return; -} - - -/** - * mega_allocate_scb() - * @adapter - pointer to our soft state - * @cmd - scsi command from the mid-layer - * - * Allocate a SCB structure. This is the central structure for controller - * commands. - */ -static inline scb_t * -mega_allocate_scb(adapter_t *adapter, Scsi_Cmnd *cmd) -{ - struct list_head *head = &adapter->free_list; - scb_t *scb; - - /* Unlink command from Free List */ - if( !list_empty(head) ) { - - scb = list_entry(head->next, scb_t, list); - - list_del_init(head->next); - - scb->state = SCB_ACTIVE; - scb->cmd = cmd; - scb->dma_type = MEGA_DMA_TYPE_NONE; - - return scb; - } - - return NULL; -} - - -/** - * mega_get_ldrv_num() - * @adapter - pointer to our soft state - * @cmd - scsi mid layer command - * @channel - channel on the controller - * - * Calculate the logical drive number based on the information in scsi command - * and the channel number. - */ -static inline int -mega_get_ldrv_num(adapter_t *adapter, Scsi_Cmnd *cmd, int channel) -{ - int tgt; - int ldrv_num; - - tgt = cmd->target; - - if ( tgt > adapter->this_id ) - tgt--; /* we do not get inquires for initiator id */ - - ldrv_num = (channel * 15) + tgt; - - - /* - * If we have a logical drive with boot enabled, project it first - */ - if( adapter->boot_ldrv_enabled ) { - if( ldrv_num == 0 ) { - ldrv_num = adapter->boot_ldrv; - } - else { - if( ldrv_num <= adapter->boot_ldrv ) { - ldrv_num--; - } - } - } - - /* - * If "delete logical drive" feature is enabled on this controller, - * the value returned should be 0x80+logical drive id. - */ - if (adapter->support_random_del) - ldrv_num += 0x80; - - return ldrv_num; -} - -/* - * Wait until the controller's mailbox is available - */ -static inline int -mega_busywait_mbox (adapter_t *adapter) -{ - if (adapter->mbox->busy) - return __mega_busywait_mbox(adapter); - return 0; -} - - -/** - * megaraid_iombox_ack_sequence - interrupt ack sequence for IO mapped HBAs - * @adapter - controller's soft state - * - * Interrupt ackrowledgement sequence for IO mapped HBAs - */ -static inline void -megaraid_iombox_ack_sequence(adapter_t *adapter) -{ - u8 status; - u8 nstatus; - u8 completed[MAX_FIRMWARE_STATUS]; - u8 byte; - int i; - - - /* - * loop till F/W has more commands for us to complete. - */ - do { - /* Check if a valid interrupt is pending */ - byte = irq_state(adapter); - if( (byte & VALID_INTR_BYTE) == 0 ) { - return; - } - set_irq_state(adapter, byte); - - while ((nstatus = adapter->mbox->numstatus) == 0xFF) { - cpu_relax(); - } - adapter->mbox->numstatus = 0xFF; - - for (i = 0; i < nstatus; i++) { - while ((completed[i] = adapter->mbox->completed[i]) - == 0xFF) { - cpu_relax(); - } - - adapter->mbox->completed[i] = 0xFF; - } - - // we must read the valid status now - if ((status = adapter->mbox->status) == 0xFF) { - printk(KERN_WARNING - "megaraid critical: status 0xFF from firmware.\n"); - } - adapter->mbox->status = 0xFF; - - /* - * decrement the pending queue counter - */ - atomic_sub(nstatus, &adapter->pend_cmds); - - /* Acknowledge interrupt */ - irq_ack(adapter); - - mega_cmd_done(adapter, completed, nstatus, status); - - } while(1); -} - - - /* * megaraid_queue() * @scmd - Issue this scsi command @@ -1755,8 +1494,8 @@ pthru = scb->pthru; memset(pthru, 0, sizeof (mega_passthru)); - /* 0=6sec/1=60sec/2=10min/3=3hrs */ - pthru->timeout = 2; + /* 0=6sec/1=60sec/2=10min/3=3hrs/4=NO timeout */ + pthru->timeout = 4; pthru->ars = 1; pthru->reqsenselen = 14; @@ -1819,8 +1558,8 @@ epthru = scb->epthru; memset(epthru, 0, sizeof(mega_ext_passthru)); - /* 0=6sec/1=60sec/2=10min/3=3hrs */ - epthru->timeout = 2; + /* 0=6sec/1=60sec/2=10min/3=3hrs/4=NO timeout */ + epthru->timeout = 4; epthru->ars = 1; epthru->reqsenselen = 14; @@ -1863,6 +1602,145 @@ /** + * mega_allocate_scb() + * @adapter - pointer to our soft state + * @cmd - scsi command from the mid-layer + * + * Allocate a SCB structure. This is the central structure for controller + * commands. + */ +static inline scb_t * +mega_allocate_scb(adapter_t *adapter, Scsi_Cmnd *cmd) +{ + struct list_head *head = &adapter->free_list; + scb_t *scb; + + /* Unlink command from Free List */ + if( !list_empty(head) ) { + + scb = list_entry(head->next, scb_t, list); + + list_del_init(head->next); + + scb->state = SCB_ACTIVE; + scb->cmd = cmd; + scb->dma_type = MEGA_DMA_TYPE_NONE; + + return scb; + } + + return NULL; +} + + +/** + * mega_runpendq() + * @adapter - pointer to our soft state + * + * Runs through the list of pending requests. + */ +static inline void +mega_runpendq(adapter_t *adapter) +{ + if(!list_empty(&adapter->pending_list)) + __mega_runpendq(adapter); +} + +static void +__mega_runpendq(adapter_t *adapter) +{ + scb_t *scb; + struct list_head *pos, *next; + + /* Issue any pending commands to the card */ + list_for_each_safe(pos, next, &adapter->pending_list) { + + scb = list_entry(pos, scb_t, list); + + if( !(scb->state & SCB_ISSUED) ) { + + if( issue_scb(adapter, scb) != 0 ) + return; + } + } + + return; +} + + +/** + * issue_scb() + * @adapter - pointer to our soft state + * @scb - scsi control block + * + * Post a command to the card if the mailbox is available, otherwise return + * busy. We also take the scb from the pending list if the mailbox is + * available. + */ +static inline int +issue_scb(adapter_t *adapter, scb_t *scb) +{ + volatile mbox64_t *mbox64 = adapter->mbox64; + volatile mbox_t *mbox = adapter->mbox; + unsigned int i = 0; + + if(unlikely(mbox->busy)) { + do { + udelay(1); + i++; + } while( mbox->busy && (i < max_mbox_busy_wait) ); + + if(mbox->busy) return -1; + } + + /* Copy mailbox data into host structure */ + memcpy((char *)mbox, (char *)scb->raw_mbox, 16); + + mbox->cmdid = scb->idx; /* Set cmdid */ + mbox->busy = 1; /* Set busy */ + + + /* + * Increment the pending queue counter + */ + atomic_inc(&adapter->pend_cmds); + + switch (mbox->cmd) { + case MEGA_MBOXCMD_EXTPTHRU: + if( !adapter->has_64bit_addr ) break; + // else fall through + case MEGA_MBOXCMD_LREAD64: + case MEGA_MBOXCMD_LWRITE64: + case MEGA_MBOXCMD_PASSTHRU64: + mbox64->xfer_segment_lo = mbox->xferaddr; + mbox64->xfer_segment_hi = 0; + mbox->xferaddr = 0xFFFFFFFF; + break; + default: + mbox64->xfer_segment_lo = 0; + mbox64->xfer_segment_hi = 0; + } + + /* + * post the command + */ + scb->state |= SCB_ISSUED; + + if( likely(adapter->flag & BOARD_MEMMAP) ) { + mbox->poll = 0; + mbox->ack = 0; + WRINDOOR(adapter, adapter->mbox_dma | 0x1); + } + else { + irq_enable(adapter); + issue_command(adapter); + } + + return 0; +} + + +/** * issue_scb_block() * @adapter - pointer to our soft state * @raw_mbox - the mailbox @@ -1979,7 +1857,6 @@ adapter_t *adapter = devp; unsigned long flags; - spin_lock_irqsave(adapter->host_lock, flags); megaraid_iombox_ack_sequence(adapter); @@ -1996,6 +1873,99 @@ /** + * megaraid_iombox_ack_sequence - interrupt ack sequence for IO mapped HBAs + * @adapter - controller's soft state + * + * Interrupt ackrowledgement sequence for IO mapped HBAs + */ +static inline void +megaraid_iombox_ack_sequence(adapter_t *adapter) +{ + u8 status; + int nstatus; + u8 completed[MAX_FIRMWARE_STATUS]; + u8 byte; + int i; + + + /* + * loop till F/W has more commands for us to complete. + */ + do { + /* Check if a valid interrupt is pending */ + byte = irq_state(adapter); + if( (byte & VALID_INTR_BYTE) == 0 ) { + return; + } + set_irq_state(adapter, byte); + + while ((nstatus = adapter->mbox->numstatus) == 0xFF) { + cpu_relax(); + } + adapter->mbox->numstatus = 0xFF; + + for (i = 0; i < nstatus; i++) { + while ((completed[i] = adapter->mbox->completed[i]) + == 0xFF) { + cpu_relax(); + } + + adapter->mbox->completed[i] = 0xFF; + } + + // we must read the valid status now + if ((status = adapter->mbox->status) == 0xFF) { + printk(KERN_WARNING + "megaraid critical: status 0xFF from firmware.\n"); + } + adapter->mbox->status = 0xFF; + + /* + * decrement the pending queue counter + */ + atomic_sub(nstatus, &adapter->pend_cmds); + + /* Acknowledge interrupt */ + irq_ack(adapter); + + mega_cmd_done(adapter, completed, nstatus, status); + + } while(1); +} + + +/** + * megaraid_isr_memmapped() + * @irq - irq + * @devp - pointer to our soft state + * @regs - unused + * + * Interrupt service routine for memory-mapped controllers. + * Find out if our device is interrupting. If yes, acknowledge the interrupt + * and service the completed commands. + */ +static void +megaraid_isr_memmapped(int irq, void *devp, struct pt_regs *regs) +{ + adapter_t *adapter = devp; + unsigned long flags; + + spin_lock_irqsave(adapter->host_lock, flags); + + megaraid_memmbox_ack_sequence(adapter); + + /* Loop through any pending requests */ + if(atomic_read(&adapter->quiescent) == 0) { + mega_runpendq(adapter); + } + + spin_unlock_irqrestore(adapter->host_lock, flags); + + return; +} + + +/** * megaraid_memmbox_ack_sequence - interrupt ack sequence for memory mapped HBAs * @adapter - controller's soft state * @@ -2006,7 +1976,7 @@ { u8 status; u32 dword = 0; - u8 nstatus; + int nstatus; u8 completed[MAX_FIRMWARE_STATUS]; int i; @@ -2063,37 +2033,6 @@ /** - * megaraid_isr_memmapped() - * @irq - irq - * @devp - pointer to our soft state - * @regs - unused - * - * Interrupt service routine for memory-mapped controllers. - * Find out if our device is interrupting. If yes, acknowledge the interrupt - * and service the completed commands. - */ -static void -megaraid_isr_memmapped(int irq, void *devp, struct pt_regs *regs) -{ - adapter_t *adapter = devp; - unsigned long flags; - - - spin_lock_irqsave(adapter->host_lock, flags); - - megaraid_memmbox_ack_sequence(adapter); - - /* Loop through any pending requests */ - if(atomic_read(&adapter->quiescent) == 0) { - mega_runpendq(adapter); - } - - spin_unlock_irqrestore(adapter->host_lock, flags); - - return; -} - -/** * mega_cmd_done() * @adapter - pointer to our soft state * @completed - array of ids of completed commands @@ -2102,7 +2041,7 @@ * * Complete the comamnds and call the scsi mid-layer callback hooks. */ -static void +static inline void mega_cmd_done(adapter_t *adapter, u8 completed[], int nstatus, int status) { mega_ext_passthru *epthru = NULL; @@ -2404,6 +2343,18 @@ list_add(&scb->list, &adapter->free_list); } + +/* + * Wait until the controller's mailbox is available + */ +static inline int +mega_busywait_mbox (adapter_t *adapter) +{ + if (adapter->mbox->busy) + return __mega_busywait_mbox(adapter); + return 0; +} + static int __mega_busywait_mbox (adapter_t *adapter) { @@ -2434,7 +2385,7 @@ cmd = scb->cmd; - /* return 0 elements if no data transfer */ + // return 0 elements if no data transfer if (!cmd->request_buffer || !cmd->request_bufflen) return 0; @@ -2561,43 +2512,6 @@ enquiry3->pdrv_state[i] = inquiry->pdrv_info.pdrv_state[i]; } -static inline void -mega_free_sgl(adapter_t *adapter) -{ - scb_t *scb; - int i; - - for(i = 0; i < adapter->max_cmds; i++) { - - scb = &adapter->scb_list[i]; - - if( scb->sgl64 ) { - pci_free_consistent(adapter->dev, - sizeof(mega_sgl64) * adapter->sglen, - scb->sgl64, - scb->sgl_dma_addr); - - scb->sgl64 = NULL; - } - - if( scb->pthru ) { - pci_free_consistent(adapter->dev, sizeof(mega_passthru), - scb->pthru, scb->pthru_dma_addr); - - scb->pthru = NULL; - } - - if( scb->epthru ) { - pci_free_consistent(adapter->dev, - sizeof(mega_ext_passthru), - scb->epthru, scb->epthru_dma_addr); - - scb->epthru = NULL; - } - - } -} - /* * Release the controller's resources @@ -2726,7 +2640,7 @@ */ scsi_unregister(host); -#if defined(__x86_64__) +#ifdef LSI_CONFIG_COMPAT unregister_ioctl32_conversion(MEGAIOCCMD); #endif @@ -2735,6 +2649,44 @@ return 0; } +static inline void +mega_free_sgl(adapter_t *adapter) +{ + scb_t *scb; + int i; + + for(i = 0; i < adapter->max_cmds; i++) { + + scb = &adapter->scb_list[i]; + + if( scb->sgl64 ) { + pci_free_consistent(adapter->dev, + sizeof(mega_sgl64) * adapter->sglen, + scb->sgl64, + scb->sgl_dma_addr); + + scb->sgl64 = NULL; + } + + if( scb->pthru ) { + pci_free_consistent(adapter->dev, sizeof(mega_passthru), + scb->pthru, scb->pthru_dma_addr); + + scb->pthru = NULL; + } + + if( scb->epthru ) { + pci_free_consistent(adapter->dev, + sizeof(mega_ext_passthru), + scb->epthru, scb->epthru_dma_addr); + + scb->epthru = NULL; + } + + } +} + + /* * Get information about the card/driver */ @@ -2835,7 +2787,6 @@ return SUCCESS; } - static int megaraid_reset(Scsi_Cmnd *cmd) { @@ -2903,12 +2854,10 @@ /* * Perform the ack sequence, since interrupts are unavailable */ - if( adapter->flag & BOARD_MEMMAP ) { + if (adapter->flag & BOARD_MEMMAP) megaraid_memmbox_ack_sequence(adapter); - } - else { + else megaraid_iombox_ack_sequence(adapter); - } spin_unlock(adapter->host_lock); @@ -2941,7 +2890,6 @@ return rval; } - #ifdef CONFIG_PROC_FS /* Following code handles /proc fs */ @@ -3200,26 +3148,6 @@ return len; } -/** - * mega_allocate_inquiry() - * @dma_handle - handle returned for dma address - * @pdev - handle to pci device - * - * allocates memory for inquiry structure - */ -static inline caddr_t -mega_allocate_inquiry(dma_addr_t *dma_handle, struct pci_dev *pdev) -{ - return pci_alloc_consistent(pdev, sizeof(mega_inquiry3), dma_handle); -} - - -static inline void -mega_free_inquiry(caddr_t inquiry, dma_addr_t dma_handle, struct pci_dev *pdev) -{ - pci_free_consistent(pdev, sizeof(mega_inquiry3), inquiry, dma_handle); -} - /** * proc_rebuild_rate() @@ -4172,7 +4100,7 @@ } -#if defined(__x86_64__) +#ifdef LSI_CONFIG_COMPAT static int megadev_compat_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *filep) @@ -4221,7 +4149,7 @@ megacmd_t mc; megastat_t *ustats; int num_ldrv; - u32 uxferaddr = 0; + caddr_t uxferaddr=NULL; struct pci_dev *pdev; ustats = NULL; /* avoid compilation warnings */ @@ -4251,13 +4179,13 @@ switch( uioc.opcode ) { case GET_DRIVER_VER: - if( put_user(driver_ver, (u32 *)uioc.uioc_uaddr) ) + if( put_user(driver_ver, (u32 *)uioc.u_dataaddr) ) return (-EFAULT); break; case GET_N_ADAP: - if( put_user(hba_count, (u32 *)uioc.uioc_uaddr) ) + if( put_user(hba_count, (u32 *)uioc.u_dataaddr) ) return (-EFAULT); /* @@ -4275,7 +4203,7 @@ if( (adapno = GETADAP(uioc.adapno)) >= hba_count ) return (-ENODEV); - if( copy_to_user(uioc.uioc_uaddr, mcontroller+adapno, + if( copy_to_user(uioc.u_dataaddr, mcontroller+adapno, sizeof(struct mcontroller)) ) return (-EFAULT); break; @@ -4291,7 +4219,7 @@ adapter = hba_soft_state[adapno]; - ustats = (megastat_t *)uioc.uioc_uaddr; + ustats = (megastat_t *)uioc.u_dataaddr; if( copy_from_user(&num_ldrv, &ustats->num_ldrv, sizeof(int)) ) return (-EFAULT); @@ -4333,7 +4261,7 @@ /* * Which adapter */ - if( (adapno = GETADAP(uioc.adapno)) >= hba_count ) + if( (adapno = GETADAP(uioc.adapno)) >= hba_count ) return (-ENODEV); adapter = hba_soft_state[adapno]; @@ -4342,37 +4270,37 @@ * Deletion of logical drive is a special case. The adapter * should be quiescent before this command is issued. */ - if( uioc.uioc_rmbox[0] == FC_DEL_LOGDRV && - uioc.uioc_rmbox[2] == OP_DEL_LOGDRV ) { + if( RMBOX(uioc)[0] == FC_DEL_LOGDRV ) { + if ( RMBOX(uioc)[2] == OP_DEL_LOGDRV ) { + /* + * Do we support this feature + */ + if( !adapter->support_random_del ) { + printk(KERN_WARNING "megaraid: logdrv "); + printk("delete on non-supporting F/W.\n"); - /* - * Do we support this feature - */ - if( !adapter->support_random_del ) { - printk(KERN_WARNING "megaraid: logdrv "); - printk("delete on non-supporting F/W.\n"); + return (-EINVAL); + } - return (-EINVAL); - } + rval = mega_del_logdrv( adapter, RMBOX(uioc)[3] ); - rval = mega_del_logdrv( adapter, uioc.uioc_rmbox[3] ); + if( rval == 0 ) { + memset(&mc, 0, sizeof(megacmd_t)); - if( rval == 0 ) { - memset(&mc, 0, sizeof(megacmd_t)); + mc.status = rval; - mc.status = rval; + rval = mega_n_to_m((void *)arg, &mc); + } - rval = mega_n_to_m((void *)arg, &mc); + return rval; } - - return rval; } /* * This interface only support the regular passthru commands. * Reject extended passthru and 64-bit passthru */ - if( uioc.uioc_rmbox[0] == MEGA_MBOXCMD_PASSTHRU64 || - uioc.uioc_rmbox[0] == MEGA_MBOXCMD_EXTPTHRU ) { + if( RMBOX(uioc)[0] == MEGA_MBOXCMD_PASSTHRU64 || + RMBOX(uioc)[0] == MEGA_MBOXCMD_EXTPTHRU ) { printk(KERN_WARNING "megaraid: rejected passthru.\n"); @@ -4386,7 +4314,7 @@ pdev = adapter->dev; /* Is it a passthru command or a DCMD */ - if( uioc.uioc_rmbox[0] == MEGA_MBOXCMD_PASSTHRU ) { + if( RMBOX(uioc)[0] == MEGA_MBOXCMD_PASSTHRU ) { /* Passthru commands */ pthru = adapter->int_pthru; @@ -4394,20 +4322,12 @@ /* * The user passthru structure */ - upthru = (mega_passthru *) - ((ulong)(MBOX(uioc)->xferaddr)); - /* - * Copy in the user passthru here. - */ - if( copy_from_user(pthru, (char *)upthru, - sizeof(mega_passthru)) ) { - return (-EFAULT); - } - + upthru = &uioc.pthru; + memcpy(pthru, (char *)upthru,sizeof(mega_passthru)); /* * 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 + * length is <= INT_MEMBLK_SZ, usr the buffer + * allocated at the load time. Otherwise, allocate it * here. */ if (pthru->dataxferlen) { @@ -4417,8 +4337,9 @@ pthru->dataxferlen, &data_dma_hndl ); - if (data == NULL) + if (data == NULL) { return (-ENOMEM); + } } else { data = adapter->int_data; @@ -4428,11 +4349,11 @@ * Save the user address and point the kernel * address at just allocated memory */ - uxferaddr = pthru->dataxferaddr; + uxferaddr = (caddr_t) uioc.u_dataaddr; if (data_dma_hndl) pthru->dataxferaddr = data_dma_hndl; else - pthru->dataxferaddr = + pthru->dataxferaddr = adapter->int_data_dma_hndl; } @@ -4440,12 +4361,12 @@ /* * Is data coming down-stream */ - if( pthru->dataxferlen && (uioc.flags & UIOC_WR) ) { + if(pthru->dataxferlen && (uioc.flags & UIOC_WR) ) { /* * Get the user data */ if( copy_from_user(data, - (char *)((ulong)uxferaddr), + (char *)uxferaddr, pthru->dataxferlen) ) { rval = (-EFAULT); goto freedata_and_return; @@ -4471,7 +4392,7 @@ * Is data going up-stream */ if( pthru->dataxferlen && (uioc.flags & UIOC_RD) ) { - if( copy_to_user((char *)((ulong)uxferaddr), + if( copy_to_user((char *)uxferaddr, data, pthru->dataxferlen) ) { rval = (-EFAULT); } @@ -4511,7 +4432,7 @@ else { data = adapter->int_data; } - uxferaddr = MBOX(uioc)->xferaddr; + uxferaddr = uioc.u_dataaddr; } /* @@ -4559,7 +4480,7 @@ * Is data going up-stream */ if( uioc.xferlen && (uioc.flags & UIOC_RD) ) { - if( copy_to_user((char *)((ulong)uxferaddr), + if( copy_to_user((char *)uxferaddr, data, uioc.xferlen) ) { rval = (-EFAULT); @@ -4648,18 +4569,18 @@ case MEGAIOC_QDRVRVER: /* Query driver version */ uioc->opcode = GET_DRIVER_VER; - uioc->uioc_uaddr = uioc_mimd.data; + uioc->u_dataaddr = uioc_mimd.data; break; case MEGAIOC_QNADAP: /* Get # of adapters */ uioc->opcode = GET_N_ADAP; - uioc->uioc_uaddr = uioc_mimd.data; + uioc->u_dataaddr = uioc_mimd.data; break; case MEGAIOC_QADAPINFO: /* Get adapter information */ uioc->opcode = GET_ADAP_INFO; uioc->adapno = uioc_mimd.ui.fcs.adapno; - uioc->uioc_uaddr = uioc_mimd.data; + uioc->u_dataaddr = uioc_mimd.data; break; default: @@ -4674,9 +4595,16 @@ uioc->opcode = MBOX_CMD; uioc->adapno = uioc_mimd.ui.fcs.adapno; - memcpy(uioc->uioc_rmbox, uioc_mimd.mbox, 18); + memcpy(&uioc->u_mbox, uioc_mimd.mbox, 18); uioc->xferlen = uioc_mimd.ui.fcs.length; + uioc->u_dataaddr = uioc_mimd.ui.fcs.buffer; + + if (uioc_mimd.mbox[0] == MEGA_MBOXCMD_PASSTHRU ) { + memcpy(&uioc->pthru,&uioc_mimd.pthru, + sizeof(mega_passthru)); + + } if( uioc_mimd.outlen ) uioc->flags = UIOC_RD; if( uioc_mimd.inlen ) uioc->flags |= UIOC_WR; @@ -4688,13 +4616,20 @@ uioc->opcode = MBOX_CMD; uioc->adapno = uioc_mimd.ui.fcs.adapno; - memcpy(uioc->uioc_rmbox, uioc_mimd.mbox, 18); + memcpy(&uioc->u_mbox, uioc_mimd.mbox, 18); /* * Choose the xferlen bigger of input and output data */ uioc->xferlen = uioc_mimd.outlen > uioc_mimd.inlen ? uioc_mimd.outlen : uioc_mimd.inlen; + uioc->u_dataaddr = uioc_mimd.data; + + if (uioc_mimd.mbox[0] == MEGA_MBOXCMD_PASSTHRU ) { + memcpy(&uioc->pthru,&uioc_mimd.pthru, + sizeof(mega_passthru)); + + } if( uioc_mimd.outlen ) uioc->flags = UIOC_RD; if( uioc_mimd.inlen ) uioc->flags |= UIOC_WR; @@ -4735,20 +4670,14 @@ if( memcmp(signature, "MEGANIT", 7) == 0 ) { - uiocp = (nitioctl_t *)arg; - - if( put_user(mc->status, (u8 *)&MBOX_P(uiocp)->status) ) - return (-EFAULT); - - if( mc->cmd == MEGA_MBOXCMD_PASSTHRU ) { - - umc = MBOX_P(uiocp); - - upthru = (mega_passthru *)((ulong)(umc->xferaddr)); - if( put_user(mc->status, (u8 *)&upthru->scsistatus) ) - return (-EFAULT); - } + /* + * NOTE: The nit ioctl is still under flux because of + * change of mailbox definition, in HPE. No applications yet + * use this interface and let's not have applications use this + * interface till the new specifitions are in place. + */ + return -EINVAL; } else { uioc_mimd = (struct uioctl_t *)arg; @@ -4763,8 +4692,7 @@ if (copy_from_user(&kmc, umc, sizeof(megacmd_t))) { return -EFAULT; } - - upthru = (mega_passthru *)((ulong)kmc.xferaddr); + upthru = (mega_passthru *)((ulong)&uioc_mimd->pthru); if( put_user(mc->status, (u8 *)&upthru->scsistatus) ){ return (-EFAULT); @@ -5179,6 +5107,55 @@ } + +/** + * mega_get_ldrv_num() + * @adapter - pointer to our soft state + * @cmd - scsi mid layer command + * @channel - channel on the controller + * + * Calculate the logical drive number based on the information in scsi command + * and the channel number. + */ +static inline int +mega_get_ldrv_num(adapter_t *adapter, Scsi_Cmnd *cmd, int channel) +{ + int tgt; + int ldrv_num; + + tgt = cmd->target; + + if ( tgt > adapter->this_id ) + tgt--; /* we do not get inquires for initiator id */ + + ldrv_num = (channel * 15) + tgt; + + + /* + * If we have a logical drive with boot enabled, project it first + */ + if( adapter->boot_ldrv_enabled ) { + if( ldrv_num == 0 ) { + ldrv_num = adapter->boot_ldrv; + } + else { + if( ldrv_num <= adapter->boot_ldrv ) { + ldrv_num--; + } + } + } + + /* + * If "delete logical drive" feature is enabled on this controller, + * the value returned should be 0x80+logical drive id. + */ + if (adapter->support_random_del) + ldrv_num += 0x80; + + return ldrv_num; +} + + /** * mega_reorder_hosts() * @@ -5393,6 +5370,26 @@ } +/** + * mega_allocate_inquiry() + * @dma_handle - handle returned for dma address + * @pdev - handle to pci device + * + * allocates memory for inquiry structure + */ +static inline caddr_t +mega_allocate_inquiry(dma_addr_t *dma_handle, struct pci_dev *pdev) +{ + return pci_alloc_consistent(pdev, sizeof(mega_inquiry3), dma_handle); +} + + +static inline void +mega_free_inquiry(caddr_t inquiry, dma_addr_t dma_handle, struct pci_dev *pdev) +{ + pci_free_consistent(pdev, sizeof(mega_inquiry3), inquiry, dma_handle); +} + /** mega_internal_dev_inquiry() * @adapter - pointer to our soft state diff -Naur old/drivers/scsi/megaraid2.h new/drivers/scsi/megaraid2.h --- old/drivers/scsi/megaraid2.h 2005-07-15 07:52:27.558936976 -0400 +++ new/drivers/scsi/megaraid2.h 2005-07-15 07:52:18.566304064 -0400 @@ -6,7 +6,7 @@ #define MEGARAID_VERSION \ - "v2.10.8.2 (Release Date: Mon Jul 26 12:15:51 EDT 2004)\n" + "v2.10.10.1 (Release Date: Thu Jan 27 16:19:44 EDT 2005)\n" /* * Driver features - change the values to enable or disable features in the @@ -83,6 +83,7 @@ #define INTEL_SUBSYS_VID 0x8086 #define FSC_SUBSYS_VID 0x1734 #define ACER_SUBSYS_VID 0x1025 +#define NEC_SUBSYS_VID 0x1033 #define HBA_SIGNATURE 0x3344 #define HBA_SIGNATURE_471 0xCCCC @@ -143,7 +144,8 @@ .eh_device_reset_handler = megaraid_reset, \ .eh_bus_reset_handler = megaraid_reset, \ .eh_host_reset_handler = megaraid_reset, \ - .highmem_io = 1 \ + .highmem_io = 1, \ + .vary_io = 1 \ } @@ -707,15 +709,15 @@ char signature[8]; /* Must contain "MEGANIT" */ u32 opcode; /* opcode for the command */ u32 adapno; /* adapter number */ - union { - u8 __raw_mbox[18]; - caddr_t __uaddr; /* xferaddr for non-mbox cmds */ - }__ua; - -#define uioc_rmbox __ua.__raw_mbox -#define MBOX(uioc) ((megacmd_t *)&((uioc).__ua.__raw_mbox[0])) -#define MBOX_P(uioc) ((megacmd_t *)&((uioc)->__ua.__raw_mbox[0])) -#define uioc_uaddr __ua.__uaddr + mbox_t u_mbox; /* user mailbox */ + caddr_t u_dataaddr; /* xferaddr for DCMD and non-mbox + commands */ + mega_passthru pthru; + +#define RMBOX(uioc) ((u8 *)&(uioc).u_mbox) +#define MBOX(uioc) ((megacmd_t *)&(uioc).u_mbox) +#define MBOX_P(uioc) ((megacmd_t *)&(uioc)->u_mbox) + u32 xferlen; /* xferlen for DCMD and non-mbox commands */ @@ -1128,7 +1130,7 @@ u32 *buffer, u32 *length); static inline int mega_busywait_mbox (adapter_t *); static int __mega_busywait_mbox (adapter_t *); -static void mega_cmd_done(adapter_t *, u8 [], int, int); +static inline void mega_cmd_done(adapter_t *, u8 [], int, int); static inline void mega_free_sgl (adapter_t *adapter); static void mega_8_to_40ld (mraid_inquiry *inquiry, mega_inquiry3 *enquiry3, mega_product_info *); @@ -1137,7 +1139,14 @@ unsigned long, void *); static int megadev_open (struct inode *, struct file *); -#if defined(__x86_64__) +#if defined(CONFIG_COMPAT) || defined( __x86_64__) || defined(IA32_EMULATION) +#ifndef __ia64__ +#define LSI_CONFIG_COMPAT +#endif +#endif + + +#ifdef LSI_CONFIG_COMPAT static int megadev_compat_ioctl(unsigned int, unsigned int, unsigned long, struct file *); #endif ---
Attachment:
megaraid2_for_2.4.31.patch
Description: Binary data