<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">
From: &lt;mikem@beardog.cca.cpqcorp.net&gt;

This patch adds per logical device queues to the HP cciss driver.  It
currently only implements a single lock but when time permits I will
provide that funtionality.  Thanks to Jeff Garzik for providing some sample
code.


---

 25-akpm/drivers/block/cciss.c |   48 ++++++++++++++++++++++++------------------
 25-akpm/drivers/block/cciss.h |    4 +--
 2 files changed, 30 insertions(+), 22 deletions(-)

diff -puN drivers/block/cciss.c~cciss-logical-device-queues drivers/block/cciss.c
--- 25/drivers/block/cciss.c~cciss-logical-device-queues	2004-04-06 19:07:41.053503496 -0700
+++ 25-akpm/drivers/block/cciss.c	2004-04-06 19:07:41.061502280 -0700
@@ -988,7 +988,7 @@ static int revalidate_allvol(ctlr_info_t
 		drive_info_struct *drv = &amp;(host-&gt;drv[i]);
 		if (!drv-&gt;nr_blocks)
 			continue;
-		blk_queue_hardsect_size(host-&gt;queue, drv-&gt;block_size);
+		blk_queue_hardsect_size(drv-&gt;queue, drv-&gt;block_size);
 		set_capacity(disk, drv-&gt;nr_blocks);
 		add_disk(disk);
 	}
@@ -2013,7 +2013,7 @@ static irqreturn_t do_cciss_intr(int irq
 	CommandList_struct *c;
 	unsigned long flags;
 	__u32 a, a1;
-
+	int j;
 
 	/* Is this interrupt for us? */
 	if (( h-&gt;access.intr_pending(h) == 0) || (h-&gt;interrupts_enabled == 0))
@@ -2059,11 +2059,18 @@ static irqreturn_t do_cciss_intr(int irq
 			}
 		}
 	}
-
 	/*
 	 * See if we can queue up some more IO
+	 * check every disk that exists on this controller
+	 * and start it's IO
 	 */
-	blk_start_queue(h-&gt;queue);
+	for(j=0;j &lt; NWD; j++) {
+		/* 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-&gt;gendisk[j]-&gt;queue) || !(h-&gt;drv[j].nr_blocks) )
+			continue;
+		blk_start_queue(h-&gt;gendisk[j]-&gt;queue);
+	}
 	spin_unlock_irqrestore(CCISS_LOCK(h-&gt;ctlr), flags);
 	return IRQ_HANDLED;
 }
@@ -2510,7 +2517,6 @@ static void free_hba(int i)
 static int __devinit cciss_init_one(struct pci_dev *pdev,
 	const struct pci_device_id *ent)
 {
-	request_queue_t *q;
 	int i;
 	int j;
 
@@ -2568,13 +2574,6 @@ static int __devinit cciss_init_one(stru
 	}
 
 	spin_lock_init(&amp;hba[i]-&gt;lock);
-	q = blk_init_queue(do_cciss_request, &amp;hba[i]-&gt;lock);
-	if (!q)
-		goto clean4;
-
-	q-&gt;backing_dev_info.ra_pages = READ_AHEAD;
-	hba[i]-&gt;queue = q;
-	q-&gt;queuedata = hba[i];
 
 	/* Initialize the pdev driver private data. 
 		have it point to hba[i].  */
@@ -2596,6 +2595,19 @@ static int __devinit cciss_init_one(stru
 
 	cciss_procinit(i);
 
+	for(j=0; j&lt;NWD; j++) {
+		drive_info_struct *drv = &amp;(hba[i]-&gt;drv[j]);
+		struct gendisk *disk = hba[i]-&gt;gendisk[j];
+		request_queue_t *q;
+
+	        q = blk_init_queue(do_cciss_request, &amp;hba[i]-&gt;lock);
+		if (!q) {
+			printk(KERN_ERR
+			   "cciss:  unable to allocate queue for disk %d\n",
+			   j);
+			break;
+		}
+		drv-&gt;queue = q;
 	blk_queue_bounce_limit(q, hba[i]-&gt;pdev-&gt;dma_mask);
 
 	/* This is a hardware imposed limit. */
@@ -2606,21 +2618,17 @@ static int __devinit cciss_init_one(stru
 
 	blk_queue_max_sectors(q, 512);
 
-
-	for(j=0; j&lt;NWD; j++) {
-		drive_info_struct *drv = &amp;(hba[i]-&gt;drv[j]);
-		struct gendisk *disk = hba[i]-&gt;gendisk[j];
-
+		q-&gt;queuedata = hba[i];
 		sprintf(disk-&gt;disk_name, "cciss/c%dd%d", i, j);
 		sprintf(disk-&gt;devfs_name, "cciss/host%d/target%d", i, j);
 		disk-&gt;major = COMPAQ_CISS_MAJOR + i;
 		disk-&gt;first_minor = j &lt;&lt; NWD_SHIFT;
 		disk-&gt;fops = &amp;cciss_fops;
-		disk-&gt;queue = hba[i]-&gt;queue;
+		disk-&gt;queue = q;
 		disk-&gt;private_data = drv;
 		if( !(drv-&gt;nr_blocks))
 			continue;
-		blk_queue_hardsect_size(hba[i]-&gt;queue, drv-&gt;block_size);
+		blk_queue_hardsect_size(q, drv-&gt;block_size);
 		set_capacity(disk, drv-&gt;nr_blocks);
 		add_disk(disk);
 	}
@@ -2690,9 +2698,9 @@ static void __devexit cciss_remove_one (
 		struct gendisk *disk = hba[i]-&gt;gendisk[j];
 		if (disk-&gt;flags &amp; GENHD_FL_UP)
 			del_gendisk(disk);
+			blk_cleanup_queue(disk-&gt;queue);
 	}
 
-	blk_cleanup_queue(hba[i]-&gt;queue);
 	pci_free_consistent(hba[i]-&gt;pdev, NR_CMDS * sizeof(CommandList_struct),
 			    hba[i]-&gt;cmd_pool, hba[i]-&gt;cmd_pool_dhandle);
 	pci_free_consistent(hba[i]-&gt;pdev, NR_CMDS * sizeof( ErrorInfo_struct),
diff -puN drivers/block/cciss.h~cciss-logical-device-queues drivers/block/cciss.h
--- 25/drivers/block/cciss.h~cciss-logical-device-queues	2004-04-06 19:07:41.054503344 -0700
+++ 25-akpm/drivers/block/cciss.h	2004-04-06 19:07:41.061502280 -0700
@@ -27,6 +27,7 @@ typedef struct _drive_info_struct
 {
  	__u32   LunID;	
 	int 	usage_count;
+	struct request_queue *queue;
 	sector_t nr_blocks;
 	int	block_size;
 	int 	heads;
@@ -69,7 +70,6 @@ struct ctlr_info 
 	unsigned int maxQsinceinit;
 	unsigned int maxSG;
 	spinlock_t lock;
-	struct request_queue *queue;
 
 	//* pointers to command and error info pool */ 
 	CommandList_struct 	*cmd_pool;
@@ -252,7 +252,7 @@ struct board_type {
 	struct access_method *access;
 };
 
-#define CCISS_LOCK(i)	(hba[i]-&gt;queue-&gt;queue_lock)
+#define CCISS_LOCK(i)	(&amp;(hba[i]-&gt;lock))
 
 #endif /* CCISS_H */
 

_
</pre></body></html>