2003-02-12 18:59:42

by Cameron, Steve

[permalink] [raw]
Subject: [PATCH] 2.5.60 make cciss driver compile

(patch 1 of 11)
Makes the cciss driver compile in 2.5.60 (from [email protected])
-- steve

--- linux-2.5.60/drivers/block/cciss_scsi.c~2_5_60_cciss_scsi_fix 2003-02-12 10:12:31.000000000 +0600
+++ linux-2.5.60-scameron/drivers/block/cciss_scsi.c 2003-02-12 10:12:31.000000000 +0600
@@ -1379,11 +1379,11 @@ cciss_scsi_queue_command (Scsi_Cmnd *cmd

// Get the ptr to our adapter structure (hba[i]) out of cmd->host.
// We violate cmd->host privacy here. (Is there another way?)
- c = (ctlr_info_t **) &cmd->host->hostdata[0];
+ c = (ctlr_info_t **) &cmd->device->host->hostdata[0];
ctlr = (*c)->ctlr;

- rc = lookup_scsi3addr(ctlr, cmd->channel, cmd->target, cmd->lun,
- scsi3addr);
+ rc = lookup_scsi3addr(ctlr, cmd->device->channel, cmd->device->id,
+ cmd->device->lun, scsi3addr);
if (rc != 0) {
/* the scsi nexus does not match any that we presented... */
/* pretend to mid layer that we got selection timeout */

_


2003-02-12 19:02:38

by Cameron, Steve

[permalink] [raw]
Subject: Re: [PATCH] 2.5.60 make cciss driver compile


Allow cciss driver attached disks other than the first to be accessed.
(patch 3 of 11)
-- steve

--- linux-2.5.60/drivers/block/cciss.c~nth_vol_partition 2003-02-12 10:12:44.000000000 +0600
+++ linux-2.5.60-scameron/drivers/block/cciss.c 2003-02-12 10:12:44.000000000 +0600
@@ -353,7 +353,7 @@ static int cciss_open(struct inode *inod
* but I'm already using way to many device nodes to claim another one
* for "raw controller".
*/
- if (inode->i_bdev->bd_inode->i_size == 0) {
+ if (hba[ctlr]->drv[dsk].nr_blocks == 0) {
if (minor(inode->i_rdev) != 0)
return -ENXIO;
if (!capable(CAP_SYS_ADMIN))

_

2003-02-12 19:01:16

by Cameron, Steve

[permalink] [raw]
Subject: Re: [PATCH] 2.5.60 make cciss driver compile


>From [email protected], fix memory leaks in cciss driver
(patch 2 of 11)
-- steve

--- linux-2.5.60/drivers/block/cciss.c~cciss-memleak 2003-02-12 10:12:41.000000000 +0600
+++ linux-2.5.60-scameron/drivers/block/cciss.c 2003-02-12 10:12:41.000000000 +0600
@@ -1013,9 +1013,9 @@ static int register_new_disk(int ctlr)
int new_lun_index = 0;
int free_index_found = 0;
int free_index = 0;
- ReportLunData_struct *ld_buff;
- ReadCapdata_struct *size_buff;
- InquiryData_struct *inq_buff;
+ ReportLunData_struct *ld_buff = NULL;
+ ReadCapdata_struct *size_buff = NULL;
+ InquiryData_struct *inq_buff = NULL;
int return_code;
int listlength = 0;
__u32 lunid = 0;
@@ -1030,26 +1030,14 @@ static int register_new_disk(int ctlr)

ld_buff = kmalloc(sizeof(ReportLunData_struct), GFP_KERNEL);
if (ld_buff == NULL)
- {
- printk(KERN_ERR "cciss: out of memory\n");
- return -1;
- }
+ goto mem_msg;
memset(ld_buff, 0, sizeof(ReportLunData_struct));
size_buff = kmalloc(sizeof( ReadCapdata_struct), GFP_KERNEL);
if (size_buff == NULL)
- {
- printk(KERN_ERR "cciss: out of memory\n");
- kfree(ld_buff);
- return -1;
- }
+ goto mem_msg;
inq_buff = kmalloc(sizeof( InquiryData_struct), GFP_KERNEL);
if (inq_buff == NULL)
- {
- printk(KERN_ERR "cciss: out of memory\n");
- kfree(ld_buff);
- kfree(size_buff);
- return -1;
- }
+ goto mem_msg;

return_code = sendcmd_withirq(CISS_REPORT_LOG, ctlr, ld_buff,
sizeof(ReportLunData_struct), 0, 0, 0 );
@@ -1068,7 +1056,7 @@ static int register_new_disk(int ctlr)
printk(KERN_WARNING "cciss: report logical volume"
" command failed\n");
listlength = 0;
- return -1;
+ goto free_err;
}
num_luns = listlength / 8; // 8 bytes pre entry
if (num_luns > CISS_MAX_LUN)
@@ -1119,7 +1107,7 @@ static int register_new_disk(int ctlr)
if (!new_lun_found)
{
printk(KERN_WARNING "cciss: New Logical Volume not found\n");
- return -1;
+ goto free_err;
}
/* Now find the free index */
for(i=0; i <CISS_MAX_LUN; i++)
@@ -1140,7 +1128,7 @@ static int register_new_disk(int ctlr)
if (!free_index_found)
{
printk(KERN_WARNING "cciss: unable to find free slot for disk\n");
- return -1;
+ goto free_err;
}

logvol = free_index;
@@ -1233,11 +1221,16 @@ static int register_new_disk(int ctlr)
disk = hba[ctlr]->gendisk[logvol];
set_capacity(disk, hba[ctlr]->drv[logvol].nr_blocks);
add_disk(disk);
-
+freeret:
kfree(ld_buff);
kfree(size_buff);
kfree(inq_buff);
return (logvol);
+mem_msg:
+ printk(KERN_ERR "cciss: out of memory\n");
+free_err:
+ logvol = -1;
+ goto freeret;
}
/*
* Wait polling for a command to complete.

_

2003-02-12 19:04:33

by Cameron, Steve

[permalink] [raw]
Subject: Re: [PATCH] 2.5.60 make cciss driver compile

Fix possible array bounds overrun in cciss driver
(patch 4 of 11)
-- steve

--- linux-2.5.60/drivers/block/cciss.c~fix_open_bug 2003-02-12 10:12:48.000000000 +0600
+++ linux-2.5.60-scameron/drivers/block/cciss.c 2003-02-12 10:12:48.000000000 +0600
@@ -345,7 +345,7 @@ static int cciss_open(struct inode *inod
printk(KERN_DEBUG "cciss_open %x (%x:%x)\n", inode->i_rdev, ctlr, dsk);
#endif /* CCISS_DEBUG */

- if (ctlr > MAX_CTLR || hba[ctlr] == NULL)
+ if (ctlr >= MAX_CTLR || hba[ctlr] == NULL)
return -ENXIO;
/*
* Root is allowed to open raw volume zero even if its not configured

_

2003-02-12 19:05:51

by Cameron, Steve

[permalink] [raw]
Subject: Re: [PATCH] 2.5.60 make cciss driver compile

Zero out cylinders when zeroing out other disk info in cciss driver.
(patch 5 of 11)
-- steve

--- linux-2.5.60/drivers/block/cciss.c~zero_cyls 2003-02-12 10:12:56.000000000 +0600
+++ linux-2.5.60-scameron/drivers/block/cciss.c 2003-02-12 10:12:56.000000000 +0600
@@ -809,6 +809,7 @@ static int deregister_disk(int ctlr, int
/* zero out the disk size info */
h->drv[logvol].nr_blocks = 0;
h->drv[logvol].block_size = 0;
+ h->drv[logvol].cylinders = 0;
h->drv[logvol].LunID = 0;
return(0);
}

_

2003-02-12 19:10:38

by Cameron, Steve

[permalink] [raw]
Subject: Re: [PATCH] 2.5.60 make cciss driver compile


Remove unneeded cciss_scsi init code from cciss driver.
(patch 8 of 11)
-- steve

--- linux-2.5.60/drivers/block/cciss.c~kill_bogus_scsi_code 2003-02-12 10:13:08.000000000 +0600
+++ linux-2.5.60-scameron/drivers/block/cciss.c 2003-02-12 10:13:08.000000000 +0600
@@ -2440,9 +2440,6 @@ static int __init cciss_init_one(struct
set_capacity(disk, drv->nr_blocks);
add_disk(disk);
}
-
- cciss_register_scsi(i, 1); /* hook ourself into SCSI subsystem */
-
return(1);
}

--- linux-2.5.60/drivers/block/cciss_scsi.c~kill_bogus_scsi_code 2003-02-12 10:13:08.000000000 +0600
+++ linux-2.5.60-scameron/drivers/block/cciss_scsi.c 2003-02-12 10:13:08.000000000 +0600
@@ -89,8 +89,10 @@ static struct cciss_scsi_hba_t ccissscsi
working even with the SCSI system. It's so
scsi_unregister_host will differentiate the controllers.
When register_scsi_module is called, each host template is
- customized (name change) in cciss_register_scsi()
- (that's called from cciss.c:cciss_init_one()) */
+ customized (name change) in cciss_register_scsi() (that's
+ called from cciss_engage_scsi, called from
+ cciss.c:cciss_proc_write(), on "engage scsi" being received
+ from user space.) */

static
Scsi_Host_Template driver_template[MAX_CTLR] =
@@ -1530,7 +1532,7 @@ cciss_unregister_scsi(int ctlr)
}

static int
-cciss_register_scsi(int ctlr, int this_is_init_time)
+cciss_register_scsi(int ctlr)
{
unsigned long flags;

@@ -1540,15 +1542,10 @@ cciss_register_scsi(int ctlr, int this_i
driver_template[ctlr].module = THIS_MODULE;;

/* Since this is really a block driver, the SCSI core may not be
- initialized yet, in which case, calling scsi_register_host
- would hang. instead, we will do it later, via /proc filesystem
+ initialized at init time, in which case, calling scsi_register_host
+ would hang. Instead, we do it later, via /proc filesystem
and rc scripts, when we know SCSI core is good to go. */

- if (this_is_init_time) {
- CPQ_TAPE_UNLOCK(ctlr, flags);
- return 0;
- }
-
/* Only register if SCSI devices are detected. */
if (ccissscsi[ctlr].ndevices != 0) {
((struct cciss_scsi_adapter_data_t *)
@@ -1582,7 +1579,7 @@ cciss_engage_scsi(int ctlr)
}
spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
cciss_update_non_disk_devices(ctlr, -1);
- cciss_register_scsi(ctlr, 0);
+ cciss_register_scsi(ctlr);
return 0;
}

@@ -1608,7 +1605,7 @@ cciss_proc_tape_report(int ctlr, unsigne

#define cciss_find_non_disk_devices(cntl_num)
#define cciss_unregister_scsi(ctlr)
-#define cciss_register_scsi(ctlr, this_is_init_time)
+#define cciss_register_scsi(ctlr)
#define cciss_proc_tape_report(ctlr, buffer, pos, len)

#endif /* CONFIG_CISS_SCSI_TAPE */

_

2003-02-12 19:06:49

by Cameron, Steve

[permalink] [raw]
Subject: Re: [PATCH] 2.5.60 make cciss driver compile


Remove unused variable from cciss_scsi.c
(patch 6 of 11)
-- steve

--- linux-2.5.60/drivers/block/cciss_scsi.c~rm_unused_var 2003-02-12 10:12:59.000000000 +0600
+++ linux-2.5.60-scameron/drivers/block/cciss_scsi.c 2003-02-12 10:12:59.000000000 +0600
@@ -1262,7 +1262,6 @@ cciss_scsi_proc_info(char *buffer, /* da

int buflen, datalen;
struct Scsi_Host *sh;
- int found;
ctlr_info_t *ci;
int cntl_num;


_

2003-02-12 19:09:21

by Cameron, Steve

[permalink] [raw]
Subject: Re: [PATCH] 2.5.60 make cciss driver compile


For the cciss driver:
This patch makes scsi commands to tape drives have no timeouts.
Previously the timeout was 1000 seconds, too short, and nothing good
happens when the timeout expires. Better to have no timeout.
e.g. mt -f /dev/st0 erase may take about 2 hours 30 min on AIT 100.
(patch 7 of 11)

-- steve

--- linux-2.5.60/drivers/block/cciss_scsi.c~no_tape_timeouts 2003-02-12 10:13:05.000000000 +0600
+++ linux-2.5.60-scameron/drivers/block/cciss_scsi.c 2003-02-12 10:13:05.000000000 +0600
@@ -913,7 +913,7 @@ cciss_scsi_do_simple_cmd(ctlr_info_t *c,

memset(cp->Request.CDB, 0, sizeof(cp->Request.CDB));
memcpy(cp->Request.CDB, cdb, cdblen);
- cp->Request.Timeout = 1000; // guarantee completion.
+ cp->Request.Timeout = 0;
cp->Request.CDBLen = cdblen;
cp->Request.Type.Type = TYPE_CMD;
cp->Request.Type.Attribute = ATTR_SIMPLE;
@@ -1427,7 +1427,7 @@ cciss_scsi_queue_command (Scsi_Cmnd *cmd

// Fill in the request block...

- cp->Request.Timeout = 1000; // guarantee completion
+ cp->Request.Timeout = 0;
memset(cp->Request.CDB, 0, sizeof(cp->Request.CDB));
if (cmd->cmd_len > sizeof(cp->Request.CDB)) BUG();
cp->Request.CDBLen = cmd->cmd_len;

_

2003-02-12 19:15:35

by Cameron, Steve

[permalink] [raw]
Subject: Re: [PATCH] 2.5.60 make cciss driver compile


factor duplicated geometry inquiry code into common routine in cciss driver.
(patch 11 of 11)
-- steve

--- linux-2.5.60/drivers/block/cciss.c~factor_more_duped_code 2003-02-12 10:13:22.000000000 +0600
+++ linux-2.5.60-scameron/drivers/block/cciss.c 2003-02-12 10:13:22.000000000 +0600
@@ -1006,6 +1006,49 @@ case CMD_HARDWARE_ERR:
return(return_status);

}
+static void cciss_geometry_inquiry(int ctlr, int logvol,
+ int withirq, unsigned int total_size,
+ unsigned int block_size, InquiryData_struct *inq_buff,
+ drive_info_struct *drv)
+{
+ int return_code;
+ memset(inq_buff, 0, sizeof(InquiryData_struct));
+ if (withirq)
+ return_code = sendcmd_withirq(CISS_INQUIRY, ctlr,
+ inq_buff, sizeof(*inq_buff), 1, logvol ,0xC1);
+ else
+ return_code = sendcmd(CISS_INQUIRY, ctlr, inq_buff,
+ sizeof(*inq_buff), 1, logvol ,0xC1, NULL);
+ if (return_code == IO_OK) {
+ if(inq_buff->data_byte[8] == 0xFF) {
+ printk(KERN_WARNING
+ "cciss: reading geometry failed, volume "
+ "does not support reading 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;
+ } else {
+ 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];
+ }
+ } 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_INFO " heads= %d, sectors= %d, cylinders= %d\n\n",
+ drv->heads, drv->sectors, drv->cylinders);
+}
static void
cciss_read_capacity(int ctlr, int logvol, ReadCapdata_struct *buf,
int withirq, unsigned int *total_size, unsigned int *block_size)
@@ -1166,53 +1209,8 @@ static int register_new_disk(int ctlr)
hba[ctlr]->highest_lun = logvol;
cciss_read_capacity(ctlr, logvol, size_buff, 1,
&total_size, &block_size);
- /* Execute the command to read the disk geometry */
- memset(inq_buff, 0, sizeof(InquiryData_struct));
- return_code = sendcmd_withirq(CISS_INQUIRY, ctlr, inq_buff,
- sizeof(InquiryData_struct), 1, logvol ,0xC1 );
- if (return_code == IO_OK)
- {
- if(inq_buff->data_byte[8] == 0xFF)
- {
- printk(KERN_WARNING "cciss: reading geometry failed, "
- "volume does not support reading geometry\n");
-
- hba[ctlr]->drv[logvol].block_size = block_size;
- hba[ctlr]->drv[logvol].nr_blocks = total_size;
- hba[ctlr]->drv[logvol].heads = 255;
- hba[ctlr]->drv[logvol].sectors = 32; // Sectors per track
- hba[ctlr]->drv[logvol].cylinders = total_size / 255 / 32;
- } else
- {
-
- hba[ctlr]->drv[logvol].block_size = block_size;
- hba[ctlr]->drv[logvol].nr_blocks = total_size;
- hba[ctlr]->drv[logvol].heads =
- inq_buff->data_byte[6];
- hba[ctlr]->drv[logvol].sectors =
- inq_buff->data_byte[7];
- hba[ctlr]->drv[logvol].cylinders =
- (inq_buff->data_byte[4] & 0xff) << 8;
- hba[ctlr]->drv[logvol].cylinders +=
- inq_buff->data_byte[5];
- }
- }
- else /* Get geometry failed */
- {
-
- printk(KERN_WARNING "cciss: reading geometry failed, "
- "continuing with default geometry\n");
-
- hba[ctlr]->drv[logvol].block_size = block_size;
- hba[ctlr]->drv[logvol].nr_blocks = total_size;
- hba[ctlr]->drv[logvol].heads = 255;
- hba[ctlr]->drv[logvol].sectors = 32; // Sectors per track
- hba[ctlr]->drv[logvol].cylinders = total_size / 255 / 32;
- }
- printk(KERN_INFO " heads= %d, sectors= %d, cylinders= %d\n\n",
- hba[ctlr]->drv[logvol].heads,
- hba[ctlr]->drv[logvol].sectors,
- hba[ctlr]->drv[logvol].cylinders);
+ cciss_geometry_inquiry(ctlr, logvol, 1, total_size, block_size,
+ inq_buff, &hba[ctlr]->drv[logvol]);
hba[ctlr]->drv[logvol].usage_count = 0;
++hba[ctlr]->num_luns;
/* setup partitions per disk */
@@ -2168,50 +2166,8 @@ static void cciss_getgeometry(int cntl_n
#endif /* CCISS_DEBUG */
cciss_read_capacity(cntl_num, i, size_buff, 0,
&total_size, &block_size);
- /* Execute the command to read the disk geometry */
- memset(inq_buff, 0, sizeof(InquiryData_struct));
- return_code = sendcmd(CISS_INQUIRY, cntl_num, inq_buff,
- sizeof(InquiryData_struct), 1, i ,0xC1, NULL );
- if (return_code == IO_OK)
- {
- if(inq_buff->data_byte[8] == 0xFF)
- {
- printk(KERN_WARNING "cciss: reading geometry failed, volume does not support reading geometry\n");
-
- hba[cntl_num]->drv[i].block_size = block_size;
- hba[cntl_num]->drv[i].nr_blocks = total_size;
- hba[cntl_num]->drv[i].heads = 255;
- hba[cntl_num]->drv[i].sectors = 32; // Sectors per track
- hba[cntl_num]->drv[i].cylinders = total_size / 255 / 32; } else
- {
-
- hba[cntl_num]->drv[i].block_size = block_size;
- hba[cntl_num]->drv[i].nr_blocks = total_size;
- hba[cntl_num]->drv[i].heads =
- inq_buff->data_byte[6];
- hba[cntl_num]->drv[i].sectors =
- inq_buff->data_byte[7];
- hba[cntl_num]->drv[i].cylinders =
- (inq_buff->data_byte[4] & 0xff) << 8;
- hba[cntl_num]->drv[i].cylinders +=
- inq_buff->data_byte[5];
- }
- }
- else /* Get geometry failed */
- {
- printk(KERN_WARNING "cciss: reading geometry failed, continuing with default geometry\n");
-
- hba[cntl_num]->drv[i].block_size = block_size;
- hba[cntl_num]->drv[i].nr_blocks = total_size;
- hba[cntl_num]->drv[i].heads = 255;
- hba[cntl_num]->drv[i].sectors = 32; // Sectors per track
- hba[cntl_num]->drv[i].cylinders = total_size / 255 / 32;
- }
- printk(KERN_INFO " heads= %d, sectors= %d, cylinders= %d\n\n",
- hba[cntl_num]->drv[i].heads,
- hba[cntl_num]->drv[i].sectors,
- hba[cntl_num]->drv[i].cylinders);
-
+ cciss_geometry_inquiry(cntl_num, i, 0, total_size, block_size,
+ inq_buff, &hba[cntl_num]->drv[i]);
}
kfree(ld_buff);
kfree(size_buff);

_

2003-02-12 19:12:28

by Cameron, Steve

[permalink] [raw]
Subject: Re: [PATCH] 2.5.60 make cciss driver compile


* Remove udelay in command polling routine
* extend timeout to 20 seconds (need for certain multiport storage box)
* Remove unneeded init time code in cciss_scsi.c (thus allowing removal
of udelay in command polling code.)
(patch 9 of 11)
-- steve

--- linux-2.5.60/drivers/block/cciss.c~20_sec_timeout 2003-02-12 10:13:14.000000000 +0600
+++ linux-2.5.60-scameron/drivers/block/cciss.c 2003-02-12 10:13:14.000000000 +0600
@@ -1236,24 +1236,25 @@ free_err:
/*
* Wait polling for a command to complete.
* The memory mapped FIFO is polled for the completion.
- * Used only at init time, interrupts disabled.
+ * Used only at init time, interrupts from the HBA are disabled.
*/
static unsigned long pollcomplete(int ctlr)
{
- unsigned long done;
- int i;
+ unsigned long done;
+ int i;

- /* Wait (up to 2 seconds) for a command to complete */
+ /* Wait (up to 20 seconds) for a command to complete */

- for (i = 200000; i > 0; i--) {
- done = hba[ctlr]->access.command_completed(hba[ctlr]);
- if (done == FIFO_EMPTY) {
- udelay(10); /* a short fixed delay */
- } else
- return (done);
- }
- /* Invalid address to tell caller we ran out of time */
- return 1;
+ for (i = 20 * HZ; i > 0; i--) {
+ done = hba[ctlr]->access.command_completed(hba[ctlr]);
+ if (done == FIFO_EMPTY) {
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ schedule_timeout(1);
+ } else
+ return (done);
+ }
+ /* Invalid address to tell caller we ran out of time */
+ return 1;
}
/*
* Send a command to the controller, and wait for it to complete.
@@ -2402,7 +2403,7 @@ static int __init cciss_init_one(struct

cciss_getgeometry(i);

- cciss_find_non_disk_devices(i); /* find our tape drives, if any */
+ cciss_scsi_setup(i);

/* Turn the interrupts on so we can service requests */
hba[i]->access.set_intr_mask(hba[i], CCISS_INTR_ON);
--- linux-2.5.60/drivers/block/cciss_scsi.c~20_sec_timeout 2003-02-12 10:13:14.000000000 +0600
+++ linux-2.5.60-scameron/drivers/block/cciss_scsi.c 2003-02-12 10:13:14.000000000 +0600
@@ -201,14 +201,12 @@ scsi_cmd_free(ctlr_info_t *h, CommandLis
}

static int
-scsi_cmd_stack_setup(int ctlr)
+scsi_cmd_stack_setup(int ctlr, struct cciss_scsi_adapter_data_t *sa)
{
int i;
- struct cciss_scsi_adapter_data_t *sa;
struct cciss_scsi_cmd_stack_t *stk;
size_t size;

- sa = (struct cciss_scsi_adapter_data_t *) hba[ctlr]->scsi_ctlr;
stk = &sa->cmd_stack;
size = sizeof(struct cciss_scsi_cmd_stack_elem_t) * CMD_STACK_SIZE;

@@ -537,126 +535,24 @@ lookup_scsi3addr(int ctlr, int bus, int
return -1;
}

-
static void
-cciss_find_non_disk_devices(int cntl_num)
+cciss_scsi_setup(int cntl_num)
{
- ReportLunData_struct *ld_buff;
- InquiryData_struct *inq_buff;
- int return_code;
- int i;
- int listlength = 0;
- int num_luns;
- unsigned char scsi3addr[8];
- unsigned long flags;
- int reportlunsize = sizeof(*ld_buff) + CISS_MAX_PHYS_LUN * 8;
+ struct cciss_scsi_adapter_data_t * shba;

- hba[cntl_num]->scsi_ctlr = (void *)
- kmalloc(sizeof(struct cciss_scsi_adapter_data_t),
- GFP_KERNEL);
- if (hba[cntl_num]->scsi_ctlr == NULL)
- return;
-
- ((struct cciss_scsi_adapter_data_t *)
- hba[cntl_num]->scsi_ctlr)->scsi_host = NULL;
- ((struct cciss_scsi_adapter_data_t *)
- hba[cntl_num]->scsi_ctlr)->lock = SPIN_LOCK_UNLOCKED;
- ((struct cciss_scsi_adapter_data_t *)
- hba[cntl_num]->scsi_ctlr)->registered = 0;
-
- if (scsi_cmd_stack_setup(cntl_num) != 0) {
- printk("Trouble, returned non-zero!\n");
- return;
- }
-
- ld_buff = kmalloc(reportlunsize, GFP_KERNEL);
- if (ld_buff == NULL) {
- printk(KERN_ERR "cciss: out of memory\n");
- return;
- }
- memset(ld_buff, 0, sizeof(ReportLunData_struct));
- inq_buff = kmalloc(sizeof( InquiryData_struct), GFP_KERNEL);
- if (inq_buff == NULL) {
- printk(KERN_ERR "cciss: out of memory\n");
- kfree(ld_buff);
- return;
- }
-
- /* Get the physical luns */
- return_code = sendcmd(CISS_REPORT_PHYS, cntl_num, ld_buff,
- reportlunsize, 0, 0, 0, NULL );
-
- if( return_code == IO_OK) {
- unsigned char *c = &ld_buff->LUNListLength[0];
- listlength = (c[0] << 24) | (c[1] << 16) | (c[2] << 8) | c[3];
- }
- else { /* getting report of physical luns failed */
- printk(KERN_WARNING "cciss: report physical luns"
- " command failed\n");
- listlength = 0;
- }
-
- CPQ_TAPE_LOCK(cntl_num, flags);
ccissscsi[cntl_num].ndevices = 0;
- num_luns = listlength / 8; // 8 bytes pre entry
- /* printk("Found %d LUNs\n", num_luns); */
-
- if (num_luns > CISS_MAX_PHYS_LUN)
- {
- printk(KERN_WARNING
- "cciss: Maximum physical LUNs (%d) exceeded. "
- "%d LUNs ignored.\n", CISS_MAX_PHYS_LUN,
- num_luns - CISS_MAX_PHYS_LUN);
- num_luns = CISS_MAX_PHYS_LUN;
- }
-
- for(i=0; i<num_luns; i++) {
- /* Execute an inquiry to figure the device type */
- memset(inq_buff, 0, sizeof(InquiryData_struct));
- memcpy(scsi3addr, ld_buff->LUN[i], 8); /* ugly... */
- return_code = sendcmd(CISS_INQUIRY, cntl_num, inq_buff,
- sizeof(InquiryData_struct), 2, 0 ,0, scsi3addr );
- if (return_code == IO_OK) {
- if(inq_buff->data_byte[8] == 0xFF)
- {
- printk(KERN_WARNING "cciss: inquiry failed\n");
- } else {
- int devtype;
-
- /* printk("Inquiry...\n");
- print_bytes((unsigned char *) inq_buff, 36, 1, 1); */
- devtype = (inq_buff->data_byte[0] & 0x1f);
-
- switch (devtype)
- {
- case 0x01: /* sequential access, (tape) */
- case 0x08: /* medium changer */
- /* this is the only kind of dev */
- /* we want to expose here. */
- if (cciss_scsi_add_entry(cntl_num, -1,
- (unsigned char *) ld_buff->LUN[i],
- devtype) != 0)
- i=num_luns; // leave loop
- break;
- default:
- break;
- }
-
- }
- }
- else printk("cciss: inquiry failed.\n");
+ shba = (struct cciss_scsi_adapter_data_t *)
+ kmalloc(sizeof(*shba), GFP_KERNEL);
+ if (shba == NULL)
+ return;
+ shba->scsi_host = NULL;
+ shba->lock = SPIN_LOCK_UNLOCKED;
+ shba->registered = 0;
+ if (scsi_cmd_stack_setup(cntl_num, shba) != 0) {
+ kfree(shba);
+ shba = NULL;
}
-#if 0
- for (i=0;i<ccissscsi[cntl_num].ndevices;i++)
- printk("Tape device presented at c%db%dt%dl%d\n",
- cntl_num, // <-- this is wrong
- ccissscsi[cntl_num].dev[i].bus,
- ccissscsi[cntl_num].dev[i].target,
- ccissscsi[cntl_num].dev[i].lun);
-#endif
- CPQ_TAPE_UNLOCK(cntl_num, flags);
- kfree(ld_buff);
- kfree(inq_buff);
+ hba[cntl_num]->scsi_ctlr = (void *) shba;
return;
}

@@ -1603,7 +1499,7 @@ cciss_proc_tape_report(int ctlr, unsigne

/* If no tape support, then these become defined out of existence */

-#define cciss_find_non_disk_devices(cntl_num)
+#define cciss_scsi_setup(cntl_num)
#define cciss_unregister_scsi(ctlr)
#define cciss_register_scsi(ctlr)
#define cciss_proc_tape_report(ctlr, buffer, pos, len)

_

2003-02-12 19:14:42

by Cameron, Steve

[permalink] [raw]
Subject: Re: [PATCH] 2.5.60 make cciss driver compile


Factor out duplicated read capacity code into common routine in cciss driver.
(patch 10 of 11)
-- steve

--- linux-2.5.60/drivers/block/cciss.c~factor_duped_code 2003-02-12 10:13:18.000000000 +0600
+++ linux-2.5.60-scameron/drivers/block/cciss.c 2003-02-12 10:13:18.000000000 +0600
@@ -114,6 +114,9 @@ static void cciss_getgeometry(int cntl_n

static inline void addQ(CommandList_struct **Qptr, CommandList_struct *c);
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);

#ifdef CONFIG_PROC_FS
static int cciss_proc_get_info(char *buffer, char **start, off_t offset,
@@ -1003,6 +1006,30 @@ case CMD_HARDWARE_ERR:
return(return_status);

}
+static void
+cciss_read_capacity(int ctlr, int logvol, ReadCapdata_struct *buf,
+ int withirq, unsigned int *total_size, unsigned int *block_size)
+{
+ int return_code;
+ memset(buf, 0, sizeof(*buf));
+ if (withirq)
+ return_code = sendcmd_withirq(CCISS_READ_CAPACITY,
+ ctlr, buf, sizeof(*buf), 1, logvol, 0 );
+ else
+ return_code = sendcmd(CCISS_READ_CAPACITY,
+ ctlr, buf, sizeof(*buf), 1, logvol, 0, NULL );
+ 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]));
+ } else { /* read capacity command failed */
+ printk(KERN_WARNING "cciss: read capacity failed\n");
+ *total_size = 0;
+ *block_size = BLOCK_SIZE;
+ }
+ printk(KERN_INFO " blocks= %d block_size= %d\n",
+ *total_size, *block_size);
+ return;
+}
static int register_new_disk(int ctlr)
{
struct gendisk *disk;
@@ -1137,38 +1164,8 @@ static int register_new_disk(int ctlr)
/* there could be gaps in lun numbers, track hightest */
if(hba[ctlr]->highest_lun < lunid)
hba[ctlr]->highest_lun = logvol;
-
- memset(size_buff, 0, sizeof(ReadCapdata_struct));
- return_code = sendcmd_withirq(CCISS_READ_CAPACITY, ctlr, size_buff,
- sizeof( ReadCapdata_struct), 1, logvol, 0 );
- if (return_code == IO_OK)
- {
- total_size = (0xff &
- (unsigned int)(size_buff->total_size[0])) << 24;
- total_size |= (0xff &
- (unsigned int)(size_buff->total_size[1])) << 16;
- total_size |= (0xff &
- (unsigned int)(size_buff->total_size[2])) << 8;
- total_size |= (0xff & (unsigned int)
- (size_buff->total_size[3]));
- total_size++; // command returns highest block address
-
- block_size = (0xff &
- (unsigned int)(size_buff->block_size[0])) << 24;
- block_size |= (0xff &
- (unsigned int)(size_buff->block_size[1])) << 16;
- block_size |= (0xff &
- (unsigned int)(size_buff->block_size[2])) << 8;
- block_size |= (0xff &
- (unsigned int)(size_buff->block_size[3]));
- } else /* read capacity command failed */
- {
- printk(KERN_WARNING "cciss: read capacity failed\n");
- total_size = 0;
- block_size = BLOCK_SIZE;
- }
- printk(KERN_INFO " blocks= %u block_size= %d\n",
- total_size, block_size);
+ cciss_read_capacity(ctlr, logvol, size_buff, 1,
+ &total_size, &block_size);
/* Execute the command to read the disk geometry */
memset(inq_buff, 0, sizeof(InquiryData_struct));
return_code = sendcmd_withirq(CISS_INQUIRY, ctlr, inq_buff,
@@ -2169,39 +2166,8 @@ static void cciss_getgeometry(int cntl_n
ld_buff->LUN[i][0], ld_buff->LUN[i][1],ld_buff->LUN[i][2],
ld_buff->LUN[i][3], hba[cntl_num]->drv[i].LunID);
#endif /* CCISS_DEBUG */
-
- memset(size_buff, 0, sizeof(ReadCapdata_struct));
- return_code = sendcmd(CCISS_READ_CAPACITY, cntl_num, size_buff,
- sizeof( ReadCapdata_struct), 1, i, 0, NULL );
- if (return_code == IO_OK)
- {
- total_size = (0xff &
- (unsigned int)(size_buff->total_size[0])) << 24;
- total_size |= (0xff &
- (unsigned int)(size_buff->total_size[1])) << 16;
- total_size |= (0xff &
- (unsigned int)(size_buff->total_size[2])) << 8;
- total_size |= (0xff & (unsigned int)
- (size_buff->total_size[3]));
- total_size++; // command returns highest block address
-
- block_size = (0xff &
- (unsigned int)(size_buff->block_size[0])) << 24;
- block_size |= (0xff &
- (unsigned int)(size_buff->block_size[1])) << 16;
- block_size |= (0xff &
- (unsigned int)(size_buff->block_size[2])) << 8;
- block_size |= (0xff &
- (unsigned int)(size_buff->block_size[3]));
- } else /* read capacity command failed */
- {
- printk(KERN_WARNING "cciss: read capacity failed\n");
- total_size = 0;
- block_size = BLOCK_SIZE;
- }
- printk(KERN_INFO " blocks= %d block_size= %d\n",
- total_size, block_size);
-
+ cciss_read_capacity(cntl_num, i, size_buff, 0,
+ &total_size, &block_size);
/* Execute the command to read the disk geometry */
memset(inq_buff, 0, sizeof(InquiryData_struct));
return_code = sendcmd(CISS_INQUIRY, cntl_num, inq_buff,

_