diff options
Diffstat (limited to 'drivers/scsi/megaraid/megaraid_mbox.c')
| -rw-r--r-- | drivers/scsi/megaraid/megaraid_mbox.c | 168 |
1 files changed, 89 insertions, 79 deletions
diff --git a/drivers/scsi/megaraid/megaraid_mbox.c b/drivers/scsi/megaraid/megaraid_mbox.c index c6a53dccc16..e2237a97cb9 100644 --- a/drivers/scsi/megaraid/megaraid_mbox.c +++ b/drivers/scsi/megaraid/megaraid_mbox.c @@ -67,9 +67,11 @@ * * NEC MegaRAID PCI Express ROMB 1000 0408 1033 8287 * - * For history of changes, see Documentation/ChangeLog.megaraid + * For history of changes, see Documentation/scsi/ChangeLog.megaraid */ +#include <linux/slab.h> +#include <linux/module.h> #include "megaraid_mbox.h" static int megaraid_init(void); @@ -112,8 +114,7 @@ static int megaraid_mbox_fire_sync_cmd(adapter_t *); static void megaraid_mbox_display_scb(adapter_t *, scb_t *); static void megaraid_mbox_setup_device_map(adapter_t *); -static int megaraid_queue_command(struct scsi_cmnd *, - void (*)(struct scsi_cmnd *)); +static int megaraid_queue_command(struct Scsi_Host *, struct scsi_cmnd *); static scb_t *megaraid_mbox_build_cmd(adapter_t *, struct scsi_cmnd *, int *); static void megaraid_mbox_runpendq(adapter_t *, scb_t *); static void megaraid_mbox_prepare_pthru(adapter_t *, scb_t *, @@ -125,7 +126,7 @@ static irqreturn_t megaraid_isr(int, void *); static void megaraid_mbox_dpc(unsigned long); -static ssize_t megaraid_sysfs_show_app_hndl(struct class_device *, char *); +static ssize_t megaraid_sysfs_show_app_hndl(struct device *, struct device_attribute *attr, char *); static ssize_t megaraid_sysfs_show_ldnum(struct device *, struct device_attribute *attr, char *); static int megaraid_cmm_register(adapter_t *); @@ -300,11 +301,11 @@ static struct pci_device_id pci_id_table_g[] = { MODULE_DEVICE_TABLE(pci, pci_id_table_g); -static struct pci_driver megaraid_pci_driver_g = { +static struct pci_driver megaraid_pci_driver = { .name = "megaraid", .id_table = pci_id_table_g, .probe = megaraid_probe_one, - .remove = __devexit_p(megaraid_detach_one), + .remove = megaraid_detach_one, .shutdown = megaraid_mbox_shutdown, }; @@ -313,12 +314,12 @@ static struct pci_driver megaraid_pci_driver_g = { // definitions for the device attributes for exporting logical drive number // for a scsi address (Host, Channel, Id, Lun) -CLASS_DEVICE_ATTR(megaraid_mbox_app_hndl, S_IRUSR, megaraid_sysfs_show_app_hndl, +DEVICE_ATTR(megaraid_mbox_app_hndl, S_IRUSR, megaraid_sysfs_show_app_hndl, NULL); // Host template initializer for megaraid mbox sysfs device attributes -static struct class_device_attribute *megaraid_shost_attrs[] = { - &class_device_attr_megaraid_mbox_app_hndl, +static struct device_attribute *megaraid_shost_attrs[] = { + &dev_attr_megaraid_mbox_app_hndl, NULL, }; @@ -335,12 +336,17 @@ static struct device_attribute *megaraid_sdev_attrs[] = { * megaraid_change_queue_depth - Change the device's queue depth * @sdev: scsi device struct * @qdepth: depth to set + * @reason: calling context * * Return value: * actual depth set */ -static int megaraid_change_queue_depth(struct scsi_device *sdev, int qdepth) +static int megaraid_change_queue_depth(struct scsi_device *sdev, int qdepth, + int reason) { + if (reason != SCSI_QDEPTH_DEFAULT) + return -EOPNOTSUPP; + if (qdepth > MBOX_MAX_SCSI_CMDS) qdepth = MBOX_MAX_SCSI_CMDS; scsi_adjust_queue_depth(sdev, 0, qdepth); @@ -361,6 +367,7 @@ static struct scsi_host_template megaraid_template_g = { .eh_host_reset_handler = megaraid_reset_handler, .change_queue_depth = megaraid_change_queue_depth, .use_clustering = ENABLE_CLUSTERING, + .no_write_same = 1, .sdev_attrs = megaraid_sdev_attrs, .shost_attrs = megaraid_shost_attrs, }; @@ -393,7 +400,7 @@ megaraid_init(void) // register as a PCI hot-plug driver module - rval = pci_register_driver(&megaraid_pci_driver_g); + rval = pci_register_driver(&megaraid_pci_driver); if (rval < 0) { con_log(CL_ANN, (KERN_WARNING "megaraid: could not register hotplug support.\n")); @@ -414,7 +421,7 @@ megaraid_exit(void) con_log(CL_DLEVEL1, (KERN_NOTICE "megaraid: unloading framework\n")); // unregister as PCI hotplug driver - pci_unregister_driver(&megaraid_pci_driver_g); + pci_unregister_driver(&megaraid_pci_driver); return; } @@ -426,9 +433,9 @@ megaraid_exit(void) * @id : pci device id of the class of controllers * * This routine should be called whenever a new adapter is detected by the - * PCI hotplug susbsytem. + * PCI hotplug susbsystem. */ -static int __devinit +static int megaraid_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) { adapter_t *adapter; @@ -458,7 +465,7 @@ megaraid_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) if (adapter == NULL) { con_log(CL_ANN, (KERN_WARNING - "megaraid: out of memory, %s %d.\n", __FUNCTION__, __LINE__)); + "megaraid: out of memory, %s %d.\n", __func__, __LINE__)); goto out_probe_one; } @@ -473,7 +480,7 @@ megaraid_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) // Setup the default DMA mask. This would be changed later on // depending on hardware capabilities - if (pci_set_dma_mask(adapter->pdev, DMA_32BIT_MASK) != 0) { + if (pci_set_dma_mask(adapter->pdev, DMA_BIT_MASK(32)) != 0) { con_log(CL_ANN, (KERN_WARNING "megaraid: pci_set_dma_mask failed:%d\n", __LINE__)); @@ -528,7 +535,6 @@ megaraid_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) return 0; out_cmm_unreg: - pci_set_drvdata(pdev, NULL); megaraid_cmm_unregister(adapter); out_fini_mbox: megaraid_fini_mbox(adapter); @@ -543,7 +549,7 @@ out_probe_one: /** * megaraid_detach_one - release framework resources and call LLD release routine - * @pdev : handle for our PCI cofiguration space + * @pdev : handle for our PCI configuration space * * This routine is called during driver unload. We free all the allocated * resources and call the corresponding LLD so that it can also release all @@ -588,11 +594,6 @@ megaraid_detach_one(struct pci_dev *pdev) // detach from the IO sub-system megaraid_io_detach(adapter); - // reset the device state in the PCI structure. We check this - // condition when we enter here. If the device state is NULL, - // that would mean the device has already been removed - pci_set_drvdata(pdev, NULL); - // Unregister from common management module // // FIXME: this must return success or failure for conditions if there @@ -729,7 +730,7 @@ megaraid_io_detach(adapter_t *adapter) * - Allocate memory required for all the commands * - Use internal library of FW routines, build up complete soft state */ -static int __devinit +static int megaraid_init_mbox(adapter_t *adapter) { struct pci_dev *pdev; @@ -900,11 +901,11 @@ megaraid_init_mbox(adapter_t *adapter) adapter->pdev->device == PCI_DEVICE_ID_PERC4_DI_EVERGLADES) || (adapter->pdev->vendor == PCI_VENDOR_ID_DELL && adapter->pdev->device == PCI_DEVICE_ID_PERC4E_DI_KOBUK)) { - if (pci_set_dma_mask(adapter->pdev, DMA_64BIT_MASK)) { + if (pci_set_dma_mask(adapter->pdev, DMA_BIT_MASK(64))) { con_log(CL_ANN, (KERN_WARNING "megaraid: DMA mask for 64-bit failed\n")); - if (pci_set_dma_mask (adapter->pdev, DMA_32BIT_MASK)) { + if (pci_set_dma_mask (adapter->pdev, DMA_BIT_MASK(32))) { con_log(CL_ANN, (KERN_WARNING "megaraid: 32-bit DMA mask failed\n")); goto out_free_sysfs_res; @@ -973,7 +974,7 @@ megaraid_fini_mbox(adapter_t *adapter) * @adapter : soft state of the raid controller * * Allocate and align the shared mailbox. This maibox is used to issue - * all the commands. For IO based controllers, the mailbox is also regsitered + * all the commands. For IO based controllers, the mailbox is also registered * with the FW. Allocate memory for all commands as well. * This is our big allocator. */ @@ -1002,7 +1003,7 @@ megaraid_alloc_cmd_packets(adapter_t *adapter) if (!raid_dev->una_mbox64) { con_log(CL_ANN, (KERN_WARNING - "megaraid: out of memory, %s %d\n", __FUNCTION__, + "megaraid: out of memory, %s %d\n", __func__, __LINE__)); return -1; } @@ -1030,7 +1031,7 @@ megaraid_alloc_cmd_packets(adapter_t *adapter) if (!adapter->ibuf) { con_log(CL_ANN, (KERN_WARNING - "megaraid: out of memory, %s %d\n", __FUNCTION__, + "megaraid: out of memory, %s %d\n", __func__, __LINE__)); goto out_free_common_mbox; @@ -1052,7 +1053,7 @@ megaraid_alloc_cmd_packets(adapter_t *adapter) if (adapter->kscb_list == NULL) { con_log(CL_ANN, (KERN_WARNING - "megaraid: out of memory, %s %d\n", __FUNCTION__, + "megaraid: out of memory, %s %d\n", __func__, __LINE__)); goto out_free_ibuf; } @@ -1060,7 +1061,7 @@ megaraid_alloc_cmd_packets(adapter_t *adapter) // memory allocation for our command packets if (megaraid_mbox_setup_dma_pools(adapter) != 0) { con_log(CL_ANN, (KERN_WARNING - "megaraid: out of memory, %s %d\n", __FUNCTION__, + "megaraid: out of memory, %s %d\n", __func__, __LINE__)); goto out_free_scb_list; } @@ -1478,7 +1479,7 @@ mbox_post_cmd(adapter_t *adapter, scb_t *scb) * Queue entry point for mailbox based controllers. */ static int -megaraid_queue_command(struct scsi_cmnd *scp, void (*done)(struct scsi_cmnd *)) +megaraid_queue_command_lck(struct scsi_cmnd *scp, void (*done)(struct scsi_cmnd *)) { adapter_t *adapter; scb_t *scb; @@ -1507,6 +1508,8 @@ megaraid_queue_command(struct scsi_cmnd *scp, void (*done)(struct scsi_cmnd *)) return if_busy; } +static DEF_SCSI_QCMD(megaraid_queue_command) + /** * megaraid_mbox_build_cmd - transform the mid-layer scsi commands * @adapter : controller's soft state @@ -1583,10 +1586,8 @@ megaraid_mbox_build_cmd(adapter_t *adapter, struct scsi_cmnd *scp, int *busy) caddr_t vaddr; sgl = scsi_sglist(scp); - if (sgl->page) { - vaddr = (caddr_t) - (page_address((&sgl[0])->page) - + (&sgl[0])->offset); + if (sg_page(sgl)) { + vaddr = (caddr_t) sg_virt(&sgl[0]); memset(vaddr, 0, scp->cmnd[4]); } @@ -2021,7 +2022,7 @@ megaraid_mbox_prepare_pthru(adapter_t *adapter, scb_t *scb, * @scb : scsi control block * @scp : scsi command from the mid-layer * - * Prepare a command for the scsi physical devices. This rountine prepares + * Prepare a command for the scsi physical devices. This routine prepares * commands for devices which can take extended CDBs (>10 bytes). */ static void @@ -2310,8 +2311,8 @@ megaraid_mbox_dpc(unsigned long devp) // Was an abort issued for this command earlier if (scb->state & SCB_ABORT) { con_log(CL_ANN, (KERN_NOTICE - "megaraid: aborted cmd %lx[%x] completed\n", - scp->serial_number, scb->sno)); + "megaraid: aborted cmd [%x] completed\n", + scb->sno)); } /* @@ -2327,10 +2328,8 @@ megaraid_mbox_dpc(unsigned long devp) && IS_RAID_CH(raid_dev, scb->dev_channel)) { sgl = scsi_sglist(scp); - if (sgl->page) { - c = *(unsigned char *) - (page_address((&sgl[0])->page) + - (&sgl[0])->offset); + if (sg_page(sgl)) { + c = *(unsigned char *) sg_virt(&sgl[0]); } else { con_log(CL_ANN, (KERN_WARNING "megaraid mailbox: invalid sg:%d\n", @@ -2469,8 +2468,8 @@ megaraid_abort_handler(struct scsi_cmnd *scp) raid_dev = ADAP2RAIDDEV(adapter); con_log(CL_ANN, (KERN_WARNING - "megaraid: aborting-%ld cmd=%x <c=%d t=%d l=%d>\n", - scp->serial_number, scp->cmnd[0], SCP2CHANNEL(scp), + "megaraid: aborting cmd=%x <c=%d t=%d l=%d>\n", + scp->cmnd[0], SCP2CHANNEL(scp), SCP2TARGET(scp), SCP2LUN(scp))); // If FW has stopped responding, simply return failure @@ -2493,9 +2492,8 @@ megaraid_abort_handler(struct scsi_cmnd *scp) list_del_init(&scb->list); // from completed list con_log(CL_ANN, (KERN_WARNING - "megaraid: %ld:%d[%d:%d], abort from completed list\n", - scp->serial_number, scb->sno, - scb->dev_channel, scb->dev_target)); + "megaraid: %d[%d:%d], abort from completed list\n", + scb->sno, scb->dev_channel, scb->dev_target)); scp->result = (DID_ABORT << 16); scp->scsi_done(scp); @@ -2524,9 +2522,8 @@ megaraid_abort_handler(struct scsi_cmnd *scp) ASSERT(!(scb->state & SCB_ISSUED)); con_log(CL_ANN, (KERN_WARNING - "megaraid abort: %ld[%d:%d], driver owner\n", - scp->serial_number, scb->dev_channel, - scb->dev_target)); + "megaraid abort: [%d:%d], driver owner\n", + scb->dev_channel, scb->dev_target)); scp->result = (DID_ABORT << 16); scp->scsi_done(scp); @@ -2557,25 +2554,21 @@ megaraid_abort_handler(struct scsi_cmnd *scp) if (!(scb->state & SCB_ISSUED)) { con_log(CL_ANN, (KERN_WARNING - "megaraid abort: %ld%d[%d:%d], invalid state\n", - scp->serial_number, scb->sno, scb->dev_channel, - scb->dev_target)); + "megaraid abort: %d[%d:%d], invalid state\n", + scb->sno, scb->dev_channel, scb->dev_target)); BUG(); } else { con_log(CL_ANN, (KERN_WARNING - "megaraid abort: %ld:%d[%d:%d], fw owner\n", - scp->serial_number, scb->sno, scb->dev_channel, - scb->dev_target)); + "megaraid abort: %d[%d:%d], fw owner\n", + scb->sno, scb->dev_channel, scb->dev_target)); } } } spin_unlock_irq(&adapter->lock); if (!found) { - con_log(CL_ANN, (KERN_WARNING - "megaraid abort: scsi cmd:%ld, do now own\n", - scp->serial_number)); + con_log(CL_ANN, (KERN_WARNING "megaraid abort: do now own\n")); // FIXME: Should there be a callback for this command? return SUCCESS; @@ -2588,7 +2581,7 @@ megaraid_abort_handler(struct scsi_cmnd *scp) } /** - * megaraid_reset_handler - device reset hadler for mailbox based driver + * megaraid_reset_handler - device reset handler for mailbox based driver * @scp : reference command * * Reset handler for the mailbox based controller. First try to find out if @@ -2646,9 +2639,8 @@ megaraid_reset_handler(struct scsi_cmnd *scp) } else { if (scb->scp == scp) { // Found command con_log(CL_ANN, (KERN_WARNING - "megaraid: %ld:%d[%d:%d], reset from pending list\n", - scp->serial_number, scb->sno, - scb->dev_channel, scb->dev_target)); + "megaraid: %d[%d:%d], reset from pending list\n", + scb->sno, scb->dev_channel, scb->dev_target)); } else { con_log(CL_ANN, (KERN_WARNING "megaraid: IO packet with %d[%d:%d] being reset\n", @@ -2686,7 +2678,7 @@ megaraid_reset_handler(struct scsi_cmnd *scp) (MBOX_RESET_WAIT + MBOX_RESET_EXT_WAIT) - i)); } - // bailout if no recovery happended in reset time + // bailout if no recovery happened in reset time if (adapter->outstanding_cmds == 0) { break; } @@ -2708,7 +2700,7 @@ megaraid_reset_handler(struct scsi_cmnd *scp) } else { con_log(CL_ANN, (KERN_NOTICE - "megaraid mbox: reset sequence completed sucessfully\n")); + "megaraid mbox: reset sequence completed successfully\n")); } @@ -2734,7 +2726,7 @@ megaraid_reset_handler(struct scsi_cmnd *scp) } out: - spin_unlock_irq(&adapter->lock); + spin_unlock(&adapter->lock); return rval; } @@ -2985,7 +2977,7 @@ megaraid_mbox_product_info(adapter_t *adapter) if (pinfo == NULL) { con_log(CL_ANN, (KERN_WARNING - "megaraid: out of memory, %s %d\n", __FUNCTION__, + "megaraid: out of memory, %s %d\n", __func__, __LINE__)); return -1; @@ -3172,6 +3164,23 @@ megaraid_mbox_support_random_del(adapter_t *adapter) uint8_t raw_mbox[sizeof(mbox_t)]; int rval; + /* + * Newer firmware on Dell CERC expect a different + * random deletion handling, so disable it. + */ + if (adapter->pdev->vendor == PCI_VENDOR_ID_AMI && + adapter->pdev->device == PCI_DEVICE_ID_AMI_MEGARAID3 && + adapter->pdev->subsystem_vendor == PCI_VENDOR_ID_DELL && + adapter->pdev->subsystem_device == PCI_SUBSYS_ID_CERC_ATA100_4CH && + (adapter->fw_version[0] > '6' || + (adapter->fw_version[0] == '6' && + adapter->fw_version[2] > '6') || + (adapter->fw_version[0] == '6' + && adapter->fw_version[2] == '6' + && adapter->fw_version[3] > '1'))) { + con_log(CL_DLEVEL1, ("megaraid: disable random deletion\n")); + return 0; + } mbox = (mbox_t *)raw_mbox; @@ -3432,7 +3441,7 @@ megaraid_mbox_display_scb(adapter_t *adapter, scb_t *scb) * megaraid_mbox_setup_device_map - manage device ids * @adapter : Driver's soft state * - * Manange the device ids to have an appropraite mapping between the kernel + * Manage the device ids to have an appropriate mapping between the kernel * scsi addresses and megaraid scsi and logical drive addresses. We export * scsi devices on their actual addresses, whereas the logical drives are * exported on a virtual scsi channel. @@ -3468,12 +3477,12 @@ megaraid_mbox_setup_device_map(adapter_t *adapter) /* * START: Interface for the common management module * - * This is the module, which interfaces with the common mangement module to + * This is the module, which interfaces with the common management module to * provide support for ioctl and sysfs */ /** - * megaraid_cmm_register - register with the mangement module + * megaraid_cmm_register - register with the management module * @adapter : HBA soft state * * Register with the management module, which allows applications to issue @@ -3495,7 +3504,7 @@ megaraid_cmm_register(adapter_t *adapter) if (adapter->uscb_list == NULL) { con_log(CL_ANN, (KERN_WARNING - "megaraid: out of memory, %s %d\n", __FUNCTION__, + "megaraid: out of memory, %s %d\n", __func__, __LINE__)); return -1; } @@ -3561,7 +3570,7 @@ megaraid_cmm_register(adapter_t *adapter) /** - * megaraid_cmm_unregister - un-register with the mangement module + * megaraid_cmm_unregister - un-register with the management module * @adapter : HBA soft state * * Un-register with the management module. @@ -3583,7 +3592,7 @@ megaraid_cmm_unregister(adapter_t *adapter) * @kioc : CMM interface packet * @action : command action * - * This routine is invoked whenever the Common Mangement Module (CMM) has a + * This routine is invoked whenever the Common Management Module (CMM) has a * command for us. The 'action' parameter specifies if this is a new command * or otherwise. */ @@ -3866,7 +3875,7 @@ megaraid_sysfs_alloc_resources(adapter_t *adapter) !raid_dev->sysfs_buffer) { con_log(CL_ANN, (KERN_WARNING - "megaraid: out of memory, %s %d\n", __FUNCTION__, + "megaraid: out of memory, %s %d\n", __func__, __LINE__)); rval = -ENOMEM; @@ -3948,12 +3957,12 @@ megaraid_sysfs_get_ldmap_timeout(unsigned long data) * * This routine will be called whenever user reads the logical drive * attributes, go get the current logical drive mapping table from the - * firmware. We use the managment API's to issue commands to the controller. + * firmware. We use the management API's to issue commands to the controller. * * NOTE: The commands issuance functionality is not generalized and * implemented in context of "get ld map" command only. If required, the * command issuance logical can be trivially pulled out and implemented as a - * standalone libary. For now, this should suffice since there is no other + * standalone library. For now, this should suffice since there is no other * user of this interface. * * Return 0 on success. @@ -4067,9 +4076,10 @@ megaraid_sysfs_get_ldmap(adapter_t *adapter) * handle, since we do not interface with applications directly. */ static ssize_t -megaraid_sysfs_show_app_hndl(struct class_device *cdev, char *buf) +megaraid_sysfs_show_app_hndl(struct device *dev, struct device_attribute *attr, + char *buf) { - struct Scsi_Host *shost = class_to_shost(cdev); + struct Scsi_Host *shost = class_to_shost(dev); adapter_t *adapter = (adapter_t *)SCSIHOST2ADAP(shost); uint32_t app_hndl; |
