Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 33079b21 authored by Mike Miller's avatar Mike Miller Committed by Linus Torvalds
Browse files

[PATCH] cciss: direct lookup for command completions



This patch changes the way we complete commands.  In the old method when we
got a completion we searched our command list from the top until we find it.

This method uses a tag associated with each command (not SCSI command tagging)
to index us directly to the completed command.  This helps performance.

Signed-off-by: default avatarDon Brace <dab@hp.com>
Signed-off-by: default avatarMike Miller <mike.miller@hp.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent ddd47442
Loading
Loading
Loading
Loading
+65 −5
Original line number Diff line number Diff line
@@ -174,6 +174,8 @@ 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);

static void fail_all_cmds(unsigned long ctlr);

#ifdef CONFIG_PROC_FS
static int cciss_proc_get_info(char *buffer, char **start, off_t offset, 
		int length, int *eof, void *data);
@@ -387,6 +389,8 @@ static CommandList_struct * cmd_alloc(ctlr_info_t *h, int get_from_pool)
                 	return NULL;
		memset(c, 0, sizeof(CommandList_struct));

		c->cmdindex = -1;

		c->err_info = (ErrorInfo_struct *)pci_alloc_consistent(
					h->pdev, sizeof(ErrorInfo_struct), 
					&err_dma_handle);
@@ -417,6 +421,8 @@ static CommandList_struct * cmd_alloc(ctlr_info_t *h, int get_from_pool)
		err_dma_handle = h->errinfo_pool_dhandle 
					+ i*sizeof(ErrorInfo_struct);
                h->nr_allocs++;

		c->cmdindex = i;
        }

	c->busaddr = (__u32) cmd_dma_handle;
@@ -2257,7 +2263,11 @@ static void do_cciss_request(request_queue_t *q)
	/* fill in the request */ 
	drv = creq->rq_disk->private_data;
	c->Header.ReplyQueue = 0;  // unused in simple mode
	c->Header.Tag.lower = c->busaddr;  // use the physical address the cmd block for tag
	/* got command from pool, so use the command block index instead */
	/* for direct lookups. */
	/* The first 2 bits are reserved for controller error reporting. */
	c->Header.Tag.lower = (c->cmdindex << 3);
	c->Header.Tag.lower |= 0x04; /* flag for direct lookup. */
	c->Header.LUN.LogDev.VolId= drv->LunID;
	c->Header.LUN.LogDev.Mode = 1;
	c->Request.CDBLen = 10; // 12 byte commands not in FW yet;
@@ -2332,7 +2342,7 @@ static irqreturn_t do_cciss_intr(int irq, void *dev_id, struct pt_regs *regs)
	ctlr_info_t *h = dev_id;
	CommandList_struct *c;
	unsigned long flags;
	__u32 a, a1;
	__u32 a, a1, a2;
	int j;
	int start_queue = h->next_to_run;

@@ -2350,10 +2360,21 @@ static irqreturn_t do_cciss_intr(int irq, void *dev_id, struct pt_regs *regs)
		while((a = h->access.command_completed(h)) != FIFO_EMPTY) 
		{
			a1 = a;
			if ((a & 0x04)) {
				a2 = (a >> 3);
				if (a2 >= NR_CMDS) {
					printk(KERN_WARNING "cciss: controller cciss%d failed, stopping.\n", h->ctlr);
					fail_all_cmds(h->ctlr);
					return IRQ_HANDLED;
				}

				c = h->cmd_pool + a2;
				a = c->busaddr;

			} else {
			a &= ~3;
			if ((c = h->cmpQ) == NULL)
			{  
				printk(KERN_WARNING "cciss: Completion of %08lx ignored\n", (unsigned long)a1);
				if ((c = h->cmpQ) == NULL) {
					printk(KERN_WARNING "cciss: Completion of %08x ignored\n", a1);
				continue;	
			} 
			while(c->busaddr != a) {
@@ -2361,6 +2382,7 @@ static irqreturn_t do_cciss_intr(int irq, void *dev_id, struct pt_regs *regs)
				if (c == h->cmpQ) 
					break;
			}
			}
			/*
			 * If we've found the command, take it off the
			 * completion Q and free it
@@ -3124,5 +3146,43 @@ static void __exit cciss_cleanup(void)
	remove_proc_entry("cciss", proc_root_driver);
}

static void fail_all_cmds(unsigned long ctlr)
{
	/* If we get here, the board is apparently dead. */
	ctlr_info_t *h = hba[ctlr];
	CommandList_struct *c;
	unsigned long flags;

	printk(KERN_WARNING "cciss%d: controller not responding.\n", h->ctlr);
	h->alive = 0;	/* the controller apparently died... */

	spin_lock_irqsave(CCISS_LOCK(ctlr), flags);

	pci_disable_device(h->pdev); /* Make sure it is really dead. */

	/* move everything off the request queue onto the completed queue */
	while( (c = h->reqQ) != NULL ) {
		removeQ(&(h->reqQ), c);
		h->Qdepth--;
		addQ (&(h->cmpQ), c);
	}

	/* Now, fail everything on the completed queue with a HW error */
	while( (c = h->cmpQ) != NULL ) {
		removeQ(&h->cmpQ, c);
		c->err_info->CommandStatus = CMD_HARDWARE_ERR;
		if (c->cmd_type == CMD_RWREQ) {
			complete_command(h, c, 0);
		} else if (c->cmd_type == CMD_IOCTL_PEND)
			complete(c->waiting);
#ifdef CONFIG_CISS_SCSI_TAPE
			else if (c->cmd_type == CMD_SCSI)
				complete_scsi_command(c, 0, 0);
#endif
	}
	spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
	return;
}

module_init(cciss_init);
module_exit(cciss_cleanup);
+1 −0
Original line number Diff line number Diff line
@@ -101,6 +101,7 @@ struct ctlr_info
#ifdef CONFIG_CISS_SCSI_TAPE
	void *scsi_ctlr; /* ptr to structure containing scsi related stuff */
#endif
	unsigned char alive;
};

/*  Defining the diffent access_menthods */
+6 −2
Original line number Diff line number Diff line
@@ -226,6 +226,10 @@ typedef struct _ErrorInfo_struct {
#define CMD_MSG_DONE	0x04
#define CMD_MSG_TIMEOUT 0x05

/* This structure needs to be divisible by 8 for new
 * indexing method.
 */
#define PADSIZE (sizeof(long) - 4)
typedef struct _CommandList_struct {
  CommandListHeader_struct Header;
  RequestBlock_struct      Request;
@@ -236,14 +240,14 @@ typedef struct _CommandList_struct {
  ErrorInfo_struct * 	   err_info; /* pointer to the allocated mem */ 
  int			   ctlr;
  int			   cmd_type; 
  long			   cmdindex;
  struct _CommandList_struct *prev;
  struct _CommandList_struct *next;
  struct request *	   rq;
  struct completion *waiting;
  int	 retry_count;
#ifdef CONFIG_CISS_SCSI_TAPE
  void * scsi_cmd;
#endif
  char   pad[PADSIZE];
} CommandList_struct;

//Configuration Table Structure
+1 −0
Original line number Diff line number Diff line
@@ -93,6 +93,7 @@ struct cciss_scsi_cmd_stack_elem_t {
	CommandList_struct cmd;
	ErrorInfo_struct Err;
	__u32 busaddr;
	__u32 pad;
};

#pragma pack()