📄 megaraid_mbox.c
字号:
/* * * Linux MegaRAID device driver * * Copyright (c) 2003-2004 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 * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * * FILE : megaraid_mbox.c * Version : v2.20.4.6 (Mar 07 2005) * * Authors: * Atul Mukker <Atul.Mukker@lsil.com> * Sreenivas Bagalkote <Sreenivas.Bagalkote@lsil.com> * Manoj Jose <Manoj.Jose@lsil.com> * * List of supported controllers * * OEM Product Name VID DID SSVID SSID * --- ------------ --- --- ---- ---- * Dell PERC3/QC 101E 1960 1028 0471 * Dell PERC3/DC 101E 1960 1028 0493 * Dell PERC3/SC 101E 1960 1028 0475 * Dell PERC3/Di 1028 1960 1028 0123 * Dell PERC4/SC 1000 1960 1028 0520 * Dell PERC4/DC 1000 1960 1028 0518 * Dell PERC4/QC 1000 0407 1028 0531 * Dell PERC4/Di 1028 000F 1028 014A * Dell PERC 4e/Si 1028 0013 1028 016c * Dell PERC 4e/Di 1028 0013 1028 016d * Dell PERC 4e/Di 1028 0013 1028 016e * Dell PERC 4e/Di 1028 0013 1028 016f * Dell PERC 4e/Di 1028 0013 1028 0170 * Dell PERC 4e/DC 1000 0408 1028 0002 * Dell PERC 4e/SC 1000 0408 1028 0001 * * * LSI MegaRAID SCSI 320-0 1000 1960 1000 A520 * LSI MegaRAID SCSI 320-1 1000 1960 1000 0520 * LSI MegaRAID SCSI 320-2 1000 1960 1000 0518 * LSI MegaRAID SCSI 320-0X 1000 0407 1000 0530 * LSI MegaRAID SCSI 320-2X 1000 0407 1000 0532 * LSI MegaRAID SCSI 320-4X 1000 0407 1000 0531 * LSI MegaRAID SCSI 320-1E 1000 0408 1000 0001 * LSI MegaRAID SCSI 320-2E 1000 0408 1000 0002 * LSI MegaRAID SATA 150-4 1000 1960 1000 4523 * LSI MegaRAID SATA 150-6 1000 1960 1000 0523 * LSI MegaRAID SATA 300-4X 1000 0409 1000 3004 * LSI MegaRAID SATA 300-8X 1000 0409 1000 3008 * * INTEL RAID Controller SRCU42X 1000 0407 8086 0532 * INTEL RAID Controller SRCS16 1000 1960 8086 0523 * INTEL RAID Controller SRCU42E 1000 0408 8086 0002 * INTEL RAID Controller SRCZCRX 1000 0407 8086 0530 * INTEL RAID Controller SRCS28X 1000 0409 8086 3008 * INTEL RAID Controller SROMBU42E 1000 0408 8086 3431 * INTEL RAID Controller SROMBU42E 1000 0408 8086 3499 * INTEL RAID Controller SRCU51L 1000 1960 8086 0520 * * FSC MegaRAID PCI Express ROMB 1000 0408 1734 1065 * * ACER MegaRAID ROMB-2E 1000 0408 1025 004D * * NEC MegaRAID PCI Express ROMB 1000 0408 1033 8287 * * For history of changes, see Documentation/ChangeLog.megaraid */#include "megaraid_mbox.h"static int megaraid_init(void);static void megaraid_exit(void);static int megaraid_probe_one(struct pci_dev*, const struct pci_device_id *);static void megaraid_detach_one(struct pci_dev *);static void megaraid_mbox_shutdown(struct pci_dev *);static int megaraid_io_attach(adapter_t *);static void megaraid_io_detach(adapter_t *);static int megaraid_init_mbox(adapter_t *);static void megaraid_fini_mbox(adapter_t *);static int megaraid_alloc_cmd_packets(adapter_t *);static void megaraid_free_cmd_packets(adapter_t *);static int megaraid_mbox_setup_dma_pools(adapter_t *);static void megaraid_mbox_teardown_dma_pools(adapter_t *);static int megaraid_sysfs_alloc_resources(adapter_t *);static void megaraid_sysfs_free_resources(adapter_t *);static int megaraid_abort_handler(struct scsi_cmnd *);static int megaraid_reset_handler(struct scsi_cmnd *);static int mbox_post_sync_cmd(adapter_t *, uint8_t []);static int mbox_post_sync_cmd_fast(adapter_t *, uint8_t []);static int megaraid_busywait_mbox(mraid_device_t *);static int megaraid_mbox_product_info(adapter_t *);static int megaraid_mbox_extended_cdb(adapter_t *);static int megaraid_mbox_support_ha(adapter_t *, uint16_t *);static int megaraid_mbox_support_random_del(adapter_t *);static int megaraid_mbox_get_max_sg(adapter_t *);static void megaraid_mbox_enum_raid_scsi(adapter_t *);static void megaraid_mbox_flush_cache(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 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 *, struct scsi_cmnd *);static void megaraid_mbox_prepare_epthru(adapter_t *, scb_t *, struct scsi_cmnd *);static irqreturn_t megaraid_isr(int, void *, struct pt_regs *);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_ldnum(struct device *, struct device_attribute *attr, char *);static int megaraid_cmm_register(adapter_t *);static int megaraid_cmm_unregister(adapter_t *);static int megaraid_mbox_mm_handler(unsigned long, uioc_t *, uint32_t);static int megaraid_mbox_mm_command(adapter_t *, uioc_t *);static void megaraid_mbox_mm_done(adapter_t *, scb_t *);static int gather_hbainfo(adapter_t *, mraid_hba_info_t *);static int wait_till_fw_empty(adapter_t *);MODULE_AUTHOR("LSI Logic Corporation");MODULE_DESCRIPTION("LSI Logic MegaRAID Mailbox Driver");MODULE_LICENSE("GPL");MODULE_VERSION(MEGARAID_VERSION);/* * ### modules parameters for driver ### *//** * Set to enable driver to expose unconfigured disk to kernel */static int megaraid_expose_unconf_disks = 0;module_param_named(unconf_disks, megaraid_expose_unconf_disks, int, 0);MODULE_PARM_DESC(unconf_disks, "Set to expose unconfigured disks to kernel (default=0)");/** * driver wait time if the adapter's mailbox is busy */static unsigned int max_mbox_busy_wait = MBOX_BUSY_WAIT;module_param_named(busy_wait, max_mbox_busy_wait, int, 0);MODULE_PARM_DESC(busy_wait, "Max wait for mailbox in microseconds if busy (default=10)");/** * number of sectors per IO command */static unsigned int megaraid_max_sectors = MBOX_MAX_SECTORS;module_param_named(max_sectors, megaraid_max_sectors, int, 0);MODULE_PARM_DESC(max_sectors, "Maximum number of sectors per IO command (default=128)");/** * number of commands per logical unit */static unsigned int megaraid_cmd_per_lun = MBOX_DEF_CMD_PER_LUN;module_param_named(cmd_per_lun, megaraid_cmd_per_lun, int, 0);MODULE_PARM_DESC(cmd_per_lun, "Maximum number of commands per logical unit (default=64)");/** * Fast driver load option, skip scanning for physical devices during load. * This would result in non-disk devices being skipped during driver load * time. These can be later added though, using /proc/scsi/scsi */static unsigned int megaraid_fast_load = 0;module_param_named(fast_load, megaraid_fast_load, int, 0);MODULE_PARM_DESC(fast_load, "Faster loading of the driver, skips physical devices! (default=0)");/** * mraid_debug level - threshold for amount of information to be displayed by * the driver. This level can be changed through modules parameters, ioctl or * sysfs/proc interface. By default, print the announcement messages only. */int mraid_debug_level = CL_ANN;module_param_named(debug_level, mraid_debug_level, int, 0);MODULE_PARM_DESC(debug_level, "Debug level for driver (default=0)");/* * ### global data ### */static uint8_t megaraid_mbox_version[8] = { 0x02, 0x20, 0x04, 0x06, 3, 7, 20, 5 };/* * PCI table for all supported controllers. */static struct pci_device_id pci_id_table_g[] = { { PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_PERC4_DI_DISCOVERY, PCI_VENDOR_ID_DELL, PCI_SUBSYS_ID_PERC4_DI_DISCOVERY, }, { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_PERC4_SC, PCI_VENDOR_ID_DELL, PCI_SUBSYS_ID_PERC4_SC, }, { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_PERC4_DC, PCI_VENDOR_ID_DELL, PCI_SUBSYS_ID_PERC4_DC, }, { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_VERDE, PCI_ANY_ID, PCI_ANY_ID, }, { PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_PERC4_DI_EVERGLADES, PCI_VENDOR_ID_DELL, PCI_SUBSYS_ID_PERC4_DI_EVERGLADES, }, { PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_PERC4E_SI_BIGBEND, PCI_VENDOR_ID_DELL, PCI_SUBSYS_ID_PERC4E_SI_BIGBEND, }, { PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_PERC4E_DI_KOBUK, PCI_VENDOR_ID_DELL, PCI_SUBSYS_ID_PERC4E_DI_KOBUK, }, { PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_PERC4E_DI_CORVETTE, PCI_VENDOR_ID_DELL, PCI_SUBSYS_ID_PERC4E_DI_CORVETTE, }, { PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_PERC4E_DI_EXPEDITION, PCI_VENDOR_ID_DELL, PCI_SUBSYS_ID_PERC4E_DI_EXPEDITION, }, { PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_PERC4E_DI_GUADALUPE, PCI_VENDOR_ID_DELL, PCI_SUBSYS_ID_PERC4E_DI_GUADALUPE, }, { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_DOBSON, PCI_ANY_ID, PCI_ANY_ID, }, { PCI_VENDOR_ID_AMI, PCI_DEVICE_ID_AMI_MEGARAID3, PCI_VENDOR_ID_DELL, PCI_SUBSYS_ID_PERC3_QC, }, { PCI_VENDOR_ID_AMI, PCI_DEVICE_ID_AMI_MEGARAID3, PCI_VENDOR_ID_DELL, PCI_SUBSYS_ID_PERC3_DC, }, { PCI_VENDOR_ID_AMI, PCI_DEVICE_ID_AMI_MEGARAID3, PCI_VENDOR_ID_DELL, PCI_SUBSYS_ID_PERC3_SC, }, { PCI_VENDOR_ID_AMI, PCI_DEVICE_ID_AMI_MEGARAID3, PCI_VENDOR_ID_AMI, PCI_SUBSYS_ID_PERC3_SC, }, { PCI_VENDOR_ID_AMI, PCI_DEVICE_ID_AMI_MEGARAID3, PCI_VENDOR_ID_AMI, PCI_SUBSYS_ID_PERC3_DC, }, { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_MEGARAID_SCSI_320_0, PCI_VENDOR_ID_LSI_LOGIC, PCI_SUBSYS_ID_MEGARAID_SCSI_320_0, }, { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_MEGARAID_SCSI_320_1, PCI_VENDOR_ID_LSI_LOGIC, PCI_SUBSYS_ID_MEGARAID_SCSI_320_1, }, { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_MEGARAID_SCSI_320_2, PCI_VENDOR_ID_LSI_LOGIC, PCI_SUBSYS_ID_MEGARAID_SCSI_320_2, }, { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_MEGARAID_I4_133_RAID, PCI_VENDOR_ID_LSI_LOGIC, PCI_SUBSYS_ID_MEGARAID_I4_133_RAID, }, { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_MEGARAID_SATA_150_4, PCI_VENDOR_ID_LSI_LOGIC, PCI_SUBSYS_ID_MEGARAID_SATA_150_4, }, { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_MEGARAID_SATA_150_6, PCI_VENDOR_ID_LSI_LOGIC, PCI_SUBSYS_ID_MEGARAID_SATA_150_6, }, { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LINDSAY, PCI_ANY_ID, PCI_ANY_ID, }, { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_INTEL_RAID_SRCS16, PCI_VENDOR_ID_INTEL, PCI_SUBSYS_ID_INTEL_RAID_SRCS16, }, { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_INTEL_RAID_SRCU41L_LAKE_SHETEK, PCI_VENDOR_ID_INTEL, PCI_SUBSYS_ID_INTEL_RAID_SRCU41L_LAKE_SHETEK, }, {0} /* Terminating entry */};MODULE_DEVICE_TABLE(pci, pci_id_table_g);static struct pci_driver megaraid_pci_driver_g = { .name = "megaraid", .id_table = pci_id_table_g, .probe = megaraid_probe_one, .remove = __devexit_p(megaraid_detach_one), .shutdown = megaraid_mbox_shutdown,};// 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, NULL);// Host template initializer for megaraid mbox sysfs device attributesstatic struct class_device_attribute *megaraid_shost_attrs[] = { &class_device_attr_megaraid_mbox_app_hndl, NULL,};DEVICE_ATTR(megaraid_mbox_ld, S_IRUSR, megaraid_sysfs_show_ldnum, NULL);// Host template initializer for megaraid mbox sysfs device attributesstatic struct device_attribute *megaraid_sdev_attrs[] = { &dev_attr_megaraid_mbox_ld, NULL,};/* * Scsi host template for megaraid unified driver */static struct scsi_host_template megaraid_template_g = { .module = THIS_MODULE, .name = "LSI Logic MegaRAID driver", .proc_name = "megaraid", .queuecommand = megaraid_queue_command, .eh_abort_handler = megaraid_abort_handler, .eh_device_reset_handler = megaraid_reset_handler, .eh_bus_reset_handler = megaraid_reset_handler, .eh_host_reset_handler = megaraid_reset_handler, .use_clustering = ENABLE_CLUSTERING, .sdev_attrs = megaraid_sdev_attrs, .shost_attrs = megaraid_shost_attrs,};/** * megaraid_init - module load hook * * We register ourselves as hotplug enabled module and let PCI subsystem * discover our adaters **/static int __initmegaraid_init(void){ int rval; // Announce the driver version con_log(CL_ANN, (KERN_INFO "megaraid: %s %s\n", MEGARAID_VERSION, MEGARAID_EXT_VERSION)); // check validity of module parameters if (megaraid_cmd_per_lun > MBOX_MAX_SCSI_CMDS) { con_log(CL_ANN, (KERN_WARNING "megaraid mailbox: max commands per lun reset to %d\n", MBOX_MAX_SCSI_CMDS)); megaraid_cmd_per_lun = MBOX_MAX_SCSI_CMDS; } // register as a PCI hot-plug driver module rval = pci_register_driver(&megaraid_pci_driver_g); if (rval < 0) { con_log(CL_ANN, (KERN_WARNING "megaraid: could not register hotplug support.\n")); } return rval;}/** * megaraid_exit - driver unload entry point * * We simply unwrap the megaraid_init routine here */static void __exitmegaraid_exit(void){ con_log(CL_DLEVEL1, (KERN_NOTICE "megaraid: unloading framework\n")); // unregister as PCI hotplug driver pci_unregister_driver(&megaraid_pci_driver_g); return;}/** * megaraid_probe_one - PCI hotplug entry point * @param pdev : handle to this controller's PCI configuration space * @param 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. **/static int __devinitmegaraid_probe_one(struct pci_dev *pdev, const struct pci_device_id *id){ adapter_t *adapter; // detected a new controller con_log(CL_ANN, (KERN_INFO "megaraid: probe new device %#4.04x:%#4.04x:%#4.04x:%#4.04x: ", pdev->vendor, pdev->device, pdev->subsystem_vendor, pdev->subsystem_device)); con_log(CL_ANN, ("bus %d:slot %d:func %d\n", pdev->bus->number, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn))); if (pci_enable_device(pdev)) { con_log(CL_ANN, (KERN_WARNING "megaraid: pci_enable_device failed\n")); return -ENODEV; } // Enable bus-mastering on this controller pci_set_master(pdev); // Allocate the per driver initialization structure adapter = kmalloc(sizeof(adapter_t), GFP_KERNEL); if (adapter == NULL) { con_log(CL_ANN, (KERN_WARNING "megaraid: out of memory, %s %d.\n", __FUNCTION__, __LINE__)); goto out_probe_one; } memset(adapter, 0, sizeof(adapter_t)); // set up PCI related soft state and other pre-known parameters adapter->unique_id = pdev->bus->number << 8 | pdev->devfn; adapter->irq = pdev->irq; adapter->pdev = pdev; atomic_set(&adapter->being_detached, 0); // 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) { con_log(CL_ANN, (KERN_WARNING "megaraid: pci_set_dma_mask failed:%d\n", __LINE__));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -