summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'openvz-sources/022.056/5118_linux-2.6.8.1-cciss-2.8.6.patch')
-rw-r--r--openvz-sources/022.056/5118_linux-2.6.8.1-cciss-2.8.6.patch680
1 files changed, 0 insertions, 680 deletions
diff --git a/openvz-sources/022.056/5118_linux-2.6.8.1-cciss-2.8.6.patch b/openvz-sources/022.056/5118_linux-2.6.8.1-cciss-2.8.6.patch
deleted file mode 100644
index f0bdd03..0000000
--- a/openvz-sources/022.056/5118_linux-2.6.8.1-cciss-2.8.6.patch
+++ /dev/null
@@ -1,680 +0,0 @@
---- linux-2.6.8.1-t047-cciss/drivers/block/cciss.c 2005-11-22 18:01:33.205086568 +0300
-+++ rhel4u2/drivers/block/cciss.c 2005-10-19 11:47:13.000000000 +0400
-@@ -1,6 +1,6 @@
- /*
- * Disk Array driver for HP SA 5xxx and 6xxx Controllers
-- * Copyright 2000, 2002 Hewlett-Packard Development Company, L.P.
-+ * Copyright 2000, 2005 Hewlett-Packard Development Company, L.P.
- *
- * 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
-@@ -46,14 +46,15 @@
- #include <linux/completion.h>
-
- #define CCISS_DRIVER_VERSION(maj,min,submin) ((maj<<16)|(min<<8)|(submin))
--#define DRIVER_NAME "Compaq CISS Driver (v 2.6.2)"
--#define DRIVER_VERSION CCISS_DRIVER_VERSION(2,6,2)
-+#define DRIVER_NAME "HP CISS Driver (v 2.6.8)"
-+#define DRIVER_VERSION CCISS_DRIVER_VERSION(2,6,8)
-
- /* Embedded module documentation macros - see modules.h */
- MODULE_AUTHOR("Hewlett-Packard Company");
--MODULE_DESCRIPTION("Driver for HP Controller SA5xxx SA6xxx version 2.6.2");
-+MODULE_DESCRIPTION("Driver for HP Controller SA5xxx SA6xxx version 2.6.8");
-+MODULE_VERSION("2.6.8");
- MODULE_SUPPORTED_DEVICE("HP SA5i SA5i+ SA532 SA5300 SA5312 SA641 SA642 SA6400"
-- " SA6i");
-+ " SA6i P600 P800 P400 E200 E200i");
- MODULE_LICENSE("GPL");
-
- #include "cciss_cmd.h"
-@@ -80,10 +81,24 @@ const struct pci_device_id cciss_pci_dev
- 0x0E11, 0x409D, 0, 0, 0},
- { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_CISSC,
- 0x0E11, 0x4091, 0, 0, 0},
-- { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_CISSC,
-- 0x0E11, 0x409E, 0, 0, 0},
-- { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_CISSC,
-+ { 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},
- {0,}
- };
- MODULE_DEVICE_TABLE(pci, cciss_pci_device_id);
-@@ -104,8 +119,15 @@ static struct board_type products[] = {
- { 0x409C0E11, "Smart Array 6400", &SA5_access},
- { 0x409D0E11, "Smart Array 6400 EM", &SA5_access},
- { 0x40910E11, "Smart Array 6i", &SA5_access},
-- { 0x409E0E11, "Smart Array 6422", &SA5_access},
-- { 0x3211103C, "Smart Array V100", &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},
- };
-
- /* How long to wait (in millesconds) for board to go into simple mode */
-@@ -115,9 +137,13 @@ static struct board_type products[] = {
- /*define how many times we will try a command because of bus resets */
- #define MAX_CMD_RETRIES 3
-
--#define READ_AHEAD 256
-+#define READ_AHEAD 1024
- #define NR_CMDS 384 /* #commands that can be outstanding */
--#define MAX_CTLR 8
-+#define MAX_CTLR 32
-+
-+/* Originally cciss driver only supports 8 major numbers */
-+#define MAX_CTLR_ORIG 8
-+
-
- #define CCISS_DMA_MASK 0xFFFFFFFF /* 32 bit DMA */
-
-@@ -192,10 +218,10 @@ static inline CommandList_struct *remove
- /*
- * Report information about this controller.
- */
--#define ENG_GIG 1048576000
-+#define ENG_GIG 1000000000
- #define ENG_GIG_FACTOR (ENG_GIG/512)
- #define RAID_UNKNOWN 6
--static const char *raid_label[] = {"0","4","1(0+1)","5","5+1","ADG",
-+static const char *raid_label[] = {"0","4","1(1+0)","5","5+1","ADG",
- "UNKNOWN"};
-
- static struct proc_dir_entry *proc_cciss;
-@@ -209,7 +235,7 @@ static int cciss_proc_get_info(char *buf
- ctlr_info_t *h = (ctlr_info_t*)data;
- drive_info_struct *drv;
- unsigned long flags;
-- unsigned int vol_sz, vol_sz_frac;
-+ sector_t vol_sz, vol_sz_frac;
-
- ctlr = h->ctlr;
-
-@@ -246,32 +272,21 @@ static int cciss_proc_get_info(char *buf
- pos += size; len += size;
- cciss_proc_tape_report(ctlr, buffer, &pos, &len);
- for(i=0; i<=h->highest_lun; i++) {
-- sector_t tmp;
-
- drv = &h->drv[i];
- if (drv->block_size == 0)
- continue;
-- vol_sz = drv->nr_blocks;
-- sector_div(vol_sz, ENG_GIG_FACTOR);
--
-- /*
-- * Awkwardly do this:
-- * vol_sz_frac =
-- * (drv->nr_blocks%ENG_GIG_FACTOR)*100/ENG_GIG_FACTOR;
-- */
-- tmp = drv->nr_blocks;
-- vol_sz_frac = sector_div(tmp, ENG_GIG_FACTOR);
--
-- /* Now, vol_sz_frac = (drv->nr_blocks%ENG_GIG_FACTOR) */
-
-+ 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);
-
- if (drv->raid_level > 5)
- drv->raid_level = RAID_UNKNOWN;
- size = sprintf(buffer+len, "cciss/c%dd%d:"
-- "\t%4d.%02dGB\tRAID %s\n",
-- ctlr, i, vol_sz,vol_sz_frac,
-+ "\t%4u.%02uGB\tRAID %s\n",
-+ ctlr, i, (int)vol_sz, (int)vol_sz_frac,
- raid_label[drv->raid_level]);
- pos += size; len += size;
- }
-@@ -449,13 +464,22 @@ static int cciss_open(struct inode *inod
-
- /*
- * Root is allowed to open raw volume zero even if it's not configured
-- * so array config can still work. I don't think I really like this,
-+ * so array config can still work. Root is also allowed to open any
-+ * volume that has a LUN ID, so it can issue IOCTL to reread the
-+ * disk information. I don't think I really like this
- * but I'm already using way to many device nodes to claim another one
- * for "raw controller".
- */
- if (drv->nr_blocks == 0) {
-- if (iminor(inode) != 0)
-+ if (iminor(inode) != 0) { /* not node 0? */
-+ /* if not node 0 make sure it is a partition = 0 */
-+ if (iminor(inode) & 0x0f) {
- return -ENXIO;
-+ /* if it is, make sure we have a LUN ID */
-+ } else if (drv->LunID == 0) {
-+ return -ENXIO;
-+ }
-+ }
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- }
-@@ -578,7 +602,7 @@ int cciss_ioctl32_passthru(unsigned int
- err = sys_ioctl(fd, CCISS_PASSTHRU, (unsigned long) p);
- if (err)
- return err;
-- err |= copy_in_user(&arg32->error_info, &p->error_info, sizeof(&arg32->error_info));
-+ err |= copy_in_user(&arg32->error_info, &p->error_info, sizeof(arg32->error_info));
- if (err)
- return -EFAULT;
- return err;
-@@ -610,7 +634,7 @@ int cciss_ioctl32_big_passthru(unsigned
- err = sys_ioctl(fd, CCISS_BIG_PASSTHRU, (unsigned long) p);
- if (err)
- return err;
-- err |= copy_in_user(&arg32->error_info, &p->error_info, sizeof(&arg32->error_info));
-+ err |= copy_in_user(&arg32->error_info, &p->error_info, sizeof(arg32->error_info));
- if (err)
- return -EFAULT;
- return err;
-@@ -657,6 +681,7 @@ static int cciss_ioctl(struct inode *ino
- cciss_pci_info_struct pciinfo;
-
- if (!arg) return -EINVAL;
-+ pciinfo.domain = pci_domain_nr(host->pdev->bus);
- pciinfo.bus = host->pdev->bus->number;
- pciinfo.dev_fn = host->pdev->devfn;
- pciinfo.board_id = host->board_id;
-@@ -810,7 +835,7 @@ static int cciss_ioctl(struct inode *ino
- luninfo.num_opens = drv->usage_count;
- luninfo.num_parts = 0;
- /* count partitions 1 to 15 with sizes > 0 */
-- for(i=1; i <MAX_PART; i++) {
-+ for (i = 0; i < MAX_PART - 1; i++) {
- if (!disk->part[i])
- continue;
- if (disk->part[i]->nr_sects != 0)
-@@ -866,6 +891,8 @@ static int cciss_ioctl(struct inode *ino
- kfree(buff);
- return -EFAULT;
- }
-+ } else {
-+ memset(buff, 0, iocommand.buf_size);
- }
- if ((c = cmd_alloc(host , 0)) == NULL)
- {
-@@ -1012,6 +1039,8 @@ static int cciss_ioctl(struct inode *ino
- copy_from_user(buff[sg_used], data_ptr, sz)) {
- status = -ENOMEM;
- goto cleanup1;
-+ } else {
-+ memset(buff[sg_used], 0, sz);
- }
- left -= sz;
- data_ptr += sz;
-@@ -1097,18 +1126,11 @@ cleanup1:
- return(status);
- }
- default:
-- return -EBADRQC;
-+ return -ENOTTY;
- }
-
- }
-
--static int cciss_revalidate(struct gendisk *disk)
--{
-- drive_info_struct *drv = disk->private_data;
-- set_capacity(disk, drv->nr_blocks);
-- return 0;
--}
--
- /*
- * revalidate_allvol is for online array config utilities. After a
- * utility reconfigures the drives in the array, it can use this function
-@@ -1160,7 +1182,9 @@ static int revalidate_allvol(ctlr_info_t
- for (i = 0; i < NWD; i++) {
- struct gendisk *disk = host->gendisk[i];
- drive_info_struct *drv = &(host->drv[i]);
-- if (!drv->nr_blocks)
-+ /* we must register the controller even if no disks exist */
-+ /* this is for the online array utilities */
-+ if (!drv->heads && i)
- continue;
- blk_queue_hardsect_size(host->queue, drv->block_size);
- set_capacity(disk, drv->nr_blocks);
-@@ -1477,21 +1501,22 @@ static void cciss_geometry_inquiry(int c
- drv->sectors = 32; // Sectors per track
- drv->cylinders = total_size / 255 / 32;
- } else {
-+ unsigned int t;
-+
- drv->block_size = block_size;
- drv->nr_blocks = total_size;
- drv->heads = inq_buff->data_byte[6];
- drv->sectors = inq_buff->data_byte[7];
- drv->cylinders = (inq_buff->data_byte[4] & 0xff) << 8;
- drv->cylinders += inq_buff->data_byte[5];
-+ drv->raid_level = inq_buff->data_byte[8];
-+ t = drv->heads * drv->sectors;
-+ if (t > 1) {
-+ drv->cylinders = total_size/t;
-+ }
- }
- } else { /* Get geometry failed */
-- printk(KERN_WARNING "cciss: reading geometry failed, "
-- "continuing with default geometry\n");
-- drv->block_size = block_size;
-- drv->nr_blocks = total_size;
-- drv->heads = 255;
-- drv->sectors = 32; // Sectors per track
-- drv->cylinders = total_size / 255 / 32;
-+ printk(KERN_WARNING "cciss: reading geometry failed\n");
- }
- printk(KERN_INFO " heads= %d, sectors= %d, cylinders= %d\n\n",
- drv->heads, drv->sectors, drv->cylinders);
-@@ -1509,8 +1534,8 @@ cciss_read_capacity(int ctlr, int logvol
- return_code = sendcmd(CCISS_READ_CAPACITY,
- ctlr, buf, sizeof(*buf), 1, logvol, 0, NULL, TYPE_CMD);
- if (return_code == IO_OK) {
-- *total_size = be32_to_cpu(*((__u32 *) &buf->total_size[0]))+1;
-- *block_size = be32_to_cpu(*((__u32 *) &buf->block_size[0]));
-+ *total_size = be32_to_cpu(*((__be32 *) &buf->total_size[0]))+1;
-+ *block_size = be32_to_cpu(*((__be32 *) &buf->block_size[0]));
- } else { /* read capacity command failed */
- printk(KERN_WARNING "cciss: read capacity failed\n");
- *total_size = 0;
-@@ -1520,6 +1545,7 @@ cciss_read_capacity(int ctlr, int logvol
- *total_size, *block_size);
- return;
- }
-+
- static int register_new_disk(ctlr_info_t *h)
- {
- struct gendisk *disk;
-@@ -1663,7 +1689,9 @@ static int register_new_disk(ctlr_info_t
- /* setup partitions per disk */
- disk = h->gendisk[logvol];
- set_capacity(disk, h->drv[logvol].nr_blocks);
-- add_disk(disk);
-+ /* if it's the controller it's already added */
-+ if(logvol)
-+ add_disk(disk);
- freeret:
- kfree(ld_buff);
- kfree(size_buff);
-@@ -1675,6 +1703,53 @@ free_err:
- logvol = -1;
- goto freeret;
- }
-+
-+static int cciss_revalidate(struct gendisk *disk)
-+{
-+ ctlr_info_t *h = get_host(disk);
-+ drive_info_struct *drv = get_drv(disk);
-+ int logvol;
-+ int FOUND=0;
-+ unsigned int block_size;
-+ unsigned int total_size;
-+ ReadCapdata_struct *size_buff = NULL;
-+ InquiryData_struct *inq_buff = NULL;
-+
-+ for(logvol=0; logvol < CISS_MAX_LUN; logvol++)
-+ {
-+ if(h->drv[logvol].LunID == drv->LunID) {
-+ FOUND=1;
-+ break;
-+ }
-+ }
-+
-+ if (!FOUND) return 1;
-+
-+ size_buff = kmalloc(sizeof( ReadCapdata_struct), GFP_KERNEL);
-+ if (size_buff == NULL)
-+ {
-+ printk(KERN_WARNING "cciss: out of memory\n");
-+ return 1;
-+ }
-+ inq_buff = kmalloc(sizeof( InquiryData_struct), GFP_KERNEL);
-+ if (inq_buff == NULL)
-+ {
-+ printk(KERN_WARNING "cciss: out of memory\n");
-+ kfree(size_buff);
-+ return 1;
-+ }
-+
-+ cciss_read_capacity(h->ctlr, logvol, size_buff, 1, &total_size, &block_size);
-+ cciss_geometry_inquiry(h->ctlr, logvol, 1, total_size, block_size, inq_buff, drv);
-+
-+ blk_queue_hardsect_size(h->queue, drv->block_size);
-+ set_capacity(disk, drv->nr_blocks);
-+
-+ kfree(size_buff);
-+ kfree(inq_buff);
-+ return 0;
-+}
-+
- /*
- * Wait polling for a command to complete.
- * The memory mapped FIFO is polled for the completion.
-@@ -1844,13 +1919,13 @@ cleanup1:
- /*
- * Map (physical) PCI mem into (virtual) kernel space
- */
--static ulong remap_pci_mem(ulong base, ulong size)
-+static void __iomem *remap_pci_mem(ulong base, ulong size)
- {
- ulong page_base = ((ulong) base) & PAGE_MASK;
- ulong page_offs = ((ulong) base) - page_base;
-- ulong page_remapped = (ulong) ioremap(page_base, page_offs+size);
-+ void __iomem *page_remapped = ioremap(page_base, page_offs+size);
-
-- return (ulong) (page_remapped ? (page_remapped + page_offs) : 0UL);
-+ return page_remapped ? (page_remapped + page_offs) : NULL;
- }
-
- /*
-@@ -2061,6 +2136,9 @@ static void do_cciss_request(request_que
- drive_info_struct *drv;
- int i, dir;
-
-+ /* We call start_io here in case there is a command waiting on the
-+ * queue that has not been sent.
-+ */
- if (blk_queue_plugged(q))
- goto startio;
-
-@@ -2149,6 +2227,9 @@ queue:
- full:
- blk_stop_queue(q);
- startio:
-+ /* We will already have the driver lock here so not need
-+ * to lock it.
-+ */
- start_io(h);
- }
-
-@@ -2158,7 +2239,8 @@ static irqreturn_t do_cciss_intr(int irq
- CommandList_struct *c;
- unsigned long flags;
- __u32 a, a1;
--
-+ int j;
-+ int start_queue = h->next_to_run;
-
- /* Is this interrupt for us? */
- if (( h->access.intr_pending(h) == 0) || (h->interrupts_enabled == 0))
-@@ -2205,13 +2287,50 @@ static irqreturn_t do_cciss_intr(int irq
- }
- }
-
-- /*
-- * See if we can queue up some more IO
-+ /* check to see if we have maxed out the number of commands that can
-+ * be placed on the queue. If so then exit. We do this check here
-+ * in case the interrupt we serviced was from an ioctl and did not
-+ * free any new commands.
- */
-- blk_start_queue(h->queue);
-+ if ((find_first_zero_bit(h->cmd_pool_bits, NR_CMDS)) == NR_CMDS)
-+ goto cleanup;
-+
-+ /* We have room on the queue for more commands. Now we need to queue
-+ * them up. We will also keep track of the next queue to run so
-+ * that every queue gets a chance to be started first.
-+ */
-+ for (j=0; j < NWD; j++){
-+ int curr_queue = (start_queue + j) % NWD;
-+ /* make sure the disk has been added and the drive is real
-+ * because this can be called from the middle of init_one.
-+ */
-+ if(!(h->gendisk[curr_queue]->queue) ||
-+ !(h->drv[curr_queue].heads))
-+ continue;
-+ blk_start_queue(h->gendisk[curr_queue]->queue);
-+
-+ /* check to see if we have maxed out the number of commands
-+ * that can be placed on the queue.
-+ */
-+ if ((find_first_zero_bit(h->cmd_pool_bits, NR_CMDS)) == NR_CMDS)
-+ {
-+ if (curr_queue == start_queue){
-+ h->next_to_run = (start_queue + 1) % NWD;
-+ goto cleanup;
-+ } else {
-+ h->next_to_run = curr_queue;
-+ goto cleanup;
-+ }
-+ } else {
-+ curr_queue = (curr_queue + 1) % NWD;
-+ }
-+ }
-+
-+cleanup:
- spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
- return IRQ_HANDLED;
- }
-+
- /*
- * We cannot read the structure directly, for portablity we must use
- * the io functions.
-@@ -2300,7 +2419,6 @@ static int find_PCI_BAR_index(struct pci
- static int cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev)
- {
- ushort subsystem_vendor_id, subsystem_device_id, command;
-- unchar irq = pdev->irq;
- __u32 board_id, scratchpad = 0;
- __u64 cfg_offset;
- __u32 cfg_base_addr;
-@@ -2359,11 +2477,11 @@ static int cciss_pci_init(ctlr_info_t *c
-
- #ifdef CCISS_DEBUG
- printk("command = %x\n", command);
-- printk("irq = %x\n", irq);
-+ printk("irq = %x\n", pdev->irq);
- printk("board_id = %x\n", board_id);
- #endif /* CCISS_DEBUG */
-
-- c->intr = irq;
-+ c->intr = pdev->irq;
-
- /*
- * Memory base addr is first addr , the second points to the config
-@@ -2411,9 +2529,9 @@ static int cciss_pci_init(ctlr_info_t *c
- #ifdef CCISS_DEBUG
- printk("cfg offset = %x\n", cfg_offset);
- #endif /* CCISS_DEBUG */
-- c->cfgtable = (CfgTable_struct *)
-- remap_pci_mem(pci_resource_start(pdev, cfg_base_addr_index)
-- + cfg_offset, sizeof(CfgTable_struct));
-+ c->cfgtable = remap_pci_mem(pci_resource_start(pdev,
-+ cfg_base_addr_index) + cfg_offset,
-+ sizeof(CfgTable_struct));
- c->board_id = board_id;
-
- #ifdef CCISS_DEBUG
-@@ -2626,7 +2744,7 @@ static int alloc_cciss_hba(void)
- }
- }
- printk(KERN_WARNING "cciss: This driver supports a maximum"
-- " of 8 controllers.\n");
-+ " of %d controllers.\n", MAX_CTLR);
- goto out;
- Enomem:
- printk(KERN_ERR "cciss: out of memory.\n");
-@@ -2658,13 +2776,14 @@ static int __devinit cciss_init_one(stru
- request_queue_t *q;
- int i;
- int j;
-+ int rc;
-
- printk(KERN_DEBUG "cciss: Device 0x%x has been found at"
- " bus %d dev %d func %d\n",
- pdev->device, pdev->bus->number, PCI_SLOT(pdev->devfn),
- PCI_FUNC(pdev->devfn));
- i = alloc_cciss_hba();
-- if( i < 0 )
-+ if(i < 0)
- return (-1);
- if (cciss_pci_init(hba[i], pdev) != 0)
- goto clean1;
-@@ -2683,11 +2802,24 @@ static int __devinit cciss_init_one(stru
- goto clean1;
- }
-
-- if (register_blkdev(COMPAQ_CISS_MAJOR+i, hba[i]->devname)) {
-- printk(KERN_ERR "cciss: Unable to register device %s\n",
-- hba[i]->devname);
-+ /*
-+ * register with the major number, or get a dynamic major number
-+ * by passing 0 as argument. This is done for greater than
-+ * 8 controller support.
-+ */
-+ if (i < MAX_CTLR_ORIG)
-+ hba[i]->major = MAJOR_NR + i;
-+ rc = register_blkdev(hba[i]->major, hba[i]->devname);
-+ if(rc == -EBUSY || rc == -EINVAL) {
-+ printk(KERN_ERR
-+ "cciss: Unable to get major number %d for %s "
-+ "on hba %d\n", hba[i]->major, hba[i]->devname, i);
- goto clean1;
- }
-+ else {
-+ if (i >= MAX_CTLR_ORIG)
-+ hba[i]->major = rc;
-+ }
-
- /* make sure the board interrupts are off */
- hba[i]->access.set_intr_mask(hba[i], CCISS_INTR_OFF);
-@@ -2758,12 +2890,14 @@ static int __devinit cciss_init_one(stru
-
- sprintf(disk->disk_name, "cciss/c%dd%d", i, j);
- sprintf(disk->devfs_name, "cciss/host%d/target%d", i, j);
-- disk->major = COMPAQ_CISS_MAJOR + i;
-+ disk->major = hba[i]->major;
- disk->first_minor = j << NWD_SHIFT;
- disk->fops = &cciss_fops;
- disk->queue = hba[i]->queue;
- disk->private_data = drv;
-- if( !(drv->nr_blocks))
-+ /* we must register the controller even if no disks exist */
-+ /* this is for the online array utilities */
-+ if(!drv->heads && j)
- continue;
- blk_queue_hardsect_size(hba[i]->queue, drv->block_size);
- set_capacity(disk, drv->nr_blocks);
-@@ -2785,7 +2919,7 @@ clean4:
- hba[i]->errinfo_pool_dhandle);
- free_irq(hba[i]->intr, hba[i]);
- clean2:
-- unregister_blkdev(COMPAQ_CISS_MAJOR+i, hba[i]->devname);
-+ unregister_blkdev(hba[i]->major, hba[i]->devname);
- clean1:
- release_io_mem(hba[i]);
- free_hba(i);
-@@ -2825,9 +2959,9 @@ static void __devexit cciss_remove_one (
- }
- free_irq(hba[i]->intr, hba[i]);
- pci_set_drvdata(pdev, NULL);
-- iounmap((void*)hba[i]->vaddr);
-+ iounmap(hba[i]->vaddr);
- cciss_unregister_scsi(i); /* unhook from SCSI subsystem */
-- unregister_blkdev(COMPAQ_CISS_MAJOR+i, hba[i]->devname);
-+ unregister_blkdev(hba[i]->major, hba[i]->devname);
- remove_proc_entry(hba[i]->devname, proc_cciss);
-
- /* remove it from the disk list */
---- linux-2.6.8.1-t047-cciss/drivers/block/cciss.h 2005-11-22 18:01:33.205086568 +0300
-+++ rhel4u2/drivers/block/cciss.h 2005-10-19 11:47:13.000000000 +0400
-@@ -13,6 +13,8 @@
- #define IO_OK 0
- #define IO_ERROR 1
-
-+#define MAJOR_NR COMPAQ_CISS_MAJOR
-+
- struct ctlr_info;
- typedef struct ctlr_info ctlr_info_t;
-
-@@ -43,13 +45,14 @@ struct ctlr_info
- char firm_ver[4]; // Firmware version
- struct pci_dev *pdev;
- __u32 board_id;
-- unsigned long vaddr;
-+ void __iomem *vaddr;
- unsigned long paddr;
- unsigned long io_mem_addr;
- unsigned long io_mem_length;
-- CfgTable_struct *cfgtable;
-- int intr;
-+ CfgTable_struct __iomem *cfgtable;
-+ unsigned int intr;
- int interrupts_enabled;
-+ int major;
- int max_commands;
- int commands_outstanding;
- int max_outstanding; /* Debug */
-@@ -81,6 +84,11 @@ struct ctlr_info
- int nr_frees;
- int busy_configuring;
-
-+ /* This element holds the zero based queue number of the last
-+ * queue to be started. It is used for fairness.
-+ */
-+ int next_to_run;
-+
- // Disk structures we need to pass back
- struct gendisk *gendisk[NWD];
- #ifdef CONFIG_CISS_SCSI_TAPE
---- linux-2.6.8.1-t047-cciss/drivers/block/cciss_scsi.c 2005-11-22 18:01:33.206086416 +0300
-+++ rhel4u2/drivers/block/cciss_scsi.c 2005-10-19 11:47:13.000000000 +0400
-@@ -696,6 +696,7 @@ static int
- cciss_scsi_detect(int ctlr)
- {
- struct Scsi_Host *sh;
-+ int error;
-
- sh = scsi_host_alloc(&cciss_driver_template, sizeof(struct ctlr_info *));
- if (sh == NULL)
-@@ -711,10 +712,15 @@ cciss_scsi_detect(int ctlr)
- sh->hostdata[0] = (unsigned long) hba[ctlr];
- sh->irq = hba[ctlr]->intr;
- sh->unique_id = sh->irq;
-- scsi_add_host(sh, &hba[ctlr]->pdev->dev); /* XXX handle failure */
-+ error = scsi_add_host(sh, &hba[ctlr]->pdev->dev);
-+ if (error)
-+ goto fail_host_put;
- scsi_scan_host(sh);
--
- return 1;
-+
-+fail_host_put:
-+ scsi_host_put(sh);
-+ return 0;
- }
-
- static void __exit cleanup_cciss_module(void);
---- linux-2.6.8.1-t047-cciss/include/linux/cciss_ioctl.h 2004-08-14 14:55:20.000000000 +0400
-+++ rhel4u2/include/linux/cciss_ioctl.h 2005-10-19 11:47:13.000000000 +0400
-@@ -11,6 +11,7 @@ typedef struct _cciss_pci_info_struct
- {
- unsigned char bus;
- unsigned char dev_fn;
-+ unsigned short domain;
- __u32 board_id;
- } cciss_pci_info_struct;
-