megaraid 2.00.09
PATCH 1/1 megaraid 2.00.09
Hi All,
This is a patch to the megaraid driver from LSI.
James
megaraid.c +494 -428
@@ -2,7 +2,7 @@* * Linux MegaRAID device driver * -* Copyright © 2002 LSI Logic Corporation. +* Copyright © 2002 LSI Logic Corporation. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License
@@ -14,7 +14,8 @@* - speed-ups (list handling fixes, issued_list, optimizations.) * - lots of cleanups. * -* Version : v2.00.3 (Feb 19, 2003) - Atul Mukker <[email protected]> +* Version : v2.00.9a-kernel 2.6 (Oct 03, 2003) - +* Atul Mukker <[email protected]> * * Description: Linux device driver for LSI Logic MegaRAID controller *
@@ -77,7 +78,9 @@static int hba_count;static adapter_t *hba_soft_state[MAX_CONTROLLERS ]; +#ifdef CONFIG_PROC_FS static struct proc_dir_entry *mega_proc_dir_entry; +#endif static struct notifier_block mega_notifier = { .notifier_call = megaraid_reboot_notify
@@ -160,16 +163,11 @@PCI_VENDOR_ID_INTEL ,PCI_DEVICE_ID_AMI_MEGARAID3 , PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_AMI_MEGARAID3 }; - host_template->proc_name ="megaraid" ;printk (KERN_NOTICE "megaraid: " MEGARAID_VERSION );megaraid_validate_parms (); -memset (mega_hbas,0 ,sizeof (mega_hbas)); - - hba_count =0 ; -/* * Scan PCI bus for our all devices. */
@@ -250,6 +248,7 @@u8 did_ioremap_f =0 ;u8 did_req_region_f =0 ;u8 did_scsi_reg_f =0 ; +u8 got_ipdev_f =0 ;u8 alloc_int_buf_f =0 ;u8 alloc_scb_f =0 ;u8 got_irq_f =0 ;
@@ -260,6 +259,16 @@while ((pdev =pci_find_device (pci_vendor, pci_device, pdev))) { +// reset flags for all controllers in this class + did_ioremap_f =0 ; + did_req_region_f =0 ; + did_scsi_reg_f =0 ; + got_ipdev_f =0 ; + alloc_int_buf_f =0 ; + alloc_scb_f =0 ; + got_irq_f =0 ; + did_setup_mbox_f =0 ; +if (pci_enable_device (pdev))continue ; pci_bus = pdev->bus->number;
@@ -295,6 +304,7 @@if ( subsysvid && (subsysvid !=AMI_SUBSYS_VID ) && (subsysvid !=DELL_SUBSYS_VID ) && (subsysvid !=HP_SUBSYS_VID ) && + (subsysvid !=INTEL_SUBSYS_VID ) && (subsysvid !=LSI_SUBSYS_VID ) )continue ;
@@ -358,6 +368,21 @@ adapter = (adapter_t *)host->hostdata;memset (adapter,0 ,sizeof (adapter_t)); +/* +* Allocate a pci device structure for allocations done +* internally - all of which would be in memory <4GB +*/ + adapter->ipdev =kmalloc (sizeof (struct pci_dev ),GFP_KERNEL ); + +if ( adapter->ipdev ==NULL ) goto fail_attach; + + got_ipdev_f =1 ; + +memcpy (adapter->ipdev, pdev,sizeof (struct pci_dev )); + +if (pci_set_dma_mask (adapter->ipdev,0xffffffff ) !=0 ) + goto fail_attach; +printk (KERN_NOTICE "scsi%d:Found MegaRAID controller at 0x%lx, IRQ:%d\n" , host->host_no, mega_baseport, irq);
@@ -367,10 +392,12 @@/* Copy resource info into structure */ INIT_LIST_HEAD (&adapter->free_list);INIT_LIST_HEAD (&adapter->pending_list); -INIT_LIST_HEAD (&adapter->completed_list); adapter->flag = flag;spin_lock_init (&adapter->lock); + + adapter->host_lock = &adapter->lock; +scsi_assign_lock (host, &adapter->lock); host->cmd_per_lun = max_cmd_per_lun;
@@ -593,7 +620,7 @@pci_set_dma_mask (pdev,0xffffffff ); adapter->has_64bit_addr =0 ; } - +init_MUTEX (&adapter->int_mtx);init_waitqueue_head (&adapter->int_waitq);
@@ -642,6 +669,8 @@ adapter->buf_dma_handle); } +if ( got_ipdev_f )kfree (adapter->ipdev); +if ( did_scsi_reg_f )scsi_unregister (host);if ( did_ioremap_f ) {
@@ -672,7 +701,7 @@ sizeof(mbox64_t), &adapter->una_mbox64_dma);if ( !adapter->una_mbox64 )return -1 ; - + adapter->mbox = &adapter->una_mbox64->mbox; adapter->mbox = (mbox_t *)((((unsigned long) adapter->mbox) + 15) &
@@ -725,7 +754,7 @@ {dma_addr_t prod_info_dma_handle;mega_inquiry3 *inquiry3; -u8 raw_mbox[sizeof (struct mbox_out )]; +u8 raw_mbox[sizeof (mbox_t)];mbox_t *mbox;int retval;
@@ -734,14 +763,14 @@ mbox = (mbox_t *)raw_mbox;memset ((void *)adapter->mega_buffer,0 ,MEGA_BUFFER_SIZE ); -memset (&mbox->m_out,0 ,sizeof (raw_mbox)); +memset (raw_mbox,0 ,sizeof (raw_mbox));/* * Try to issue Inquiry3 command * if not succeeded, then issue MEGA_MBOXCMD_ADAPTERINQ command and * update enquiry3 structure */ - mbox->m_out.xferaddr = (u32 )adapter->buf_dma_handle; + mbox->xferaddr = (u32 )adapter->buf_dma_handle; inquiry3 = (mega_inquiry3 *)adapter->mega_buffer;
@@ -764,10 +793,10 @@ inq = &ext_inq->raid_inq; - mbox->m_out.xferaddr = (u32 )dma_handle; + mbox->xferaddr = (u32 )dma_handle;/*issue old 0x04 command to adapter */ - mbox->m_out.cmd =MEGA_MBOXCMD_ADPEXTINQ ; + mbox->cmd =MEGA_MBOXCMD_ADPEXTINQ ;issue_scb_block (adapter, raw_mbox);
@@ -792,7 +821,7 @@ &adapter->product_info, sizeof(mega_product_info), PCI_DMA_FROMDEVICE); - mbox->m_out.xferaddr = prod_info_dma_handle; + mbox->xferaddr = prod_info_dma_handle; raw_mbox[0 ] =FC_NEW_CONFIG ;/* i.e. mbox->cmd=0xA1 */ raw_mbox[2 ] =NC_SUBOP_PRODUCT_INFO ;/* i.e. 0x0E */
@@ -986,7 +1015,7 @@ }else {/* this is physical channel */ - channel = cmd->device->channel; + channel = cmd->device->channel; target = cmd->device->id;/*
@@ -1005,11 +1034,11 @@else {if ( islogical ) {/* this is the logical channel */ - channel = cmd->device->channel; + channel = cmd->device->channel; }else {/* physical channel */ - channel = cmd->device->channel -NVIRT_CHAN ; + channel = cmd->device->channel -NVIRT_CHAN ; target = cmd->device->id; } }
@@ -1143,10 +1172,10 @@memcpy (pthru->cdb, cmd->cmnd, cmd->cmd_len);if ( adapter->has_64bit_addr ) { - mbox->m_out.cmd =MEGA_MBOXCMD_PASSTHRU64 ; + mbox->cmd =MEGA_MBOXCMD_PASSTHRU64 ; }else { - mbox->m_out.cmd =MEGA_MBOXCMD_PASSTHRU ; + mbox->cmd =MEGA_MBOXCMD_PASSTHRU ; } scb->dma_direction =PCI_DMA_FROMDEVICE ;
@@ -1154,7 +1183,7 @@ pthru->numsgelements =mega_build_sglist (adapter, scb, &pthru->dataxferaddr, &pthru->dataxferlen); - mbox->m_out.xferaddr = scb->pthru_dma_addr; + mbox->xferaddr = scb->pthru_dma_addr;return scb;
@@ -1177,19 +1206,19 @@ mbox = (mbox_t *)scb->raw_mbox;memset (mbox,0 ,sizeof (scb->raw_mbox)); - mbox->m_out.logdrv = ldrv_num; + mbox->logdrv = ldrv_num;/* * A little hack: 2nd bit is zero for all scsi read * commands and is set for all scsi write commands */ if ( adapter->has_64bit_addr ) { - mbox->m_out.cmd = (*cmd->cmnd &0x02 ) ? + mbox->cmd = (*cmd->cmnd &0x02 ) ?MEGA_MBOXCMD_LWRITE64 :MEGA_MBOXCMD_LREAD64 ; }else { - mbox->m_out.cmd = (*cmd->cmnd &0x02 ) ? + mbox->cmd = (*cmd->cmnd &0x02 ) ?MEGA_MBOXCMD_LWRITE :MEGA_MBOXCMD_LREAD ; }
@@ -1198,13 +1227,13 @@* 6-byte READ(0x08) or WRITE(0x0A) cdb */ if ( cmd->cmd_len ==6 ) { - mbox->m_out.numsectors = (u32 ) cmd->cmnd[4 ]; - mbox->m_out.lba = + mbox->numsectors = (u32 ) cmd->cmnd[4 ]; + mbox->lba = ((u32 )cmd->cmnd[1 ] <<16 ) | ((u32 )cmd->cmnd[2 ] <<8 ) | (u32 )cmd->cmnd[3 ]; - mbox->m_out.lba &=0x1FFFFF ; + mbox->lba &=0x1FFFFF ;#if MEGA_HAVE_STATS /*
@@ -1215,11 +1244,11 @@if (*cmd->cmnd ==READ_6 ) { adapter->nreads[ldrv_num%0x80 ]++; adapter->nreadblocks[ldrv_num%0x80 ] += - mbox->m_out.numsectors; + mbox->numsectors; }else { adapter->nwrites[ldrv_num%0x80 ]++; adapter->nwriteblocks[ldrv_num%0x80 ] += - mbox->m_out.numsectors; + mbox->numsectors; }#endif }
@@ -1228,10 +1257,10 @@* 10-byte READ(0x28) or WRITE(0x2A) cdb */ if ( cmd->cmd_len ==10 ) { - mbox->m_out.numsectors = + mbox->numsectors = (u32 )cmd->cmnd[8 ] | ((u32 )cmd->cmnd[7 ] <<8 ); - mbox->m_out.lba = + mbox->lba = ((u32 )cmd->cmnd[2 ] <<24 ) | ((u32 )cmd->cmnd[3 ] <<16 ) | ((u32)cmd->cmnd[4] << 8) |
@@ -1241,11 +1270,11 @@if (*cmd->cmnd ==READ_10 ) { adapter->nreads[ldrv_num%0x80 ]++; adapter->nreadblocks[ldrv_num%0x80 ] += - mbox->m_out.numsectors; + mbox->numsectors; }else { adapter->nwrites[ldrv_num%0x80 ]++; adapter->nwriteblocks[ldrv_num%0x80 ] += - mbox->m_out.numsectors; + mbox->numsectors; }#endif }
@@ -1254,13 +1283,13 @@* 12-byte READ(0xA8) or WRITE(0xAA) cdb */ if ( cmd->cmd_len ==12 ) { - mbox->m_out.lba = + mbox->lba = ((u32 )cmd->cmnd[2 ] <<24 ) | ((u32 )cmd->cmnd[3 ] <<16 ) | ((u32 )cmd->cmnd[4 ] <<8 ) | (u32 )cmd->cmnd[5 ]; - mbox->m_out.numsectors = + mbox->numsectors = ((u32 )cmd->cmnd[6 ] <<24 ) | ((u32 )cmd->cmnd[7 ] <<16 ) | ((u32)cmd->cmnd[8] << 8) |
@@ -1270,11 +1299,11 @@if (*cmd->cmnd ==READ_12 ) { adapter->nreads[ldrv_num%0x80 ]++; adapter->nreadblocks[ldrv_num%0x80 ] += - mbox->m_out.numsectors; + mbox->numsectors; }else { adapter->nwrites[ldrv_num%0x80 ]++; adapter->nwriteblocks[ldrv_num%0x80 ] += - mbox->m_out.numsectors; + mbox->numsectors; }#endif }
@@ -1290,8 +1319,8 @@ }/* Calculate Scatter-Gather info */ - mbox->m_out.numsgelements =mega_build_sglist (adapter, scb, - (u32 *)&mbox->m_out.xferaddr, (u32 *)&seg); + mbox->numsgelements =mega_build_sglist (adapter, scb, + (u32 *)&mbox->xferaddr, (u32 *)&seg);return scb;
@@ -1359,9 +1388,9 @@ epthru =mega_prepare_extpassthru (adapter, scb, cmd, channel, target); - mbox->m_out.cmd =MEGA_MBOXCMD_EXTPTHRU ; + mbox->cmd =MEGA_MBOXCMD_EXTPTHRU ; - mbox->m_out.xferaddr = scb->epthru_dma_addr; + mbox->xferaddr = scb->epthru_dma_addr; }else {
@@ -1371,13 +1400,13 @@/* Initialize mailbox */ if ( adapter->has_64bit_addr ) { - mbox->m_out.cmd =MEGA_MBOXCMD_PASSTHRU64 ; + mbox->cmd =MEGA_MBOXCMD_PASSTHRU64 ; }else { - mbox->m_out.cmd =MEGA_MBOXCMD_PASSTHRU ; + mbox->cmd =MEGA_MBOXCMD_PASSTHRU ; } - mbox->m_out.xferaddr = scb->pthru_dma_addr; + mbox->xferaddr = scb->pthru_dma_addr; }return scb;
@@ -1595,21 +1624,20 @@volatile mbox_t *mbox = adapter->mbox;unsigned int i =0 ; -if (unlikely (mbox->m_in.busy)) { +if (unlikely (mbox->busy)) {do {udelay (1 ); i++; - }while ( mbox->m_in.busy && (i < max_mbox_busy_wait) ); + }while ( mbox->busy && (i < max_mbox_busy_wait) ); -if (mbox->m_in.busy)return -1 ; +if (mbox->busy)return -1 ; }/* Copy mailbox data into host structure */ -memcpy ((char *)&mbox->m_out, (char *)scb->raw_mbox, -sizeof (struct mbox_out )); +memcpy ((char *)mbox, (char *)scb->raw_mbox,16 ); - mbox->m_out.cmdid = scb->idx;/* Set cmdid */ - mbox->m_in.busy =1 ;/* Set busy */ + mbox->cmdid = scb->idx;/* Set cmdid */ + mbox->busy =1 ;/* Set busy */ /*
@@ -1617,14 +1645,16 @@*/ atomic_inc (&adapter->pend_cmds); -switch (mbox->m_out.cmd) { +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 : -case MEGA_MBOXCMD_EXTPTHRU : - mbox64->xfer_segment_lo = mbox->m_out.xferaddr; + mbox64->xfer_segment_lo = mbox->xferaddr; mbox64->xfer_segment_hi =0 ; - mbox->m_out.xferaddr =0xFFFFFFFF ; + mbox->xferaddr =0xFFFFFFFF ;break ;default : mbox64->xfer_segment_lo =0 ;
@@ -1637,8 +1667,8 @@ scb->state |=SCB_ISSUED ;if (likely (adapter->flag &BOARD_MEMMAP ) ) { - mbox->m_in.poll =0 ; - mbox->m_in.ack =0 ; + mbox->poll =0 ; + mbox->ack =0 ;WRINDOOR (adapter, adapter->mbox_dma |0x1 ); }else {
@@ -1663,24 +1693,28 @@volatile mbox64_t *mbox64 = adapter->mbox64;volatile mbox_t *mbox = adapter->mbox;u8 byte; +u8 status; +int i;/* Wait until mailbox is free */ if (mega_busywait_mbox (adapter)) goto bug_blocked_mailbox;/* Copy mailbox data into host structure */ -memcpy ((char *) mbox, raw_mbox,sizeof (struct mbox_out )); - mbox->m_out.cmdid =0xFE ; - mbox->m_in.busy =1 ; +memcpy ((char *) mbox, raw_mbox,16 ); + mbox->cmdid =0xFE ; + mbox->busy =1 ;switch (raw_mbox[0 ]) { +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 : -case MEGA_MBOXCMD_EXTPTHRU : - mbox64->xfer_segment_lo = mbox->m_out.xferaddr; + mbox64->xfer_segment_lo = mbox->xferaddr; mbox64->xfer_segment_hi =0 ; - mbox->m_out.xferaddr =0xFFFFFFFF ; + mbox->xferaddr =0xFFFFFFFF ;break ;default : mbox64->xfer_segment_lo =0 ;
@@ -1688,22 +1722,28 @@ }if (likely (adapter->flag &BOARD_MEMMAP ) ) { - mbox->m_in.poll =0 ; - mbox->m_in.ack =0 ; - mbox->m_in.numstatus =0xFF ; - mbox->m_in.status =0xFF ; + mbox->poll =0 ; + mbox->ack =0 ; + mbox->numstatus =0xFF ; + mbox->status =0xFF ;WRINDOOR (adapter, adapter->mbox_dma |0x1 ); -while ((volatile u8 )mbox->m_in.numstatus ==0xFF ) +while (mbox->numstatus ==0xFF )cpu_relax (); - mbox->m_in.numstatus =0xFF ; + mbox->numstatus =0xFF ; -while ( (volatile u8 )mbox->m_in.poll !=0x77 ) +while (mbox->status ==0xFF )cpu_relax (); - mbox->m_in.poll =0 ; - mbox->m_in.ack =0x77 ; + status = mbox->status; + mbox->status =0xFF ; + +while (mbox->poll !=0x77 ) +cpu_relax (); + + mbox->poll =0 ; + mbox->ack =0x77 ;WRINDOOR (adapter, adapter->mbox_dma |0x2 );
@@ -1717,12 +1757,22 @@while (!((byte =irq_state (adapter)) &INTR_VALID ))cpu_relax (); + status = mbox->status; + mbox->numstatus =0xFF ; + mbox->status =0xFF ; +set_irq_state (adapter, byte);irq_enable (adapter);irq_ack (adapter); } -return mbox->m_in.status; +// invalidate the completed command id array. After command +// completion, firmware would write the valid id. +for (i =0 ; i <MAX_FIRMWARE_STATUS ; i++) { + mbox->completed[i] =0xFF ; + } + +return status; bug_blocked_mailbox:printk (KERN_WARNING "megaraid: Blocked mailbox......!!\n" );
@@ -1746,65 +1796,86 @@ {adapter_t *adapter = devp;unsigned long flags; +int rval; + + +spin_lock_irqsave (adapter->host_lock, flags); + + rval =megaraid_iombox_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 IRQ_RETVAL (rval); +} + + +/** +* 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 int +megaraid_iombox_ack_sequence (adapter_t *adapter) +{u8 status;u8 nstatus;u8 completed[MAX_FIRMWARE_STATUS ];u8 byte; -int handled =0 ; +int i; +int irq_handled =0 ;/* * loop till F/W has more commands for us to complete. */ -spin_lock_irqsave (&adapter->lock, flags); -do {/* Check if a valid interrupt is pending */ byte =irq_state (adapter);if ( (byte &VALID_INTR_BYTE ) ==0 ) { -/* -* No more pending commands -*/ - goto out_unlock; +return irq_handled; }set_irq_state (adapter, byte); -while ((nstatus = (volatile u8 )adapter->mbox->m_in.numstatus) - ==0xFF ) +while ((nstatus = adapter->mbox->numstatus) ==0xFF ) {cpu_relax (); - adapter->mbox->m_in.numstatus =0xFF ; + } + 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 ; + } - status = adapter->mbox->m_in.status; +// 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); -memcpy (completed, (void *)adapter->mbox->m_in.completed, - nstatus); -/* Acknowledge interrupt */ irq_ack (adapter);mega_cmd_done (adapter, completed, nstatus, status); -mega_rundoneq (adapter); - - handled =1 ; - -/* Loop through any pending requests */ -if (atomic_read (&adapter->quiescent) ==0 ) { -mega_runpendq (adapter); - } + irq_handled =1 ; }while (1 ); - - out_unlock: - -spin_unlock_irqrestore (&adapter->lock, flags); - -return IRQ_RETVAL (handled); }
@@ -1823,69 +1894,94 @@ {adapter_t *adapter = devp;unsigned long flags; +int rval; + + +spin_lock_irqsave (adapter->host_lock, flags); + + rval =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 IRQ_RETVAL (rval); +} + + +/** +* megaraid_memmbox_ack_sequence - interrupt ack sequence for memory mapped HBAs +* @adapter - controller's soft state +* +* Interrupt ackrowledgement sequence for memory mapped HBAs +*/ +static inline int +megaraid_memmbox_ack_sequence (adapter_t *adapter) +{u8 status;u32 dword =0 ;u8 nstatus;u8 completed[MAX_FIRMWARE_STATUS ]; -int handled =0 ; +int i; +int irq_handled =0 ;/* * loop till F/W has more commands for us to complete. */ -spin_lock_irqsave (&adapter->lock, flags); -do {/* Check if a valid interrupt is pending */ dword =RDOUTDOOR (adapter); -if (dword !=0x10001234 ) { +if ( dword !=0x10001234 ) {/* * No more pending commands */ - goto out_unlock; +return irq_handled; }WROUTDOOR (adapter,0x10001234 ); -while ((nstatus = (volatile u8 )adapter->mbox->m_in.numstatus) - ==0xFF ) { +while ((nstatus = adapter->mbox->numstatus) ==0xFF ) {cpu_relax (); } - adapter->mbox->m_in.numstatus =0xFF ; + adapter->mbox->numstatus =0xFF ; - status = adapter->mbox->m_in.status; +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); -memcpy (completed, (void *)adapter->mbox->m_in.completed, - nstatus); -/* Acknowledge interrupt */ WRINDOOR (adapter,0x2 ); - handled =1 ; -while (RDINDOOR (adapter) &0x02 )cpu_relax ();mega_cmd_done (adapter, completed, nstatus, status); -mega_rundoneq (adapter); - -/* Loop through any pending requests */ -if (atomic_read (&adapter->quiescent) ==0 ) { -mega_runpendq (adapter); - } + irq_handled =1 ; }while (1 ); +} - out_unlock: - -spin_unlock_irqrestore (&adapter->lock, flags); -return IRQ_RETVAL (handled); -}/** * mega_cmd_done() * @adapter - pointer to our soft state
@@ -1903,9 +1999,9 @@Scsi_Cmnd *cmd =NULL ;mega_passthru *pthru =NULL ;mbox_t *mbox =NULL ; +int islogical;u8 c;scb_t *scb; -int islogical;int cmdid;int i;
@@ -1931,6 +2027,10 @@ }else { scb = &adapter->scb_list[cmdid]; + cmd = scb->cmd; + pthru = scb->pthru; + epthru = scb->epthru; + mbox = (mbox_t *)scb->raw_mbox;/* * Make sure f/w has completed a valid command
@@ -1945,21 +2045,20 @@ }/* -* Was a abort issued for this command +* Was an abort issued for this command */ if ( scb->state &SCB_ABORT ) { -printk (KERN_WARNING +printk (KERN_NOTICE "megaraid: aborted cmd %lx[%x] complete.\n" , scb->cmd->serial_number, scb->idx); - scb->cmd->result = (DID_ABORT <<16 ); - -list_add_tail (SCSI_LIST (scb->cmd), - &adapter->completed_list); + cmd->result = (DID_ABORT <<16 );mega_free_scb (adapter, scb); + cmd->scsi_done (cmd); +continue ; }
@@ -1974,25 +2073,20 @@ scb->cmd->result = (DID_RESET <<16 ); -list_add_tail (SCSI_LIST (scb->cmd), - &adapter->completed_list); -mega_free_scb (adapter, scb); + cmd->scsi_done (cmd); +continue ; } - cmd = scb->cmd; - pthru = scb->pthru; - epthru = scb->epthru; - mbox = (mbox_t *)scb->raw_mbox; -#if MEGA_HAVE_STATS { -int logdrv = mbox->m_out.logdrv; +int logdrv = mbox->logdrv; islogical = adapter->logdrv_chan[cmd->channel]; +/* * Maintain an error counter for the logical drive. * Some application like SNMP agent need such
@@ -2029,7 +2123,7 @@* PJ */ islogical = adapter->logdrv_chan[cmd->device->channel]; -if ( cmd->cmnd[0 ] ==INQUIRY && !islogical ) { +if (cmd->cmnd[0 ] ==INQUIRY && !islogical) {if ( cmd->use_sg ) { sgl = (struct scatterlist *)
@@ -2037,8 +2131,8 @@if ( sgl->page ) { c = *(unsigned char *) -page_address ((&sgl[0 ])->page) + - (&sgl[0 ])->offset; +page_address ((&sgl[0 ])->page) + + (&sgl[0 ])->offset; }else { printk(KERN_WARNING
@@ -2069,8 +2163,8 @@SCSI_STATUS_CHECK_CONDITION */ /* set sense_buffer and result fields */ -if ( mbox->m_out.cmd ==MEGA_MBOXCMD_PASSTHRU || - mbox->m_out.cmd ==MEGA_MBOXCMD_PASSTHRU64 ) { +if ( mbox->cmd ==MEGA_MBOXCMD_PASSTHRU || + mbox->cmd ==MEGA_MBOXCMD_PASSTHRU64 ) {memcpy (cmd->sense_buffer, pthru->reqsensearea,14 );
@@ -2080,7 +2174,7 @@ (CHECK_CONDITION <<1 ); }else { -if (mbox->m_out.cmd ==MEGA_MBOXCMD_EXTPTHRU ) { +if (mbox->cmd ==MEGA_MBOXCMD_EXTPTHRU ) {memcpy (cmd->sense_buffer, epthru->reqsensearea,14 );
@@ -2148,32 +2242,11 @@mega_free_scb (adapter, scb); } -/* Add Scsi_Command to end of completed queue */ -list_add_tail (SCSI_LIST (cmd), &adapter->completed_list); - } -} - - -/* -* mega_runpendq() -* -* Run through the list of completed requests and finish it -*/ -static void -mega_rundoneq (adapter_t *adapter) -{ -Scsi_Cmnd *cmd; -struct list_head *pos; - -list_for_each (pos, &adapter->completed_list) { - -Scsi_Pointer * spos = (Scsi_Pointer *)pos; - - cmd =list_entry (spos, Scsi_Cmnd, SCp); +/* +* Call the mid-layer callback for this command +*/ cmd->scsi_done (cmd); } - -INIT_LIST_HEAD (&adapter->completed_list); }
@@ -2194,8 +2267,7 @@ scb->cmd->request_bufflen, scb->dma_direction);if ( scb->dma_direction ==PCI_DMA_FROMDEVICE ) { -pci_dma_sync_single (adapter->dev, - scb->dma_h_bulkdata, +pci_dma_sync_single (adapter->dev, scb->dma_h_bulkdata, scb->cmd->request_bufflen,PCI_DMA_FROMDEVICE ); }
@@ -2207,8 +2279,7 @@ scb->cmd->use_sg, scb->dma_direction);if ( scb->dma_direction ==PCI_DMA_FROMDEVICE ) { -pci_dma_sync_sg (adapter->dev, - scb->cmd->request_buffer, +pci_dma_sync_sg (adapter->dev, scb->cmd->request_buffer, scb->cmd->use_sg,PCI_DMA_FROMDEVICE ); }
@@ -2237,7 +2308,7 @@static inline int mega_busywait_mbox (adapter_t *adapter) { -if (adapter->mbox->m_in.busy) +if (adapter->mbox->busy)return __mega_busywait_mbox (adapter);return 0 ; }
@@ -2249,7 +2320,7 @@long counter;for (counter =0 ; counter <10000 ; counter++) { -if (!mbox->m_in.busy) +if (!mbox->busy)return 0 ;udelay (100 );yield (); }
@@ -2278,8 +2349,7 @@ page =virt_to_page (cmd->request_buffer); offset =offset_in_page (cmd->request_buffer); - scb->dma_h_bulkdata =pci_map_page (adapter->dev, - page, offset, + scb->dma_h_bulkdata =pci_map_page (adapter->dev, page, offset, cmd->request_bufflen, scb->dma_direction); scb->dma_type =MEGA_BULK_DATA ;
@@ -2317,8 +2387,7 @@* * The number of sg elements returned must not exceed our limit */ - sgcnt =pci_map_sg (adapter->dev, sgl, cmd->use_sg, - scb->dma_direction); + sgcnt =pci_map_sg (adapter->dev, sgl, cmd->use_sg, scb->dma_direction); scb->dma_type =MEGA_SGLIST ;
@@ -2395,6 +2464,7 @@ enquiry3->pdrv_state[i] = inquiry->pdrv_info.pdrv_state[i]; } +/* * Release the controller's resources */
@@ -2403,8 +2473,10 @@ {adapter_t *adapter;mbox_t *mbox; -u_char raw_mbox[sizeof (struct mbox_out )]; +u_char raw_mbox[sizeof (mbox_t)]; +#ifdef CONFIG_PROC_FS char buf[12 ] = {0 }; +#endif adapter = (adapter_t *)host->hostdata; mbox = (mbox_t *)raw_mbox;
@@ -2412,7 +2484,7 @@printk (KERN_NOTICE "megaraid: being unloaded..." );/* Flush adapter cache */ -memset (&mbox->m_out,0 ,sizeof (raw_mbox)); +memset (raw_mbox,0 ,sizeof (raw_mbox)); raw_mbox[0 ] =FLUSH_ADAPTER ;irq_disable (adapter);
@@ -2422,7 +2494,7 @@issue_scb_block (adapter, raw_mbox);/* Flush disks cache */ -memset (&mbox->m_out,0 ,sizeof (raw_mbox)); +memset (raw_mbox,0 ,sizeof (raw_mbox)); raw_mbox[0 ] =FLUSH_SYSTEM ;/* Issue a blocking (interrupts disabled) command to the card */
@@ -2483,6 +2555,8 @@pci_free_consistent (adapter->dev,sizeof (mbox64_t), (void *)adapter->una_mbox64, adapter->una_mbox64_dma); +kfree (adapter->ipdev); + hba_count--;if ( hba_count ==0 ) {
@@ -2572,25 +2646,106 @@return buffer; } -/* + +/** +* megaraid_abort - abort the scsi command +* @scp - command to be aborted +* * Abort a previous SCSI request. Only commands on the pending list can be * aborted. All the commands issued to the F/W must complete. */ static int -megaraid_abort (Scsi_Cmnd *cmd) +megaraid_abort (Scsi_Cmnd *scp) { -adapter_t *adapter; -int rval; +adapter_t *adapter; +struct list_head *pos, *next; +scb_t *scb; +long iter; +int rval =SUCCESS ; - adapter = (adapter_t *)cmd->device->host->hostdata; + adapter = (adapter_t *)scp->device->host->hostdata; + +ASSERT (spin_is_locked (adapter->host_lock) ); - rval =megaraid_abort_and_reset (adapter, cmd,SCB_ABORT ); +printk ("megaraid: aborting-%ld cmd=%x <c=%d t=%d l=%d>\n" , + scp->serial_number, scp->cmnd[0 ], scp->device->channel, + scp->device->id, scp->device->lun); + + +list_for_each_safe ( pos, next, &adapter->pending_list ) { + + scb =list_entry (pos, scb_t, list); + +if ( scb->cmd == scp ) {/* Found command */ + + scb->state |=SCB_ABORT ; + +/* +* Check if this command was never issued. If this is +* the case, take it off from the pending list and +* complete. +*/ +if ( !(scb->state &SCB_ISSUED ) ) { + +printk (KERN_WARNING +"megaraid: %ld:%d, driver owner.\n" , + scp->serial_number, scb->idx); + + scp->result = (DID_ABORT <<16 ); + +mega_free_scb (adapter, scb); + + scp->scsi_done (scp); + +break ; + } + } + }/* -* This is required here to complete any completed requests -* to be communicated over to the mid layer. +* By this time, either all commands are completed or aborted by +* mid-layer. Do not return until all the commands are actually +* completed by the firmware */ -mega_rundoneq (adapter); + iter =0 ; +while (atomic_read (&adapter->pend_cmds) >0 ) { +/* +* Perform the ack sequence, since interrupts are not +* available right now! +*/ +if ( adapter->flag &BOARD_MEMMAP ) { +megaraid_memmbox_ack_sequence (adapter); + } +else { +megaraid_iombox_ack_sequence (adapter); + } + +/* +* print a message once every second only +*/ +if ( !(iter %1000 ) ) { +printk ( +"megaraid: Waiting for %d commands to flush: iter:%ld\n" , +atomic_read (&adapter->pend_cmds), iter); + } + +if ( iter++ <MBOX_ABORT_SLEEP *1000 ) { +mdelay (1 ); + } +else { +printk (KERN_WARNING +"megaraid: critical hardware error!\n" ); + + rval =FAILED ; + +break ; + } + } + +if ( rval ==SUCCESS ) { +printk (KERN_INFO +"megaraid: abort sequence successfully complete.\n" ); + }return rval; }
@@ -2601,15 +2756,23 @@ {adapter_t *adapter;megacmd_t mc; -int rval; +long iter; +int rval =SUCCESS ; adapter = (adapter_t *)cmd->device->host->hostdata; +ASSERT (spin_is_locked (adapter->host_lock) ); + +printk ("megaraid: reset-%ld cmd=%x <c=%d t=%d l=%d>\n" , + cmd->serial_number, cmd->cmnd[0 ], cmd->device->channel, + cmd->device->id, cmd->device->lun); + +#if MEGA_HAVE_CLUSTERING mc.cmd =MEGA_CLUSTER_CMD ; mc.opcode =MEGA_RESET_RESERVATIONS ; -spin_unlock_irq (&adapter->lock); +spin_unlock_irq (adapter->host_lock);if (mega_internal_command (adapter,LOCK_INT , &mc,NULL ) !=0 ) {printk (KERN_WARNING "megaraid: reservation reset failed.\n" );
@@ -2617,97 +2780,54 @@ else {printk (KERN_INFO "megaraid: reservation reset.\n" ); } -spin_lock_irq (&adapter->lock); +spin_lock_irq (adapter->host_lock);#endif - rval =megaraid_abort_and_reset (adapter, cmd,SCB_RESET ); -/* -* This is required here to complete any completed requests -* to be communicated over to the mid layer. +* Do not return until all the commands are actually completed by the +* firmware */ -mega_rundoneq (adapter); - -return rval; -} - - - -/** -* megaraid_abort_and_reset() -* @adapter - megaraid soft state -* @cmd - scsi command to be aborted or reset -* @aor - abort or reset flag -* -* Try to locate the scsi command in the pending queue. If found and is not -* issued to the controller, abort/reset it. Otherwise return failure -*/ -static int -megaraid_abort_and_reset (adapter_t *adapter,Scsi_Cmnd *cmd,int aor) -{ -struct list_head *pos, *next; -scb_t *scb; - -printk (KERN_WARNING "megaraid: %s-%lx cmd=%x <c=%d t=%d l=%d>\n" , - (aor ==SCB_ABORT )?"ABORTING" :"RESET" , cmd->serial_number, - cmd->cmnd[0 ], cmd->device->channel, - cmd->device->id, cmd->device->lun); - -if (list_empty (&adapter->pending_list)) -return FALSE; - -list_for_each_safe (pos, next, &adapter->pending_list) { - - scb =list_entry (pos, scb_t, list); - -if (scb->cmd == cmd) {/* Found command */ - - scb->state |= aor; - -/* -* Check if this command has firmare owenership. If -* yes, we cannot reset this command. Whenever, f/w -* completes this command, we will return appropriate -* status from ISR. -*/ -if ( scb->state &SCB_ISSUED ) { - -printk (KERN_WARNING -"megaraid: %s-%lx[%x], fw owner.\n" , - (aor==SCB_ABORT ) ?"ABORTING" :"RESET" , - cmd->serial_number, scb->idx); - -return FALSE; - } -else { - -/* -* Not yet issued! Remove from the pending -* list -*/ -printk (KERN_WARNING -"megaraid: %s-%lx[%x], driver owner.\n" , - (aor==SCB_ABORT ) ?"ABORTING" :"RESET" , - cmd->serial_number, scb->idx); + iter =0 ; +while (atomic_read (&adapter->pend_cmds) >0 ) { +/* +* Perform the ack sequence, since interrupts are not +* available right now! +*/ +if ( adapter->flag &BOARD_MEMMAP ) { +megaraid_memmbox_ack_sequence (adapter); + } +else { +megaraid_iombox_ack_sequence (adapter); + } -mega_free_scb (adapter, scb); +/* +* print a message once every second only +*/ +if ( !(iter %1000 ) ) { +printk ( +"megaraid: Waiting for %d commands to flush: iter:%ld\n" , +atomic_read (&adapter->pend_cmds), iter); + } -if ( aor ==SCB_ABORT ) { - cmd->result = (DID_ABORT <<16 ); - } -else { - cmd->result = (DID_RESET <<16 ); - } +if ( iter++ <MBOX_RESET_SLEEP *1000 ) { +mdelay (1 ); + } +else { +printk (KERN_WARNING +"megaraid: critical hardware error!\n" ); -list_add_tail (SCSI_LIST (cmd), - &adapter->completed_list); + rval =FAILED ; -return TRUE; - } +break ; } } -return FALSE; +if ( rval ==SUCCESS ) { +printk (KERN_INFO +"megaraid: reset sequence successfully complete.\n" ); + } + +return rval; }
@@ -2953,24 +3073,16 @@int len =0 ; len =sprintf (page,"Contents of Mail Box Structure\n" ); - len +=sprintf (page+len," Fw Command = 0x%02x\n" , - mbox->m_out.cmd); - len +=sprintf (page+len," Cmd Sequence = 0x%02x\n" , - mbox->m_out.cmdid); - len +=sprintf (page+len," No of Sectors= %04d\n" , - mbox->m_out.numsectors); - len +=sprintf (page+len," LBA = 0x%02x\n" , - mbox->m_out.lba); - len +=sprintf (page+len," DTA = 0x%08x\n" , - mbox->m_out.xferaddr); - len +=sprintf (page+len," Logical Drive= 0x%02x\n" , - mbox->m_out.logdrv); + len +=sprintf (page+len," Fw Command = 0x%02x\n" , mbox->cmd); + len +=sprintf (page+len," Cmd Sequence = 0x%02x\n" , mbox->cmdid); + len +=sprintf (page+len," No of Sectors= %04d\n" , mbox->numsectors); + len +=sprintf (page+len," LBA = 0x%02x\n" , mbox->lba); + len +=sprintf (page+len," DTA = 0x%08x\n" , mbox->xferaddr); + len +=sprintf (page+len," Logical Drive= 0x%02x\n" , mbox->logdrv); len +=sprintf (page+len," No of SG Elmt= 0x%02x\n" , - mbox->m_out.numsgelements); - len +=sprintf (page+len," Busy = %01x\n" , - mbox->m_in.busy); - len +=sprintf (page+len," Status = 0x%02x\n" , - mbox->m_in.status); + mbox->numsgelements); + len +=sprintf (page+len," Busy = %01x\n" , mbox->busy); + len +=sprintf (page+len," Status = 0x%02x\n" , mbox->status); *eof =1 ;
@@ -2999,13 +3111,9 @@struct pci_dev *pdev;int len =0 ; -if (make_local_pdev (adapter, &pdev) !=0 ) { - *eof =1 ; -return len; - } + pdev = adapter->ipdev;if ( (inquiry =mega_allocate_inquiry (&dma_handle, pdev)) ==NULL ) { -free_local_pdev (pdev); *eof =1 ;return len; }
@@ -3018,8 +3126,6 @@mega_free_inquiry (inquiry, dma_handle, pdev); -free_local_pdev (pdev); - *eof =1 ;return len;
@@ -3038,8 +3144,6 @@mega_free_inquiry (inquiry, dma_handle, pdev); -free_local_pdev (pdev); - *eof =1 ;return len;
@@ -3069,13 +3173,9 @@char str[256 ];int len =0 ; -if (make_local_pdev (adapter, &pdev) !=0 ) { - *eof =1 ; -return len; - } + pdev = adapter->ipdev;if ( (inquiry =mega_allocate_inquiry (&dma_handle, pdev)) ==NULL ) { -free_local_pdev (pdev); *eof =1 ;return len; }
@@ -3088,8 +3188,6 @@mega_free_inquiry (inquiry, dma_handle, pdev); -free_local_pdev (pdev); - *eof =1 ;return len;
@@ -3137,8 +3235,6 @@mega_free_inquiry (inquiry, dma_handle, pdev); -free_local_pdev (pdev); - *eof =1 ;return len;
@@ -3260,12 +3356,9 @@char str[80 ];int i; -if (make_local_pdev (adapter, &pdev) !=0 ) { -return len; - } + pdev = adapter->ipdev;if ( (inquiry =mega_allocate_inquiry (&dma_handle, pdev)) ==NULL ) { -free_local_pdev (pdev);return len; }
@@ -3277,8 +3370,6 @@mega_free_inquiry (inquiry, dma_handle, pdev); -free_local_pdev (pdev); -return len; }
@@ -3290,8 +3381,6 @@mega_free_inquiry (inquiry, dma_handle, pdev); -free_local_pdev (pdev); -return len; }
@@ -3374,8 +3463,6 @@mega_free_inquiry (inquiry, dma_handle, pdev); -free_local_pdev (pdev); -return len; }
@@ -3543,13 +3630,11 @@u32 array_sz;int len =0 ;int i; +u8 span8_flag =1 ; -if (make_local_pdev (adapter, &pdev) !=0 ) { -return len; - } + pdev = adapter->ipdev;if ( (inquiry =mega_allocate_inquiry (&dma_handle, pdev)) ==NULL ) { -free_local_pdev (pdev);return len; }
@@ -3561,14 +3646,13 @@mega_free_inquiry (inquiry, dma_handle, pdev); -free_local_pdev (pdev); -return len; }memset (&mc,0 ,sizeof (megacmd_t));if ( adapter->flag &BOARD_40LD ) { + array_sz =sizeof (disk_array_40ld); rdrv_state = ((mega_inquiry3 *)inquiry)->ldrv_state;
@@ -3576,7 +3660,12 @@ num_ldrv = ((mega_inquiry3 *)inquiry)->num_ldrv; }else { - array_sz =sizeof (disk_array_8ld); +/* +* 'array_sz' is either the size of diskarray_span4_t or the +* size of disk_array_span8_t. We use span8_t's size because +* it is bigger of the two. +*/ + array_sz =sizeof ( diskarray_span8_t ); rdrv_state = ((mraid_ext_inquiry *)inquiry)-> raid_inq.logdrv_info.ldrv_state;
@@ -3593,8 +3682,6 @@mega_free_inquiry (inquiry, dma_handle, pdev); -free_local_pdev (pdev); -return len; }
@@ -3613,17 +3700,22 @@pci_free_consistent (pdev, array_sz, disk_array, disk_array_dma_handle); -free_local_pdev (pdev); -return len; } }else { +/* +* Try 8-Span "read config" command +*/ mc.cmd =NEW_READ_CONFIG_8LD ;if (mega_internal_command (adapter,LOCK_INT , &mc,NULL ) ) { +/* +* 8-Span command failed; try 4-Span command +*/ + span8_flag =0 ; mc.cmd =READ_CONFIG_8LD ; if( mega_internal_command(adapter, LOCK_INT, &mc,
@@ -3638,8 +3730,6 @@ disk_array, disk_array_dma_handle); -free_local_pdev (pdev); -return len; } }
@@ -3652,8 +3742,14 @@ &((disk_array_40ld *)disk_array)->ldrv[i].lparam; }else { - lparam = - &((disk_array_8ld *)disk_array)->ldrv[i].lparam; +if ( span8_flag ) { + lparam = (logdrv_param *) &((diskarray_span8_t *) + (disk_array))->log_drv[i]; + } +else { + lparam = (logdrv_param *) &((diskarray_span4_t *) + (disk_array))->log_drv[i]; + } }/*
@@ -3764,8 +3860,6 @@pci_free_consistent (pdev, array_sz, disk_array, disk_array_dma_handle); -free_local_pdev (pdev); -return len; }
@@ -3848,6 +3942,7 @@return 0 ; } +/** * megaraid_reboot_notify() * @this - unused
@@ -3863,9 +3958,9 @@ {adapter_t *adapter;struct Scsi_Host *host; -u8 raw_mbox[sizeof (struct mbox_out )]; +u8 raw_mbox[sizeof (mbox_t)];mbox_t *mbox; -int i,j; +int i;/* * Flush the controller's cache irrespective of the codes coming down.
@@ -3879,7 +3974,7 @@ mbox = (mbox_t *)raw_mbox;/* Flush adapter cache */ -memset (&mbox->m_out,0 ,sizeof (raw_mbox)); +memset (raw_mbox,0 ,sizeof (raw_mbox)); raw_mbox[0 ] =FLUSH_ADAPTER ;irq_disable (adapter);
@@ -3892,7 +3987,7 @@issue_scb_block (adapter, raw_mbox);/* Flush disks cache */ -memset (&mbox->m_out,0 ,sizeof (raw_mbox)); +memset (raw_mbox,0 ,sizeof (raw_mbox)); raw_mbox[0 ] =FLUSH_SYSTEM ;issue_scb_block (adapter, raw_mbox);
@@ -3908,12 +4003,13 @@* Have a delibrate delay to make sure all the caches are * actually flushed. */ -printk ("megaraid: cache flush delay: " ); -for ( j =10 ; j >=0 ; j-- ) { -printk ("[%d] " , j); +printk (KERN_INFO "megaraid: cache flush delay: " ); +for ( i =9 ; i >=0 ; i-- ) { +printk ("\b\b\b[%d]" , i);mdelay (1000 ); } -printk ("\n" ); +printk ("\b\b\b[done]\n" ); +mdelay (1000 );return NOTIFY_DONE ; }
@@ -4209,8 +4305,7 @@* For all internal commands, the buffer must be allocated in * <4GB address range */ -if (make_local_pdev (adapter, &pdev) !=0 ) -return -EIO ; + pdev = adapter->ipdev;/* Is it a passthru command or a DCMD */ if ( uioc.uioc_rmbox[0 ] ==MEGA_MBOXCMD_PASSTHRU ) {
@@ -4221,7 +4316,6 @@ &pthru_dma_hndl);if ( pthru ==NULL ) { -free_local_pdev (pdev);return (-ENOMEM ); }
@@ -4240,8 +4334,6 @@sizeof (mega_passthru), pthru, pthru_dma_hndl); -free_local_pdev (pdev); -return (-EFAULT ); }
@@ -4259,8 +4351,6 @@ pthru, pthru_dma_hndl); -free_local_pdev (pdev); -return (-ENOMEM ); }
@@ -4329,8 +4419,6 @@pci_free_consistent (pdev,sizeof (mega_passthru), pthru, pthru_dma_hndl); -free_local_pdev (pdev); -return rval; }else {
@@ -4344,7 +4432,6 @@ uioc.xferlen, &data_dma_hndl);if ( data ==NULL ) { -free_local_pdev (pdev);return (-ENOMEM ); }
@@ -4365,8 +4452,6 @@ uioc.xferlen, data, data_dma_hndl); -free_local_pdev (pdev); -return (-EFAULT ); } }
@@ -4389,8 +4474,6 @@ data_dma_hndl); } -free_local_pdev (pdev); -return rval; }
@@ -4411,8 +4494,6 @@ data_dma_hndl); } -free_local_pdev (pdev); -return rval; }
@@ -4564,6 +4645,7 @@ {nitioctl_t *uiocp;megacmd_t *umc; +megacmd_t kmc;mega_passthru *upthru;struct uioctl_t *uioc_mimd;char signature[8 ] = {0 };
@@ -4600,8 +4682,10 @@if ( mc->cmd ==MEGA_MBOXCMD_PASSTHRU ) { umc = (megacmd_t *)uioc_mimd->mbox; +if (copy_from_user (&kmc, umc,sizeof (megacmd_t))) +return -EFAULT ; - upthru = (mega_passthru *)umc->xferaddr; + upthru = (mega_passthru *)kmc.xferaddr;if (put_user (mc->status, (u8 *)&upthru->scsistatus) )return (-EFAULT );
@@ -4625,17 +4709,17 @@static int mega_is_bios_enabled (adapter_t *adapter) { -unsigned char raw_mbox[sizeof (struct mbox_out )]; +unsigned char raw_mbox[sizeof (mbox_t)];mbox_t *mbox;int ret; mbox = (mbox_t *)raw_mbox; -memset (&mbox->m_out,0 ,sizeof (raw_mbox)); +memset (raw_mbox,0 ,sizeof (raw_mbox));memset ((void *)adapter->mega_buffer,0 ,MEGA_BUFFER_SIZE ); - mbox->m_out.xferaddr = (u32 )adapter->buf_dma_handle; + mbox->xferaddr = (u32 )adapter->buf_dma_handle; raw_mbox[0 ] =IS_BIOS_ENABLED ; raw_mbox[2 ] =GET_BIOS ;
@@ -4658,13 +4742,13 @@static void mega_enum_raid_scsi (adapter_t *adapter) { -unsigned char raw_mbox[sizeof (struct mbox_out )]; +unsigned char raw_mbox[sizeof (mbox_t)];mbox_t *mbox;int i; mbox = (mbox_t *)raw_mbox; -memset (&mbox->m_out,0 ,sizeof (raw_mbox)); +memset (raw_mbox,0 ,sizeof (raw_mbox));/* * issue command to find out what channels are raid/scsi
@@ -4674,7 +4758,7 @@memset ((void *)adapter->mega_buffer,0 ,MEGA_BUFFER_SIZE ); - mbox->m_out.xferaddr = (u32 )adapter->buf_dma_handle; + mbox->xferaddr = (u32 )adapter->buf_dma_handle;/* * Non-ROMB firware fail this command, so all channels
@@ -4713,7 +4797,7 @@ mega_get_boot_drv(adapter_t *adapter) {struct private_bios_data *prv_bios_data; -unsigned char raw_mbox[sizeof (struct mbox_out )]; +unsigned char raw_mbox[sizeof (mbox_t)];mbox_t *mbox;u16 cksum =0 ;u8 *cksum_p;
@@ -4722,14 +4806,14 @@ mbox = (mbox_t *)raw_mbox; -memset (&mbox->m_out,0 ,sizeof (raw_mbox)); +memset (raw_mbox,0 ,sizeof (raw_mbox)); raw_mbox[0 ] =BIOS_PVT_DATA ; raw_mbox[2 ] =GET_BIOS_PVT_DATA ;memset ((void *)adapter->mega_buffer,0 ,MEGA_BUFFER_SIZE ); - mbox->m_out.xferaddr = (u32 )adapter->buf_dma_handle; + mbox->xferaddr = (u32 )adapter->buf_dma_handle; adapter->boot_ldrv_enabled =0 ; adapter->boot_ldrv =0 ;
@@ -4779,13 +4863,13 @@static int mega_support_random_del (adapter_t *adapter) { -unsigned char raw_mbox[sizeof (struct mbox_out )]; +unsigned char raw_mbox[sizeof (mbox_t)];mbox_t *mbox;int rval; mbox = (mbox_t *)raw_mbox; -memset (&mbox->m_out,0 ,sizeof (raw_mbox)); +memset (raw_mbox,0 ,sizeof (raw_mbox));/* * issue command
@@ -4808,13 +4892,13 @@static int mega_support_ext_cdb (adapter_t *adapter) { -unsigned char raw_mbox[sizeof (struct mbox_out )]; +unsigned char raw_mbox[sizeof (mbox_t)];mbox_t *mbox;int rval; mbox = (mbox_t *)raw_mbox; -memset (&mbox->m_out,0 ,sizeof (raw_mbox)); +memset (raw_mbox,0 ,sizeof (raw_mbox));/* * issue command to find out if controller supports extended CDBs. */
@@ -4843,6 +4927,8 @@scb_t *scb;int rval; +ASSERT ( !spin_is_locked (adapter->host_lock) ); +/* * Stop sending commands to the controller, queue them internally. * When deletion is complete, ISR will flush the queue.
@@ -4853,15 +4939,15 @@* Wait till all the issued commands are complete and there are no * commands in the pending queue */ -while (atomic_read (&adapter->pend_cmds) >0 || - !list_empty (&adapter->pending_list) ) { +while (atomic_read (&adapter->pend_cmds) >0 ) {sleep_on_timeout ( &wq,1 *HZ );/* sleep for 1s */ } rval =mega_do_del_logdrv (adapter, logdrv); -spin_lock_irqsave (&adapter->lock, flags); + +spin_lock_irqsave (adapter->host_lock, flags);/* * If delete operation was successful, add 0x80 to the logical drive
@@ -4871,8 +4957,8 @@struct list_head *pos;list_for_each (pos, &adapter->pending_list) { scb =list_entry (pos, scb_t, list); -if (scb->pthru->logdrv <0x80 ) - scb->pthru->logdrv +=0x80 ; +if (((mbox_t *)scb->raw_mbox)->logdrv <0x80 ) + ((mbox_t *)scb->raw_mbox)->logdrv +=0x80 ; } }
@@ -4880,7 +4966,7 @@mega_runpendq (adapter); -spin_unlock_irqrestore (&adapter->lock, flags); +spin_unlock_irqrestore (adapter->host_lock, flags);return rval; }
@@ -4889,16 +4975,17 @@static int mega_do_del_logdrv (adapter_t *adapter,int logdrv) { -megacmd_t mc;int rval; +u8 raw_mbox[sizeof (mbox_t)]; -memset ( &mc,0 ,sizeof (megacmd_t)); +memset (raw_mbox,0 ,sizeof (raw_mbox)); - mc.cmd =FC_DEL_LOGDRV ; - mc.opcode =OP_DEL_LOGDRV ; - mc.subopcode = logdrv; + raw_mbox[0 ] =FC_DEL_LOGDRV ; + raw_mbox[2 ] =OP_DEL_LOGDRV ; + raw_mbox[3 ] = logdrv; - rval =mega_internal_command (adapter,LOCK_INT , &mc,NULL ); +/* Issue a blocking command to the card */ + rval =issue_scb_block (adapter, raw_mbox);/* log this event */ if (rval) {
@@ -4926,16 +5013,16 @@static void mega_get_max_sgl (adapter_t *adapter) { -unsigned char raw_mbox[sizeof (struct mbox_out )]; +unsigned char raw_mbox[sizeof (mbox_t)];mbox_t *mbox; mbox = (mbox_t *)raw_mbox; -memset (mbox,0 ,sizeof (raw_mbox)); +memset (raw_mbox,0 ,sizeof (raw_mbox));memset ((void *)adapter->mega_buffer,0 ,MEGA_BUFFER_SIZE ); - mbox->m_out.xferaddr = (u32 )adapter->buf_dma_handle; + mbox->xferaddr = (u32 )adapter->buf_dma_handle; raw_mbox[0 ] =MAIN_MISC_OPCODE ; raw_mbox[2 ] =GET_MAX_SG_SUPPORT ;
@@ -4971,16 +5058,16 @@static int mega_support_cluster (adapter_t *adapter) { -unsigned char raw_mbox[sizeof (struct mbox_out )]; +unsigned char raw_mbox[sizeof (mbox_t)];mbox_t *mbox; mbox = (mbox_t *)raw_mbox; -memset (mbox,0 ,sizeof (raw_mbox)); +memset (raw_mbox,0 ,sizeof (raw_mbox));memset ((void *)adapter->mega_buffer,0 ,MEGA_BUFFER_SIZE ); - mbox->m_out.xferaddr = (u32 )adapter->buf_dma_handle; + mbox->xferaddr = (u32 )adapter->buf_dma_handle;/* * Try to get the initiator id. This command will succeed iff the
@@ -5021,7 +5108,7 @@int ldrv_num; tgt = cmd->device->id; - +if ( tgt > adapter->this_id ) tgt--;/* we do not get inquires for initiator id */
@@ -5065,6 +5152,7 @@ } +#ifdef CONFIG_PROC_FS /** * mega_adapinq() * @adapter - pointer to our soft state
@@ -5144,13 +5232,12 @@* For all internal commands, the buffer must be allocated in <4GB * address range */ -if (make_local_pdev (adapter, &pdev) !=0 )return -1 ; + pdev = adapter->ipdev; pthru =pci_alloc_consistent (pdev,sizeof (mega_passthru), &pthru_dma_handle);if ( pthru ==NULL ) { -free_local_pdev (pdev);return -1 ; }
@@ -5186,10 +5273,9 @@pci_free_consistent (pdev,sizeof (mega_passthru), pthru, pthru_dma_handle); -free_local_pdev (pdev); - return rval; } +#endif // #ifdef CONFIG_PROC_FS /**
@@ -5236,6 +5322,7 @@ scmd->device = sdev; scmd->device->host = adapter->host; + scmd->buffer = (void *)scb; scmd->cmnd[0 ] =MEGA_INTERNAL_CMD ;
@@ -5259,16 +5346,18 @@/* * Get the lock only if the caller has not acquired it already */ -if ( ls ==LOCK_INT )spin_lock_irqsave (&adapter->lock, flags); +if ( ls ==LOCK_INT )spin_lock_irqsave (adapter->host_lock, flags);megaraid_queue (scmd, mega_internal_done); -if ( ls ==LOCK_INT )spin_unlock_irqrestore (&adapter->lock, flags); +if ( ls ==LOCK_INT )spin_unlock_irqrestore (adapter->host_lock, flags);/* * Wait till this command finishes. Do not use * wait_event_interruptible(). It causes panic if CTRL-C is hit when * dumping e.g., physical disk information through /proc interface. +* Catching the return value should solve the issue but for now keep +* the call non-interruptible. */ #if 0 wait_event_interruptible (adapter->int_waitq, scmd->state);
@@ -5277,8 +5366,8 @@ rval = scmd->result; mc->status = scmd->result; -kfree (sdev); +kfree (sdev);/* * Print a debug message for all failed commands. Applications can use * this information.
@@ -5320,36 +5409,12 @@ } - -static inline int -make_local_pdev (adapter_t *adapter,struct pci_dev **pdev) -{ - *pdev =kmalloc (sizeof (struct pci_dev ),GFP_KERNEL ); - -if ( *pdev ==NULL )return -1 ; - -memcpy (*pdev, adapter->dev,sizeof (struct pci_dev )); - -if (pci_set_dma_mask (*pdev,0xffffffff ) !=0 ) { -kfree (*pdev); -return -1 ; - } - -return 0 ; -} - -static inline void -free_local_pdev (struct pci_dev *pdev) -{ -kfree (pdev); -} -static Scsi_Host_Template driver_template = { .name ="MegaRAID" , .detect = megaraid_detect, .release = megaraid_release, .info = megaraid_info, - .queuecommand = megaraid_queue, + .queuecommand = megaraid_queue, .bios_param = megaraid_biosparam, .max_sectors =MAX_SECTORS_PER_IO , .can_queue =MAX_COMMANDS ,
@@ -5362,6 +5427,7 @@ .eh_bus_reset_handler = megaraid_reset, .eh_host_reset_handler = megaraid_reset, }; +#include "scsi_module.c" /* vi: set ts=8 sw=8 tw=78: */
megaraid.h +92 -23
221 lines not on this page · raw message
- * Copyright © 2002 LSI Logic Corporation.
+ * Copyright © 2002 LSI Logic Corporation.
Strange encoding?
@@ -358,6 +368,21 @@
adapter = (adapter_t *)host->hostdata; memset(adapter, 0, sizeof(adapter_t));
+ /*
+ * Allocate a pci device structure for allocations done
+ * internally - all of which would be in memory <4GB
+ */
+ adapter->ipdev = kmalloc(sizeof(struct pci_dev), GFP_KERNEL);
+
+ if( adapter->ipdev == NULL ) goto fail_attach;
This is wrong. We have the consistent_dma_mask for this.
+
+ got_ipdev_f = 1;
this got_foo / did_foo stuff is crap - use proper gotos for unwinding,
+
+ adapter->host_lock = &adapter->lock;
+
scsi_assign_lock(host, &adapter->lock);
still b0rked. The driver shouldn't use scsi_assign_lock which it's one of the last users of but just use host->host_lock directly everywhere.
-
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html