SOURCES: linux-2.6-cciss-3.6.18.patch (NEW) - from hp.com
marcus
marcus at pld-linux.org
Mon Nov 3 09:48:16 CET 2008
Author: marcus Date: Mon Nov 3 08:48:16 2008 GMT
Module: SOURCES Tag: HEAD
---- Log message:
- from hp.com
---- Files affected:
SOURCES:
linux-2.6-cciss-3.6.18.patch (NONE -> 1.1) (NEW)
---- Diffs:
================================================================
Index: SOURCES/linux-2.6-cciss-3.6.18.patch
diff -u /dev/null SOURCES/linux-2.6-cciss-3.6.18.patch:1.1
--- /dev/null Mon Nov 3 09:48:17 2008
+++ SOURCES/linux-2.6-cciss-3.6.18.patch Mon Nov 3 09:48:11 2008
@@ -0,0 +1,4876 @@
+diff -uNr linux-2.6.16.orig/Documentation/cciss.txt linux-2.6.16/Documentation/cciss.txt
+--- linux-2.6.16.orig/Documentation/cciss.txt 2006-03-20 06:53:29.000000000 +0100
++++ linux-2.6.16/Documentation/cciss.txt 2008-10-03 02:40:19.000000000 +0200
+@@ -16,10 +16,16 @@
+ * SA 6i
+ * SA P600
+ * SA P800
+- * SA E400
++ * SA P400
+ * SA P400i
+ * SA E200
+ * SA E200i
++ * SA E500
++
++This driver also implements a new method of detecting HP Smart Array
++controllers. If an "unknown" controller is detected, we will attempt to
++bind to the controller. On success a message is displayed informing the
++user to upgrade the driver. On failure we bail.
+
+ If nodes are not already created in the /dev/cciss directory, run as root:
+
+@@ -36,8 +42,8 @@
+ Major numbers:
+ 104 cciss0
+ 105 cciss1
+- 106 cciss2
+- 105 cciss3
++ 106 cciss2
++ 107 cciss3
+ 108 cciss4
+ 109 cciss5
+ 110 cciss6
+@@ -79,7 +85,7 @@
+ the SCSI core may not yet be initialized (because the driver is a block
+ driver) and attempting to register it with the SCSI core in such a case
+ would cause a hang. This is best done via an initialization script
+-(typically in /etc/init.d, but could vary depending on distibution).
++(typically in /etc/init.d, but could vary depending on distribution).
+ For example:
+
+ for x in /proc/driver/cciss/cciss[0-9]*
+@@ -145,18 +151,18 @@
+ If that doesn't work, the SCSI bus is reset. If that doesn't work
+ the host bus adapter is reset. Because the cciss driver is a block
+ driver as well as a SCSI driver and only the tape drives and medium
+-changers are presented to the SCSI mid layer, and unlike more
++changers are presented to the SCSI mid layer, and unlike more
+ straightforward SCSI drivers, disk i/o continues through the block
+ side during the SCSI error recovery process, the cciss driver only
+ implements the first two of these actions, aborting the command, and
+-resetting the device. Additionally, most tape drives will not oblige
+-in aborting commands, and sometimes it appears they will not even
+-obey a reset coommand, though in most circumstances they will. In
+-the case that the command cannot be aborted and the device cannot be
++resetting the device. Additionally, most tape drives will not oblige
++in aborting commands, and sometimes it appears they will not even
++obey a reset command, though in most circumstances they will. In
++the case that the command cannot be aborted and the device cannot be
+ reset, the device will be set offline.
+
+ In the event the error handling code is triggered and a tape drive is
+-successfully reset or the tardy command is successfully aborted, the
++successfully reset or the tardy command is successfully aborted, the
+ tape drive may still not allow i/o to continue until some command
+ is issued which positions the tape to a known position. Typically you
+ must rewind the tape (by issuing "mt -f /dev/st0 rewind" for example)
+diff -uNr linux-2.6.16.orig/drivers/block/cciss.c linux-2.6.16/drivers/block/cciss.c
+--- linux-2.6.16.orig/drivers/block/cciss.c 2008-11-02 19:51:53.000000000 +0100
++++ linux-2.6.16/drivers/block/cciss.c 2008-10-03 02:40:19.000000000 +0200
+@@ -33,6 +33,7 @@
+ #include <linux/bio.h>
+ #include <linux/blkpg.h>
+ #include <linux/timer.h>
++#include <linux/seq_file.h>
+ #include <linux/proc_fs.h>
+ #include <linux/init.h>
+ #include <linux/hdreg.h>
+@@ -40,111 +41,121 @@
+ #include <linux/compat.h>
+ #include <asm/uaccess.h>
+ #include <asm/io.h>
++#include <asm/div64.h>
++
++#ifdef CONFIG_BLK_DEV_IO_TRACE
++#include <linux/blktrace_api.h>
++#endif
+
+ #include <linux/dma-mapping.h>
+ #include <linux/blkdev.h>
+ #include <linux/genhd.h>
+ #include <linux/completion.h>
++#include <scsi/scsi.h>
++#include <scsi/sg.h>
++#include <scsi/scsi_ioctl.h>
++#include <linux/cdrom.h>
+
+ #define CCISS_DRIVER_VERSION(maj,min,submin) ((maj<<16)|(min<<8)|(submin))
+-#define DRIVER_NAME "HP CISS Driver (v 2.6.10)"
+-#define DRIVER_VERSION CCISS_DRIVER_VERSION(2,6,10)
++#define DRIVER_NAME "HP CISS Driver (v 3.6.18)"
++#define DRIVER_VERSION CCISS_DRIVER_VERSION(3,6,18)
+
+ /* Embedded module documentation macros - see modules.h */
+ MODULE_AUTHOR("Hewlett-Packard Company");
+-MODULE_DESCRIPTION("Driver for HP Controller SA5xxx SA6xxx version 2.6.10");
++MODULE_DESCRIPTION("Driver for HP Controller SA5xxx SA6xxx version 3.6.18");
+ MODULE_SUPPORTED_DEVICE("HP SA5i SA5i+ SA532 SA5300 SA5312 SA641 SA642 SA6400"
+- " SA6i P600 P800 P400 P400i E200 E200i");
++ " SA6i P600 P800 P400 P400i E200 E200i E500");
+ MODULE_LICENSE("GPL");
+
+ #include "cciss_cmd.h"
+ #include "cciss.h"
+ #include <linux/cciss_ioctl.h>
+
++#ifndef PCI_DEVICE_ID_COMPAQ_CISSC
++#define PCI_DEVICE_ID_COMPAQ_CISSC 0x46
++#endif
++#ifndef PCI_DEVICE_ID_HP_CISS
++#define PCI_DEVICE_ID_HP_CISS 0x3210
++#endif
++#ifndef PCI_DEVICE_ID_HP_CISSA
++#define PCI_DEVICE_ID_HP_CISSA 0x3220
++#endif
++#ifndef PCI_DEVICE_ID_HP_CISSC
++#define PCI_DEVICE_ID_HP_CISSC 0x3230
++#endif
++#ifndef PCI_DEVICE_ID_HP_CISSD
++#define PCI_DEVICE_ID_HP_CISSD 0x3238
++#endif
+ /* define the PCI info for the cards we can control */
+ static const struct pci_device_id cciss_pci_device_id[] = {
+- { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_CISS,
+- 0x0E11, 0x4070, 0, 0, 0},
+- { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_CISSB,
+- 0x0E11, 0x4080, 0, 0, 0},
+- { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_CISSB,
+- 0x0E11, 0x4082, 0, 0, 0},
+- { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_CISSB,
+- 0x0E11, 0x4083, 0, 0, 0},
+- { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_CISSC,
+- 0x0E11, 0x409A, 0, 0, 0},
+- { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_CISSC,
+- 0x0E11, 0x409B, 0, 0, 0},
+- { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_CISSC,
+- 0x0E11, 0x409C, 0, 0, 0},
+- { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_CISSC,
+- 0x0E11, 0x409D, 0, 0, 0},
+- { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_CISSC,
+- 0x0E11, 0x4091, 0, 0, 0},
+- { PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSA,
+- 0x103C, 0x3225, 0, 0, 0},
+- { PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSC,
+- 0x103c, 0x3223, 0, 0, 0},
+- { PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSC,
+- 0x103c, 0x3234, 0, 0, 0},
+- { PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSC,
+- 0x103c, 0x3235, 0, 0, 0},
+- { PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSD,
+- 0x103c, 0x3211, 0, 0, 0},
+- { PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSD,
+- 0x103c, 0x3212, 0, 0, 0},
+- { PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSD,
+- 0x103c, 0x3213, 0, 0, 0},
+- { PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSD,
+- 0x103c, 0x3214, 0, 0, 0},
+- { PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSD,
+- 0x103c, 0x3215, 0, 0, 0},
++ {PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_CISS, 0x0E11, 0x4070},
++ {PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_CISSB, 0x0E11, 0x4080},
++ {PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_CISSB, 0x0E11, 0x4082},
++ {PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_CISSB, 0x0E11, 0x4083},
++ {PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_CISSC, 0x0E11, 0x409A},
++ {PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_CISSC, 0x0E11, 0x409B},
++ {PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_CISSC, 0x0E11, 0x409C},
++ {PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_CISSC, 0x0E11, 0x409D},
++ {PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_CISSC, 0x0E11, 0x4091},
++ {PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_CISSC, 0x0E11, 0x409E},
++ {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSA, 0x103C, 0x3225},
++ {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSC, 0x103c, 0x3234},
++ {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSC, 0x103c, 0x3235},
++ {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSD, 0x103c, 0x3211},
++ {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSD, 0x103c, 0x3212},
++ {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSD, 0x103c, 0x3213},
++ {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSD, 0x103c, 0x3214},
++ {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSD, 0x103c, 0x3215},
++ {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSC, 0x103C, 0x3223},
++ {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSC, 0x103c, 0x3237},
++ {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSC, 0x103C, 0x323D},
++ {PCI_VENDOR_ID_HP, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
++ PCI_CLASS_STORAGE_RAID << 8, 0xffff << 8, 0},
+ {0,}
+ };
+ MODULE_DEVICE_TABLE(pci, cciss_pci_device_id);
+
+-#define NR_PRODUCTS ARRAY_SIZE(products)
+-
+ /* board_id = Subsystem Device ID & Vendor ID
+ * product = Marketing Name for the board
+ * access = Address of the struct of function pointers
++ * nr_cmds = Number of commands supported by controller
+ */
+ static struct board_type products[] = {
+- { 0x40700E11, "Smart Array 5300", &SA5_access },
+- { 0x40800E11, "Smart Array 5i", &SA5B_access},
+- { 0x40820E11, "Smart Array 532", &SA5B_access},
+- { 0x40830E11, "Smart Array 5312", &SA5B_access},
+- { 0x409A0E11, "Smart Array 641", &SA5_access},
+- { 0x409B0E11, "Smart Array 642", &SA5_access},
+- { 0x409C0E11, "Smart Array 6400", &SA5_access},
+- { 0x409D0E11, "Smart Array 6400 EM", &SA5_access},
+- { 0x40910E11, "Smart Array 6i", &SA5_access},
+- { 0x3225103C, "Smart Array P600", &SA5_access},
+- { 0x3223103C, "Smart Array P800", &SA5_access},
+- { 0x3234103C, "Smart Array P400", &SA5_access},
+- { 0x3235103C, "Smart Array P400i", &SA5_access},
+- { 0x3211103C, "Smart Array E200i", &SA5_access},
+- { 0x3212103C, "Smart Array E200", &SA5_access},
+- { 0x3213103C, "Smart Array E200i", &SA5_access},
+- { 0x3214103C, "Smart Array E200i", &SA5_access},
+- { 0x3215103C, "Smart Array E200i", &SA5_access},
++ { 0x40700E11, "Smart Array 5300", &SA5_access, 384},
++ { 0x40800E11, "Smart Array 5i", &SA5B_access, 384},
++ { 0x40820E11, "Smart Array 532", &SA5B_access, 384},
++ { 0x40830E11, "Smart Array 5312", &SA5B_access, 384},
++ { 0x409A0E11, "Smart Array 641", &SA5_access, 384},
++ { 0x409B0E11, "Smart Array 642", &SA5_access, 384},
++ { 0x409C0E11, "Smart Array 6400", &SA5_access, 384},
++ { 0x409D0E11, "Smart Array 6400 EM", &SA5_access, 384},
++ { 0x40910E11, "Smart Array 6i", &SA5_access, 384},
++ { 0x409E0E11, "Smart Array 6422", &SA5_access, 384},
++ { 0x3225103C, "Smart Array P600", &SA5_access, 384},
++ { 0x3234103C, "Smart Array P400", &SA5_access, 512},
++ { 0x3235103C, "Smart Array P400i", &SA5_access, 512},
++ { 0x3211103C, "Smart Array E200i", &SA5_access,120},
++ { 0x3212103C, "Smart Array E200", &SA5_access,120},
++ { 0x3213103C, "Smart Array E200i", &SA5_access,120},
++ { 0x3214103C, "Smart Array E200i", &SA5_access, 120},
++ { 0x3215103C, "Smart Array E200i", &SA5_access, 120},
++ { 0x3223103C, "Smart Array P800", &SA5_access, 512},
++ { 0x3237103C, "Smart Array E500", &SA5_access, 128},
++ { 0x323D103C, "Smart Array P700m", &SA5_access, 512},
++ { 0xFFFF103C, "Unknown Smart Array", &SA5_access, 120},
+ };
+
+-/* How long to wait (in millesconds) for board to go into simple mode */
++/* How long to wait (in millisconds) for board to go into simple mode */
+ #define MAX_CONFIG_WAIT 30000
+ #define MAX_IOCTL_CONFIG_WAIT 1000
+
+ /*define how many times we will try a command because of bus resets */
+ #define MAX_CMD_RETRIES 3
+-
+-#define READ_AHEAD 1024
+-#define NR_CMDS 384 /* #commands that can be outstanding */
+ #define MAX_CTLR 32
+
+ /* Originally cciss driver only supports 8 major numbers */
+ #define MAX_CTLR_ORIG 8
+
+-
+ static ctlr_info_t *hba[MAX_CTLR];
+
+ static void do_cciss_request(request_queue_t *q);
+@@ -155,35 +166,40 @@
+ unsigned int cmd, unsigned long arg);
+ static int cciss_getgeo(struct block_device *bdev, struct hd_geometry *geo);
+
+-static int revalidate_allvol(ctlr_info_t *host);
+ static int cciss_revalidate(struct gendisk *disk);
+ static int rebuild_lun_table(ctlr_info_t *h, struct gendisk *del_disk);
+-static int deregister_disk(struct gendisk *disk, drive_info_struct *drv, int clear_all);
+-
+-static void cciss_read_capacity(int ctlr, int logvol, ReadCapdata_struct *buf,
+- int withirq, unsigned int *total_size, unsigned int *block_size);
++static int deregister_disk(struct gendisk *disk, drive_info_struct *drv,
++ int clear_all);
++static void cciss_read_capacity(int ctlr, int logvol, int withirq,
++ sector_t *total_size, unsigned int *block_size);
++static void cciss_read_capacity_16(int ctlr, int logvol, int withirq,
++ sector_t *total_size, unsigned int *block_size);
+ static void cciss_geometry_inquiry(int ctlr, int logvol,
+- int withirq, unsigned int total_size,
++ int withirq, sector_t total_size,
+ unsigned int block_size, InquiryData_struct *inq_buff,
+ drive_info_struct *drv);
+ static void cciss_getgeometry(int cntl_num);
+-static void __devinit cciss_interrupt_mode(ctlr_info_t *, struct pci_dev *, __u32);
++static void __devinit cciss_interrupt_mode(ctlr_info_t *, struct pci_dev *,
++ __u32);
+ static void start_io( ctlr_info_t *h);
+ static int sendcmd( __u8 cmd, int ctlr, void *buff, size_t size,
+- unsigned int use_unit_num, unsigned int log_unit, __u8 page_code,
+- unsigned char *scsi3addr, int cmd_type);
++ unsigned int use_unit_num, unsigned int log_unit,
++ __u8 page_code, unsigned char *scsi3addr, int cmd_type);
+ static int sendcmd_withirq(__u8 cmd, int ctlr, void *buff, size_t size,
+- unsigned int use_unit_num, unsigned int log_unit, __u8 page_code,
+- int cmd_type);
++ unsigned int use_unit_num, unsigned int log_unit,
++ __u8 page_code, int cmd_type);
+
+-static void fail_all_cmds(unsigned long ctlr);
++static void cciss_shutdown (struct pci_dev *pdev);
++static void __devexit cciss_remove_one(struct pci_dev *pdev);
+
++static void fail_all_cmds(unsigned long ctlr);
++static void print_cmd(CommandList_struct *);
+ #ifdef CONFIG_PROC_FS
+-static int cciss_proc_get_info(char *buffer, char **start, off_t offset,
+- int length, int *eof, void *data);
+ static void cciss_procinit(int i);
+ #else
+-static void cciss_procinit(int i) {}
++static void cciss_procinit(int i)
++{
++}
+ #endif /* CONFIG_PROC_FS */
+
+ #ifdef CONFIG_COMPAT
+@@ -222,7 +238,8 @@
+ CommandList_struct *c)
+ {
+ if (c && c->next != c) {
+- if (*Qptr == c) *Qptr = c->next;
++ if (*Qptr == c)
++ *Qptr = c->next;
+ c->prev->next = c->next;
+ c->next->prev = c->prev;
+ } else {
+@@ -231,46 +248,492 @@
+ return c;
+ }
+
+-#include "cciss_scsi.c" /* For SCSI tape support */
++static inline int find_drv_index(int ctlr, drive_info_struct *drv){
++ int i;
++ for (i=0; i < CISS_MAX_LUN; i++) {
++ if (hba[ctlr]->drv[i].LunID == drv->LunID)
++ return i;
++ }
++ return i;
++}
+
+-#ifdef CONFIG_PROC_FS
++#include "cciss_scsi.c" /* For SCSI tape support */
+
+-/*
+- * Report information about this controller.
+- */
+ #define ENG_GIG 1000000000
+ #define ENG_GIG_FACTOR (ENG_GIG/512)
+ #define RAID_UNKNOWN 6
++#define ENGAGE_SCSI "engage scsi"
++#define RESCAN_VOLUMES "rescan volumes"
++
+ static const char *raid_label[] = {"0","4","1(1+0)","5","5+1","ADG",
+ "UNKNOWN"};
+
+-static struct proc_dir_entry *proc_cciss;
++static spinlock_t sysfs_lock = SPIN_LOCK_UNLOCKED;
++
++static void cciss_sysfs_stat_inquiry(int ctlr, int logvol,
++ int withirq, drive_info_struct *drv)
++{
++ int return_code;
++ InquiryData_struct *inq_buff;
++
++ /* If there are no heads then this is the controller disk and
++ * not a valid logical drive so don't query it.
++ */
++ if (!drv->heads)
++ return;
++
++ inq_buff = kzalloc(sizeof(InquiryData_struct), GFP_KERNEL);
++ if (!inq_buff) {
++ printk(KERN_ERR "cciss: out of memory\n");
++ goto err;
++ }
++
++ if (withirq)
++ return_code = sendcmd_withirq(CISS_INQUIRY, ctlr,
++ inq_buff, sizeof(*inq_buff), 1, logvol ,0, TYPE_CMD);
++ else
++ return_code = sendcmd(CISS_INQUIRY, ctlr, inq_buff,
++ sizeof(*inq_buff), 1, logvol , 0, NULL, TYPE_CMD);
++ if (return_code == IO_OK) {
++ memcpy(drv->vendor, &inq_buff->data_byte[8], 8);
++ drv->vendor[8]='\0';
++ memcpy(drv->model, &inq_buff->data_byte[16], 16);
++ drv->model[16] = '\0';
++ memcpy(drv->rev, &inq_buff->data_byte[32], 4);
++ drv->rev[4] = '\0';
++ } else { /* Get geometry failed */
++ printk(KERN_WARNING "cciss: inquiry for VPD page 0 failed\n");
++ }
++
++ if (withirq)
++ return_code = sendcmd_withirq(CISS_INQUIRY, ctlr,
++ inq_buff, sizeof(*inq_buff), 1, logvol ,0x83, TYPE_CMD);
++ else
++ return_code = sendcmd(CISS_INQUIRY, ctlr, inq_buff,
++ sizeof(*inq_buff), 1, logvol , 0x83, NULL, TYPE_CMD);
++
++ if (return_code == IO_OK) {
++ memcpy(drv->uid, &inq_buff->data_byte[8], 16);
++ } else { /* Get geometry failed */
++ printk(KERN_WARNING "cciss: id logical drive failed\n");
++ }
++
++ kfree(inq_buff);
++err:
++ drv->vendor[8] = '\0';
++ drv->model[16] = '\0';
++ drv->rev[4] = '\0';
++
++}
+
+-static int cciss_proc_get_info(char *buffer, char **start, off_t offset,
+- int length, int *eof, void *data)
++static ssize_t cciss_show_raid_level(struct device *dev,
++ struct device_attribute *attr, char *buf)
+ {
+- off_t pos = 0;
+- off_t len = 0;
+- int size, i, ctlr;
+- ctlr_info_t *h = (ctlr_info_t*)data;
+- drive_info_struct *drv;
++ struct drv_dynamic *d;
++ drive_info_struct *drv;
++ ctlr_info_t *h;
+ unsigned long flags;
+- sector_t vol_sz, vol_sz_frac;
++ int raid;
+
+- ctlr = h->ctlr;
++ d = container_of(dev, struct drv_dynamic, dev);
++ spin_lock(&sysfs_lock);
++ if (!d->disk) {
++ spin_unlock(&sysfs_lock);
++ return -ENOENT;
++ }
+
+- /* prevent displaying bogus info during configuration
+- * or deconfiguration of a logical volume
+- */
+- spin_lock_irqsave(CCISS_LOCK(ctlr), flags);
++ h = get_host(d->disk);
++
++ spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags);
+ if (h->busy_configuring) {
+- spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
+- return -EBUSY;
++ spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
++ spin_unlock(&sysfs_lock);
++ return snprintf(buf, 30, "Device busy configuring\n");
+ }
+- h->busy_configuring = 1;
+- spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
+
+- size = sprintf(buffer, "%s: HP %s Controller\n"
++ drv = d->disk->private_data;
++ if ((drv->raid_level < 0) || (drv->raid_level) > 5)
++ raid = RAID_UNKNOWN;
++ else
++ raid = drv->raid_level;
++
++ spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
++ spin_unlock(&sysfs_lock);
++ return snprintf(buf, 20, "RAID %s\n", raid_label[raid]);
++}
++
++static ssize_t cciss_show_disk_size(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ struct drv_dynamic *d;
++ drive_info_struct *drv;
++ ctlr_info_t *h;
++ unsigned long flags;
++ sector_t vol_sz, vol_sz_frac;
++
++ d = container_of(dev, struct drv_dynamic, dev);
++ spin_lock(&sysfs_lock);
++ if (!d->disk) {
++ spin_unlock(&sysfs_lock);
++ return -ENOENT;
++ }
++ h = get_host(d->disk);
++
++ spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags);
++ if (h->busy_configuring) {
++ spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
++ spin_unlock(&sysfs_lock);
++ return snprintf(buf, 30, "Device busy configuring\n");
++ }
++
++ drv = d->disk->private_data;
++ vol_sz = drv->nr_blocks;
++ vol_sz_frac = sector_div(vol_sz, ENG_GIG_FACTOR);
++ vol_sz_frac *= 100;
++ sector_div(vol_sz_frac, ENG_GIG_FACTOR);
++
++ spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
++ spin_unlock(&sysfs_lock);
++ return snprintf(buf, 30, "%4u.%02uGB\n", (int)vol_sz, (int)vol_sz_frac);
++}
++
++static ssize_t cciss_show_usage_count(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ struct drv_dynamic *d;
++ drive_info_struct *drv;
++ int count;
++
++ d = container_of(dev, struct drv_dynamic, dev);
++ spin_lock(&sysfs_lock);
++ if (!d->disk) {
++ spin_unlock(&sysfs_lock);
++ return -ENOENT;
++ }
++ drv = d->disk->private_data;
++ count = drv->usage_count;
++ spin_unlock(&sysfs_lock);
++ return snprintf(buf, 20, "%d\n", count);
++}
++
++static ssize_t cciss_show_vendor(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ struct drv_dynamic *d;
++ drive_info_struct *drv;
++ ctlr_info_t *h;
++ unsigned long flags;
++ int drv_index;
++
++ d = container_of(dev, struct drv_dynamic, dev);
++ spin_lock(&sysfs_lock);
++ if (!d->disk) {
++ spin_unlock(&sysfs_lock);
++ return -ENOENT;
++ }
++
++ h = get_host(d->disk);
++
++ spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags);
++ if (h->busy_configuring) {
++ spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
++ spin_unlock(&sysfs_lock);
++ return -EBUSY;
++ }
++
++ drv = d->disk->private_data;
++
++ if (!drv->heads) {
++ spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
++ spin_unlock(&sysfs_lock);
++ return -ENOTTY;
++ }
++
++ drv_index = find_drv_index(h->ctlr, drv);
++ if (drv_index != CISS_MAX_LUN) {
++ spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
++ spin_unlock(&sysfs_lock);
++ return snprintf(buf, 20, "%s\n", (char *)drv->vendor);
++ }
++
++ printk(KERN_ERR "cciss: logical drive not found\n");
++ spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
++ spin_unlock(&sysfs_lock);
++ return -ENOTTY;
++}
++
++static ssize_t cciss_show_model(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ struct drv_dynamic *d;
++ drive_info_struct *drv;
++ ctlr_info_t *h;
++ unsigned long flags;
++ int drv_index;
++
++ d = container_of(dev, struct drv_dynamic, dev);
++ spin_lock(&sysfs_lock);
++ if (!d->disk) {
++ spin_unlock(&sysfs_lock);
++ return -ENOENT;
++ }
++
++ h = get_host(d->disk);
++
++ spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags);
<<Diff was trimmed, longer than 597 lines>>
More information about the pld-cvs-commit
mailing list