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