[opensuse] pci-express raid card or pci
Ok I am giving up on the 3ware 9650 raid card for now til the next version of suse comes out. I need another raid card for this machine I'm working on that is either pci-e or the old pci type. I have one of each of those slots free to use. I have 5 Seagate sata drives to hook to it in a raid 10 config with one spare drive at the moment. So I need at least an 8 port card. I have always used 3ware raid cards but for now the 9650 I have is not supported in suse linux. I have been told that it works in 10.3 alpha but not in 10.2 so I'm putting it aside for now. Thanks Jack Malone -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org For additional commands, e-mail: opensuse+help@opensuse.org
* Jack Malone (jmalone@horizonind.com) [20070508 15:41]:
Ok I am giving up on the 3ware 9650 raid card for now til the next version of suse comes out.
Why don't you try to build a 10.2 kernel with drivers/scsi/3w-9xxx.c and taken from the 10.3 Alpha kernel? Or apply the following diff (though I haven't checked wether it builds and/or works). Philipp --- linux-2.6.18/drivers/scsi/3w-9xxx.c 2006-09-20 05:42:06.000000000 +0200 +++ linux-2.6.21/drivers/scsi/3w-9xxx.c 2007-04-26 05:08:32.000000000 +0200 @@ -66,6 +66,9 @@ 2.26.02.006 - Fix 9550SX pchip reset timeout. Add big endian support. 2.26.02.007 - Disable local interrupts during kmap/unmap_atomic(). + 2.26.02.008 - Free irq handler in __twa_shutdown(). + Serialize reset code. + Add support for 9650SE controllers. */ #include <linux/module.h> @@ -89,7 +92,7 @@ #include "3w-9xxx.h" /* Globals */ -#define TW_DRIVER_VERSION "2.26.02.007" +#define TW_DRIVER_VERSION "2.26.02.008" static TW_Device_Extension *twa_device_extension_list[TW_MAX_SLOT]; static unsigned int twa_device_extension_count; static int twa_major = -1; @@ -194,7 +197,7 @@ static struct class_device_attribute *tw }; /* File operations struct for character device */ -static struct file_operations twa_fops = { +static const struct file_operations twa_fops = { .owner = THIS_MODULE, .ioctl = twa_chrdev_ioctl, .open = twa_chrdev_open, @@ -566,9 +569,9 @@ static int twa_check_srl(TW_Device_Exten goto out; } - tw_dev->working_srl = fw_on_ctlr_srl; - tw_dev->working_branch = fw_on_ctlr_branch; - tw_dev->working_build = fw_on_ctlr_build; + tw_dev->tw_compat_info.working_srl = fw_on_ctlr_srl; + tw_dev->tw_compat_info.working_branch = fw_on_ctlr_branch; + tw_dev->tw_compat_info.working_build = fw_on_ctlr_build; /* Try base mode compatibility */ if (!(init_connect_result & TW_CTLR_FW_COMPATIBLE)) { @@ -590,10 +593,23 @@ static int twa_check_srl(TW_Device_Exten } goto out; } - tw_dev->working_srl = TW_BASE_FW_SRL; - tw_dev->working_branch = TW_BASE_FW_BRANCH; - tw_dev->working_build = TW_BASE_FW_BUILD; - } + tw_dev->tw_compat_info.working_srl = TW_BASE_FW_SRL; + tw_dev->tw_compat_info.working_branch = TW_BASE_FW_BRANCH; + tw_dev->tw_compat_info.working_build = TW_BASE_FW_BUILD; + } + + /* Load rest of compatibility struct */ + strncpy(tw_dev->tw_compat_info.driver_version, TW_DRIVER_VERSION, strlen(TW_DRIVER_VERSION)); + tw_dev->tw_compat_info.driver_srl_high = TW_CURRENT_DRIVER_SRL; + tw_dev->tw_compat_info.driver_branch_high = TW_CURRENT_DRIVER_BRANCH; + tw_dev->tw_compat_info.driver_build_high = TW_CURRENT_DRIVER_BUILD; + tw_dev->tw_compat_info.driver_srl_low = TW_BASE_FW_SRL; + tw_dev->tw_compat_info.driver_branch_low = TW_BASE_FW_BRANCH; + tw_dev->tw_compat_info.driver_build_low = TW_BASE_FW_BUILD; + tw_dev->tw_compat_info.fw_on_ctlr_srl = fw_on_ctlr_srl; + tw_dev->tw_compat_info.fw_on_ctlr_branch = fw_on_ctlr_branch; + tw_dev->tw_compat_info.fw_on_ctlr_build = fw_on_ctlr_build; + retval = 0; out: return retval; @@ -631,7 +647,7 @@ static int twa_chrdev_ioctl(struct inode goto out2; /* Check data buffer size */ - if (driver_command.buffer_length > TW_MAX_SECTORS * 512) { + if (driver_command.buffer_length > TW_MAX_SECTORS * 2048) { retval = TW_IOCTL_ERROR_OS_EINVAL; goto out2; } @@ -680,13 +696,6 @@ static int twa_chrdev_ioctl(struct inode /* Now wait for command to complete */ timeout = wait_event_timeout(tw_dev->ioctl_wqueue, tw_dev->chrdev_request_id == TW_IOCTL_CHRDEV_FREE, timeout); - /* See if we reset while waiting for the ioctl to complete */ - if (test_bit(TW_IN_RESET, &tw_dev->flags)) { - clear_bit(TW_IN_RESET, &tw_dev->flags); - retval = TW_IOCTL_ERROR_OS_ERESTARTSYS; - goto out3; - } - /* We timed out, and didn't get an interrupt */ if (tw_dev->chrdev_request_id != TW_IOCTL_CHRDEV_FREE) { /* Now we need to reset the board */ @@ -694,11 +703,6 @@ static int twa_chrdev_ioctl(struct inode tw_dev->host->host_no, TW_DRIVER, 0xc, cmd); retval = TW_IOCTL_ERROR_OS_EIO; - spin_lock_irqsave(tw_dev->host->host_lock, flags); - tw_dev->state[request_id] = TW_S_COMPLETED; - twa_free_request_id(tw_dev, request_id); - tw_dev->posted_request_count--; - spin_unlock_irqrestore(tw_dev->host->host_lock, flags); twa_reset_device_extension(tw_dev, 1); goto out3; } @@ -717,16 +721,7 @@ static int twa_chrdev_ioctl(struct inode tw_ioctl->driver_command.status = 0; /* Copy compatiblity struct into ioctl data buffer */ tw_compat_info = (TW_Compatibility_Info *)tw_ioctl->data_buffer; - strncpy(tw_compat_info->driver_version, TW_DRIVER_VERSION, strlen(TW_DRIVER_VERSION)); - tw_compat_info->working_srl = tw_dev->working_srl; - tw_compat_info->working_branch = tw_dev->working_branch; - tw_compat_info->working_build = tw_dev->working_build; - tw_compat_info->driver_srl_high = TW_CURRENT_DRIVER_SRL; - tw_compat_info->driver_branch_high = TW_CURRENT_DRIVER_BRANCH; - tw_compat_info->driver_build_high = TW_CURRENT_DRIVER_BUILD; - tw_compat_info->driver_srl_low = TW_BASE_FW_SRL; - tw_compat_info->driver_branch_low = TW_BASE_FW_BRANCH; - tw_compat_info->driver_build_low = TW_BASE_FW_BUILD; + memcpy(tw_compat_info, &tw_dev->tw_compat_info, sizeof(TW_Compatibility_Info)); break; case TW_IOCTL_GET_LAST_EVENT: if (tw_dev->event_queue_wrapped) { @@ -895,7 +890,8 @@ static int twa_decode_bits(TW_Device_Ext } if (status_reg_value & TW_STATUS_QUEUE_ERROR) { - TW_PRINTK(tw_dev->host, TW_DRIVER, 0xe, "Controller Queue Error: clearing"); + if ((tw_dev->tw_pci_dev->device != PCI_DEVICE_ID_3WARE_9650SE) || (!test_bit(TW_IN_RESET, &tw_dev->flags))) + TW_PRINTK(tw_dev->host, TW_DRIVER, 0xe, "Controller Queue Error: clearing"); writel(TW_CONTROL_CLEAR_QUEUE_ERROR, TW_CONTROL_REG_ADDR(tw_dev)); } @@ -939,10 +935,12 @@ static int twa_empty_response_queue_larg unsigned long before; int retval = 1; - if (tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9550SX) { + if ((tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9550SX) || + (tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9650SE)) { before = jiffies; while ((response_que_value & TW_9550SX_DRAIN_COMPLETED) != TW_9550SX_DRAIN_COMPLETED) { response_que_value = readl(TW_RESPONSE_QUEUE_REG_ADDR_LARGE(tw_dev)); + msleep(1); if (time_after(jiffies, before + HZ * 30)) goto out; } @@ -1192,7 +1190,7 @@ out: } /* End twa_initialize_device_extension() */ /* This function is the interrupt service routine */ -static irqreturn_t twa_interrupt(int irq, void *dev_instance, struct pt_regs *regs) +static irqreturn_t twa_interrupt(int irq, void *dev_instance) { int request_id, error = 0; u32 status_reg_value; @@ -1214,6 +1212,10 @@ static irqreturn_t twa_interrupt(int irq handled = 1; + /* If we are resetting, bail */ + if (test_bit(TW_IN_RESET, &tw_dev->flags)) + goto twa_interrupt_bail; + /* Check controller for errors */ if (twa_check_bits(status_reg_value)) { if (twa_decode_bits(tw_dev, status_reg_value)) { @@ -1355,8 +1357,8 @@ static void twa_load_sgl(TW_Command_Full if (TW_OP_OUT(full_command_packet->command.newcommand.opcode__reserved) == TW_OP_EXECUTE_SCSI) { newcommand = &full_command_packet->command.newcommand; - newcommand->request_id__lunl = - TW_REQ_LUN_IN(TW_LUN_OUT(newcommand->request_id__lunl), request_id); + newcommand->request_id__lunl = + cpu_to_le16(TW_REQ_LUN_IN(TW_LUN_OUT(newcommand->request_id__lunl), request_id)); newcommand->sg_list[0].address = TW_CPU_TO_SGL(dma_handle + sizeof(TW_Ioctl_Buf_Apache) - 1); newcommand->sg_list[0].length = cpu_to_le32(length); newcommand->sgl_entries__lunh = @@ -1531,6 +1533,13 @@ static int twa_post_command_packet(TW_De int retval = 1; command_que_value = tw_dev->command_packet_phys[request_id]; + + /* For 9650SE write low 4 bytes first */ + if (tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9650SE) { + command_que_value += TW_COMMAND_OFFSET; + writel((u32)command_que_value, TW_COMMAND_QUEUE_REG_ADDR_LARGE(tw_dev)); + } + status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev)); if (twa_check_bits(status_reg_value)) @@ -1557,13 +1566,17 @@ static int twa_post_command_packet(TW_De TW_UNMASK_COMMAND_INTERRUPT(tw_dev); goto out; } else { - /* We successfully posted the command packet */ - if (sizeof(dma_addr_t) > 4) { - command_que_value += TW_COMMAND_OFFSET; - writel((u32)command_que_value, TW_COMMAND_QUEUE_REG_ADDR(tw_dev)); - writel((u32)((u64)command_que_value >> 32), TW_COMMAND_QUEUE_REG_ADDR(tw_dev) + 0x4); + if (tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9650SE) { + /* Now write upper 4 bytes */ + writel((u32)((u64)command_que_value >> 32), TW_COMMAND_QUEUE_REG_ADDR_LARGE(tw_dev) + 0x4); } else { - writel(TW_COMMAND_OFFSET + command_que_value, TW_COMMAND_QUEUE_REG_ADDR(tw_dev)); + if (sizeof(dma_addr_t) > 4) { + command_que_value += TW_COMMAND_OFFSET; + writel((u32)command_que_value, TW_COMMAND_QUEUE_REG_ADDR(tw_dev)); + writel((u32)((u64)command_que_value >> 32), TW_COMMAND_QUEUE_REG_ADDR(tw_dev) + 0x4); + } else { + writel(TW_COMMAND_OFFSET + command_que_value, TW_COMMAND_QUEUE_REG_ADDR(tw_dev)); + } } tw_dev->state[request_id] = TW_S_POSTED; tw_dev->posted_request_count++; @@ -1620,14 +1633,9 @@ static int twa_reset_device_extension(TW goto out; TW_ENABLE_AND_CLEAR_INTERRUPTS(tw_dev); + clear_bit(TW_IN_RESET, &tw_dev->flags); + tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE; - /* Wake up any ioctl that was pending before the reset */ - if ((tw_dev->chrdev_request_id == TW_IOCTL_CHRDEV_FREE) || (ioctl_reset)) { - clear_bit(TW_IN_RESET, &tw_dev->flags); - } else { - tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE; - wake_up(&tw_dev->ioctl_wqueue); - } retval = 0; out: return retval; @@ -1736,6 +1744,9 @@ static int twa_scsi_eh_reset(struct scsi "WARNING: (0x%02X:0x%04X): Command (0x%x) timed out, resetting card.\n", TW_DRIVER, 0x2c, SCpnt->cmnd[0]); + /* Make sure we are not issuing an ioctl or resetting from ioctl */ + mutex_lock(&tw_dev->ioctl_lock); + /* Now reset the card and some of the device extension data */ if (twa_reset_device_extension(tw_dev, 0)) { TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2b, "Controller reset failed during scsi host reset"); @@ -1744,6 +1755,7 @@ static int twa_scsi_eh_reset(struct scsi retval = SUCCESS; out: + mutex_unlock(&tw_dev->ioctl_lock); return retval; } /* End twa_scsi_eh_reset() */ @@ -1753,8 +1765,14 @@ static int twa_scsi_queue(struct scsi_cm int request_id, retval; TW_Device_Extension *tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata; + /* If we are resetting due to timed out ioctl, report as busy */ + if (test_bit(TW_IN_RESET, &tw_dev->flags)) { + retval = SCSI_MLQUEUE_HOST_BUSY; + goto out; + } + /* Check if this FW supports luns */ - if ((SCpnt->device->lun != 0) && (tw_dev->working_srl < TW_FW_SRL_LUNS_SUPPORTED)) { + if ((SCpnt->device->lun != 0) && (tw_dev->tw_compat_info.working_srl < TW_FW_SRL_LUNS_SUPPORTED)) { SCpnt->result = (DID_BAD_TARGET << 16); done(SCpnt); retval = 0; @@ -1960,6 +1978,9 @@ static void __twa_shutdown(TW_Device_Ext /* Disable interrupts */ TW_DISABLE_INTERRUPTS(tw_dev); + /* Free up the IRQ */ + free_irq(tw_dev->tw_pci_dev->irq, tw_dev); + printk(KERN_WARNING "3w-9xxx: Shutting down host %d.\n", tw_dev->host->host_no); /* Tell the card we are shutting down */ @@ -2091,21 +2112,25 @@ static int __devinit twa_probe(struct pc /* Initialize the card */ if (twa_reset_sequence(tw_dev, 0)) - goto out_release_mem_region; + goto out_iounmap; /* Set host specific parameters */ - host->max_id = TW_MAX_UNITS; + if (pdev->device == PCI_DEVICE_ID_3WARE_9650SE) + host->max_id = TW_MAX_UNITS_9650SE; + else + host->max_id = TW_MAX_UNITS; + host->max_cmd_len = TW_MAX_CDB_LEN; /* Channels aren't supported by adapter */ - host->max_lun = TW_MAX_LUNS(tw_dev->working_srl); + host->max_lun = TW_MAX_LUNS(tw_dev->tw_compat_info.working_srl); host->max_channel = 0; /* Register the card with the kernel SCSI layer */ retval = scsi_add_host(host, &pdev->dev); if (retval) { TW_PRINTK(tw_dev->host, TW_DRIVER, 0x27, "scsi add host failed"); - goto out_release_mem_region; + goto out_iounmap; } pci_set_drvdata(pdev, host); @@ -2145,6 +2170,8 @@ static int __devinit twa_probe(struct pc out_remove_host: scsi_remove_host(host); +out_iounmap: + iounmap(tw_dev->base_addr); out_release_mem_region: pci_release_regions(pdev); out_free_device_extension: @@ -2170,12 +2197,12 @@ static void twa_remove(struct pci_dev *p twa_major = -1; } - /* Free up the IRQ */ - free_irq(tw_dev->tw_pci_dev->irq, tw_dev); - /* Shutdown the card */ __twa_shutdown(tw_dev); + /* Free IO remapping */ + iounmap(tw_dev->base_addr); + /* Free up the mem region */ pci_release_regions(pdev); @@ -2193,6 +2220,8 @@ static struct pci_device_id twa_pci_tbl[ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { PCI_VENDOR_ID_3WARE, PCI_DEVICE_ID_3WARE_9550SX, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + { PCI_VENDOR_ID_3WARE, PCI_DEVICE_ID_3WARE_9650SE, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { } }; MODULE_DEVICE_TABLE(pci, twa_pci_tbl); @@ -2211,7 +2240,7 @@ static int __init twa_init(void) { printk(KERN_WARNING "3ware 9000 Storage Controller device driver for Linux v%s.\n", TW_DRIVER_VERSION); - return pci_module_init(&twa_driver); + return pci_register_driver(&twa_driver); } /* End twa_init() */ /* This function is called on driver exit */ -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org For additional commands, e-mail: opensuse+help@opensuse.org
I have never done that before, not even sure where to begin at this point. How would go about this an using the new kernel at installation time. Jack > > Why don't you try to build a 10.2 kernel with drivers/scsi/3w-9xxx.c > and > taken from the 10.3 Alpha kernel? Or apply the following diff (though I > haven't checked wether it builds and/or works). > > Philipp > > --- linux-2.6.18/drivers/scsi/3w-9xxx.c 2006-09-20 05:42:06.000000000 > +0200 > +++ linux-2.6.21/drivers/scsi/3w-9xxx.c 2007-04-26 05:08:32.000000000 > +0200 > @@ -66,6 +66,9 @@ > 2.26.02.006 - Fix 9550SX pchip reset timeout. > Add big endian support. > 2.26.02.007 - Disable local interrupts during kmap/unmap_atomic(). > + 2.26.02.008 - Free irq handler in __twa_shutdown(). > + Serialize reset code. > + Add support for 9650SE controllers. > */ > > #include <linux/module.h> > @@ -89,7 +92,7 @@ > #include "3w-9xxx.h" > > /* Globals */ > -#define TW_DRIVER_VERSION "2.26.02.007" > +#define TW_DRIVER_VERSION "2.26.02.008" > static TW_Device_Extension *twa_device_extension_list[TW_MAX_SLOT]; > static unsigned int twa_device_extension_count; > static int twa_major = -1; > @@ -194,7 +197,7 @@ static struct class_device_attribute *tw > }; > > /* File operations struct for character device */ > -static struct file_operations twa_fops = { > +static const struct file_operations twa_fops = { > .owner = THIS_MODULE, > .ioctl = twa_chrdev_ioctl, > .open = twa_chrdev_open, > @@ -566,9 +569,9 @@ static int twa_check_srl(TW_Device_Exten > goto out; > } > > - tw_dev->working_srl = fw_on_ctlr_srl; > - tw_dev->working_branch = fw_on_ctlr_branch; > - tw_dev->working_build = fw_on_ctlr_build; > + tw_dev->tw_compat_info.working_srl = fw_on_ctlr_srl; > + tw_dev->tw_compat_info.working_branch = fw_on_ctlr_branch; > + tw_dev->tw_compat_info.working_build = fw_on_ctlr_build; > > /* Try base mode compatibility */ > if (!(init_connect_result & TW_CTLR_FW_COMPATIBLE)) { > @@ -590,10 +593,23 @@ static int twa_check_srl(TW_Device_Exten > } > goto out; > } > - tw_dev->working_srl = TW_BASE_FW_SRL; > - tw_dev->working_branch = TW_BASE_FW_BRANCH; > - tw_dev->working_build = TW_BASE_FW_BUILD; > - } > + tw_dev->tw_compat_info.working_srl = TW_BASE_FW_SRL; > + tw_dev->tw_compat_info.working_branch = TW_BASE_FW_BRANCH; > + tw_dev->tw_compat_info.working_build = TW_BASE_FW_BUILD; > + } > + > + /* Load rest of compatibility struct */ > + strncpy(tw_dev->tw_compat_info.driver_version, TW_DRIVER_VERSION, > strlen(TW_DRIVER_VERSION)); > + tw_dev->tw_compat_info.driver_srl_high = TW_CURRENT_DRIVER_SRL; > + tw_dev->tw_compat_info.driver_branch_high = > TW_CURRENT_DRIVER_BRANCH; > + tw_dev->tw_compat_info.driver_build_high = > TW_CURRENT_DRIVER_BUILD; > + tw_dev->tw_compat_info.driver_srl_low = TW_BASE_FW_SRL; > + tw_dev->tw_compat_info.driver_branch_low = TW_BASE_FW_BRANCH; > + tw_dev->tw_compat_info.driver_build_low = TW_BASE_FW_BUILD; > + tw_dev->tw_compat_info.fw_on_ctlr_srl = fw_on_ctlr_srl; > + tw_dev->tw_compat_info.fw_on_ctlr_branch = fw_on_ctlr_branch; > + tw_dev->tw_compat_info.fw_on_ctlr_build = fw_on_ctlr_build; > + > retval = 0; > out: > return retval; > @@ -631,7 +647,7 @@ static int twa_chrdev_ioctl(struct inode > goto out2; > > /* Check data buffer size */ > - if (driver_command.buffer_length > TW_MAX_SECTORS * 512) { > + if (driver_command.buffer_length > TW_MAX_SECTORS * 2048) { > retval = TW_IOCTL_ERROR_OS_EINVAL; > goto out2; > } > @@ -680,13 +696,6 @@ static int twa_chrdev_ioctl(struct inode > /* Now wait for command to complete */ > timeout = wait_event_timeout(tw_dev->ioctl_wqueue, tw_dev- > >chrdev_request_id == TW_IOCTL_CHRDEV_FREE, timeout); > > - /* See if we reset while waiting for the ioctl to complete > */ > - if (test_bit(TW_IN_RESET, &tw_dev->flags)) { > - clear_bit(TW_IN_RESET, &tw_dev->flags); > - retval = TW_IOCTL_ERROR_OS_ERESTARTSYS; > - goto out3; > - } > - > /* We timed out, and didn't get an interrupt */ > if (tw_dev->chrdev_request_id != TW_IOCTL_CHRDEV_FREE) { > /* Now we need to reset the board */ > @@ -694,11 +703,6 @@ static int twa_chrdev_ioctl(struct inode > tw_dev->host->host_no, TW_DRIVER, 0xc, > cmd); > retval = TW_IOCTL_ERROR_OS_EIO; > - spin_lock_irqsave(tw_dev->host->host_lock, flags); > - tw_dev->state[request_id] = TW_S_COMPLETED; > - twa_free_request_id(tw_dev, request_id); > - tw_dev->posted_request_count--; > - spin_unlock_irqrestore(tw_dev->host->host_lock, > flags); > twa_reset_device_extension(tw_dev, 1); > goto out3; > } > @@ -717,16 +721,7 @@ static int twa_chrdev_ioctl(struct inode > tw_ioctl->driver_command.status = 0; > /* Copy compatiblity struct into ioctl data buffer */ > tw_compat_info = (TW_Compatibility_Info *)tw_ioctl- > >data_buffer; > - strncpy(tw_compat_info->driver_version, TW_DRIVER_VERSION, > strlen(TW_DRIVER_VERSION)); > - tw_compat_info->working_srl = tw_dev->working_srl; > - tw_compat_info->working_branch = tw_dev->working_branch; > - tw_compat_info->working_build = tw_dev->working_build; > - tw_compat_info->driver_srl_high = TW_CURRENT_DRIVER_SRL; > - tw_compat_info->driver_branch_high = > TW_CURRENT_DRIVER_BRANCH; > - tw_compat_info->driver_build_high = > TW_CURRENT_DRIVER_BUILD; > - tw_compat_info->driver_srl_low = TW_BASE_FW_SRL; > - tw_compat_info->driver_branch_low = TW_BASE_FW_BRANCH; > - tw_compat_info->driver_build_low = TW_BASE_FW_BUILD; > + memcpy(tw_compat_info, &tw_dev->tw_compat_info, > sizeof(TW_Compatibility_Info)); > break; > case TW_IOCTL_GET_LAST_EVENT: > if (tw_dev->event_queue_wrapped) { > @@ -895,7 +890,8 @@ static int twa_decode_bits(TW_Device_Ext > } > > if (status_reg_value & TW_STATUS_QUEUE_ERROR) { > - TW_PRINTK(tw_dev->host, TW_DRIVER, 0xe, "Controller Queue > Error: clearing"); > + if ((tw_dev->tw_pci_dev->device != > PCI_DEVICE_ID_3WARE_9650SE) || (!test_bit(TW_IN_RESET, &tw_dev- > >flags))) > + TW_PRINTK(tw_dev->host, TW_DRIVER, 0xe, "Controller > Queue Error: clearing"); > writel(TW_CONTROL_CLEAR_QUEUE_ERROR, > TW_CONTROL_REG_ADDR(tw_dev)); > } > > @@ -939,10 +935,12 @@ static int twa_empty_response_queue_larg > unsigned long before; > int retval = 1; > > - if (tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9550SX) { > + if ((tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9550SX) || > + (tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9650SE)) { > before = jiffies; > while ((response_que_value & TW_9550SX_DRAIN_COMPLETED) != > TW_9550SX_DRAIN_COMPLETED) { > response_que_value = > readl(TW_RESPONSE_QUEUE_REG_ADDR_LARGE(tw_dev)); > + msleep(1); > if (time_after(jiffies, before + HZ * 30)) > goto out; > } > @@ -1192,7 +1190,7 @@ out: > } /* End twa_initialize_device_extension() */ > > /* This function is the interrupt service routine */ > -static irqreturn_t twa_interrupt(int irq, void *dev_instance, struct > pt_regs *regs) > +static irqreturn_t twa_interrupt(int irq, void *dev_instance) > { > int request_id, error = 0; > u32 status_reg_value; > @@ -1214,6 +1212,10 @@ static irqreturn_t twa_interrupt(int irq > > handled = 1; > > + /* If we are resetting, bail */ > + if (test_bit(TW_IN_RESET, &tw_dev->flags)) > + goto twa_interrupt_bail; > + > /* Check controller for errors */ > if (twa_check_bits(status_reg_value)) { > if (twa_decode_bits(tw_dev, status_reg_value)) { > @@ -1355,8 +1357,8 @@ static void twa_load_sgl(TW_Command_Full > > if (TW_OP_OUT(full_command_packet- > >command.newcommand.opcode__reserved) == TW_OP_EXECUTE_SCSI) { > newcommand = &full_command_packet->command.newcommand; > - newcommand->request_id__lunl = > - TW_REQ_LUN_IN(TW_LUN_OUT(newcommand- > >request_id__lunl), request_id); > + newcommand->request_id__lunl = > + cpu_to_le16(TW_REQ_LUN_IN(TW_LUN_OUT(newcommand- > >request_id__lunl), request_id)); > newcommand->sg_list[0].address = TW_CPU_TO_SGL(dma_handle + > sizeof(TW_Ioctl_Buf_Apache) - 1); > newcommand->sg_list[0].length = cpu_to_le32(length); > newcommand->sgl_entries__lunh = > @@ -1531,6 +1533,13 @@ static int twa_post_command_packet(TW_De > int retval = 1; > > command_que_value = tw_dev->command_packet_phys[request_id]; > + > + /* For 9650SE write low 4 bytes first */ > + if (tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9650SE) { > + command_que_value += TW_COMMAND_OFFSET; > + writel((u32)command_que_value, > TW_COMMAND_QUEUE_REG_ADDR_LARGE(tw_dev)); > + } > + > status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev)); > > if (twa_check_bits(status_reg_value)) > @@ -1557,13 +1566,17 @@ static int twa_post_command_packet(TW_De > TW_UNMASK_COMMAND_INTERRUPT(tw_dev); > goto out; > } else { > - /* We successfully posted the command packet */ > - if (sizeof(dma_addr_t) > 4) { > - command_que_value += TW_COMMAND_OFFSET; > - writel((u32)command_que_value, > TW_COMMAND_QUEUE_REG_ADDR(tw_dev)); > - writel((u32)((u64)command_que_value >> 32), > TW_COMMAND_QUEUE_REG_ADDR(tw_dev) + 0x4); > + if (tw_dev->tw_pci_dev->device == > PCI_DEVICE_ID_3WARE_9650SE) { > + /* Now write upper 4 bytes */ > + writel((u32)((u64)command_que_value >> 32), > TW_COMMAND_QUEUE_REG_ADDR_LARGE(tw_dev) + 0x4); > } else { > - writel(TW_COMMAND_OFFSET + command_que_value, > TW_COMMAND_QUEUE_REG_ADDR(tw_dev)); > + if (sizeof(dma_addr_t) > 4) { > + command_que_value += TW_COMMAND_OFFSET; > + writel((u32)command_que_value, > TW_COMMAND_QUEUE_REG_ADDR(tw_dev)); > + writel((u32)((u64)command_que_value >> 32), > TW_COMMAND_QUEUE_REG_ADDR(tw_dev) + 0x4); > + } else { > + writel(TW_COMMAND_OFFSET + command_que_value, > TW_COMMAND_QUEUE_REG_ADDR(tw_dev)); > + } > } > tw_dev->state[request_id] = TW_S_POSTED; > tw_dev->posted_request_count++; > @@ -1620,14 +1633,9 @@ static int twa_reset_device_extension(TW > goto out; > > TW_ENABLE_AND_CLEAR_INTERRUPTS(tw_dev); > + clear_bit(TW_IN_RESET, &tw_dev->flags); > + tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE; > > - /* Wake up any ioctl that was pending before the reset */ > - if ((tw_dev->chrdev_request_id == TW_IOCTL_CHRDEV_FREE) || > (ioctl_reset)) { > - clear_bit(TW_IN_RESET, &tw_dev->flags); > - } else { > - tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE; > - wake_up(&tw_dev->ioctl_wqueue); > - } > retval = 0; > out: > return retval; > @@ -1736,6 +1744,9 @@ static int twa_scsi_eh_reset(struct scsi > "WARNING: (0x%02X:0x%04X): Command (0x%x) timed out, > resetting card.\n", > TW_DRIVER, 0x2c, SCpnt->cmnd[0]); > > + /* Make sure we are not issuing an ioctl or resetting from ioctl > */ > + mutex_lock(&tw_dev->ioctl_lock); > + > /* Now reset the card and some of the device extension data */ > if (twa_reset_device_extension(tw_dev, 0)) { > TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2b, "Controller reset > failed during scsi host reset"); > @@ -1744,6 +1755,7 @@ static int twa_scsi_eh_reset(struct scsi > > retval = SUCCESS; > out: > + mutex_unlock(&tw_dev->ioctl_lock); > return retval; > } /* End twa_scsi_eh_reset() */ > > @@ -1753,8 +1765,14 @@ static int twa_scsi_queue(struct scsi_cm > int request_id, retval; > TW_Device_Extension *tw_dev = (TW_Device_Extension *)SCpnt- > >device->host->hostdata; > > + /* If we are resetting due to timed out ioctl, report as busy */ > + if (test_bit(TW_IN_RESET, &tw_dev->flags)) { > + retval = SCSI_MLQUEUE_HOST_BUSY; > + goto out; > + } > + > /* Check if this FW supports luns */ > - if ((SCpnt->device->lun != 0) && (tw_dev->working_srl < > TW_FW_SRL_LUNS_SUPPORTED)) { > + if ((SCpnt->device->lun != 0) && (tw_dev- > >tw_compat_info.working_srl < TW_FW_SRL_LUNS_SUPPORTED)) { > SCpnt->result = (DID_BAD_TARGET << 16); > done(SCpnt); > retval = 0; > @@ -1960,6 +1978,9 @@ static void __twa_shutdown(TW_Device_Ext > /* Disable interrupts */ > TW_DISABLE_INTERRUPTS(tw_dev); > > + /* Free up the IRQ */ > + free_irq(tw_dev->tw_pci_dev->irq, tw_dev); > + > printk(KERN_WARNING "3w-9xxx: Shutting down host %d.\n", tw_dev- > >host->host_no); > > /* Tell the card we are shutting down */ > @@ -2091,21 +2112,25 @@ static int __devinit twa_probe(struct pc > > /* Initialize the card */ > if (twa_reset_sequence(tw_dev, 0)) > - goto out_release_mem_region; > + goto out_iounmap; > > /* Set host specific parameters */ > - host->max_id = TW_MAX_UNITS; > + if (pdev->device == PCI_DEVICE_ID_3WARE_9650SE) > + host->max_id = TW_MAX_UNITS_9650SE; > + else > + host->max_id = TW_MAX_UNITS; > + > host->max_cmd_len = TW_MAX_CDB_LEN; > > /* Channels aren't supported by adapter */ > - host->max_lun = TW_MAX_LUNS(tw_dev->working_srl); > + host->max_lun = TW_MAX_LUNS(tw_dev->tw_compat_info.working_srl); > host->max_channel = 0; > > /* Register the card with the kernel SCSI layer */ > retval = scsi_add_host(host, &pdev->dev); > if (retval) { > TW_PRINTK(tw_dev->host, TW_DRIVER, 0x27, "scsi add host > failed"); > - goto out_release_mem_region; > + goto out_iounmap; > } > > pci_set_drvdata(pdev, host); > @@ -2145,6 +2170,8 @@ static int __devinit twa_probe(struct pc > > out_remove_host: > scsi_remove_host(host); > +out_iounmap: > + iounmap(tw_dev->base_addr); > out_release_mem_region: > pci_release_regions(pdev); > out_free_device_extension: > @@ -2170,12 +2197,12 @@ static void twa_remove(struct pci_dev *p > twa_major = -1; > } > > - /* Free up the IRQ */ > - free_irq(tw_dev->tw_pci_dev->irq, tw_dev); > - > /* Shutdown the card */ > __twa_shutdown(tw_dev); > > + /* Free IO remapping */ > + iounmap(tw_dev->base_addr); > + > /* Free up the mem region */ > pci_release_regions(pdev); > > @@ -2193,6 +2220,8 @@ static struct pci_device_id twa_pci_tbl[ > PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, > { PCI_VENDOR_ID_3WARE, PCI_DEVICE_ID_3WARE_9550SX, > PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, > + { PCI_VENDOR_ID_3WARE, PCI_DEVICE_ID_3WARE_9650SE, > + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, > { } > }; > MODULE_DEVICE_TABLE(pci, twa_pci_tbl); > @@ -2211,7 +2240,7 @@ static int __init twa_init(void) > { > printk(KERN_WARNING "3ware 9000 Storage Controller device driver > for Linux v%s.\n", TW_DRIVER_VERSION); > > - return pci_module_init(&twa_driver); > + return pci_register_driver(&twa_driver); > } /* End twa_init() */ > > /* This function is called on driver exit */ > -- > To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org > For additional commands, e-mail: opensuse+help@opensuse.org -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org For additional commands, e-mail: opensuse+help@opensuse.org
* Jack Malone (jmalone@horizonind.com) [20070508 18:05]:
I have never done that before, not even sure where to begin at this point. How would go about this an using the new kernel at installation time.
Yea, there's a catch :( You'd need to build a driver update disk and I'm not sure if that's documented somewhere ... BTW, I do read the list so I don't need nor want an extra copy as private mail. Philipp -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org For additional commands, e-mail: opensuse+help@opensuse.org
I have never done that before, not even sure where to begin at this point. How would go about this an using the new kernel at installation time.
Yea, there's a catch :( You'd need to build a driver update disk and I'm not sure if that's documented somewhere ...
BTW, I do read the list so I don't need nor want an extra copy as private mail.
Thanks for replying back Philipp. I forgot to delete your email address from the message before I sent it out sorry about that. For now I'm going to use an older 3ware card ( 95008mi) in this machine so that I can get it up an going. I'm planning to build a new server again in near future an will use the 9650 card in that machine then after you get the new 10.3 out in production. Thanks for trying to help me, I just need to get this machine back up and in use an the new / older 95008mi card should help me in that for now. I have wasted enough time on this issue at this time an finally convinced my boss that I need to go with another card for now. Now after this is done he wants me to look into clustering software for two different machines here with linux. I will save that for another message later to the list. Jack -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org For additional commands, e-mail: opensuse+help@opensuse.org
participants (2)
-
Jack Malone
-
Philipp Thomas