Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 251191
b: refs/heads/master
c: 8a4ec67
h: refs/heads/master
i:
  251189: 5a56492
  251187: 9f14e45
  251183: 026d8af
v: v3
  • Loading branch information
Stephen M. Cameron authored and Jens Axboe committed May 6, 2011
1 parent e4c6fd9 commit 02ca01e
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 24 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 063d2cf72ab6101d2dd69bd6fb503b229be70325
refs/heads/master: 8a4ec67bd5648beb09d7db988a75835b740e950d
15 changes: 15 additions & 0 deletions trunk/Documentation/blockdev/cciss.txt
Original file line number Diff line number Diff line change
Expand Up @@ -169,3 +169,18 @@ 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)
before i/o can proceed again to a tape drive which was reset.

There is a cciss_tape_cmds module parameter which can be used to make cciss
allocate more commands for use by tape drives. Ordinarily only a few commands
(6) are allocated for tape drives because tape drives are slow and
infrequently used and the primary purpose of Smart Array controllers is to
act as a RAID controller for disk drives, so the vast majority of commands
are allocated for disk devices. However, if you have more than a few tape
drives attached to a smart array, the default number of commands may not be
enought (for example, if you have 8 tape drives, you could only rewind 6
at one time with the default number of commands.) The cciss_tape_cmds module
parameter allows more commands (up to 16 more) to be allocated for use by
tape drives. For example:

insmod cciss.ko cciss_tape_cmds=16

Or, as a kernel boot parameter passed in via grub: cciss.cciss_tape_cmds=8
11 changes: 10 additions & 1 deletion trunk/drivers/block/cciss.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ MODULE_DESCRIPTION("Driver for HP Smart Array Controllers");
MODULE_SUPPORTED_DEVICE("HP Smart Array Controllers");
MODULE_VERSION("3.6.26");
MODULE_LICENSE("GPL");
static int cciss_tape_cmds = 6;
module_param(cciss_tape_cmds, int, 0644);
MODULE_PARM_DESC(cciss_tape_cmds,
"number of commands to allocate for tape devices (default: 6)");

static DEFINE_MUTEX(cciss_mutex);
static struct proc_dir_entry *proc_cciss;
Expand Down Expand Up @@ -4221,7 +4225,7 @@ static void __devinit cciss_get_max_perf_mode_cmds(struct ctlr_info *h)
static void __devinit cciss_find_board_params(ctlr_info_t *h)
{
cciss_get_max_perf_mode_cmds(h);
h->nr_cmds = h->max_commands - 4; /* Allow room for some ioctls */
h->nr_cmds = h->max_commands - 4 - cciss_tape_cmds;
h->maxsgentries = readl(&(h->cfgtable->MaxSGElements));
/*
* Limit in-command s/g elements to 32 save dma'able memory.
Expand Down Expand Up @@ -4959,6 +4963,11 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
sprintf(h->devname, "cciss%d", i);
h->ctlr = i;

if (cciss_tape_cmds < 2)
cciss_tape_cmds = 2;
if (cciss_tape_cmds > 16)
cciss_tape_cmds = 16;

init_completion(&h->scan_wait);

if (cciss_create_hba_sysfs_entry(h))
Expand Down
41 changes: 23 additions & 18 deletions trunk/drivers/block/cciss_scsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,6 @@ static struct scsi_host_template cciss_driver_template = {
.proc_name = "cciss",
.proc_info = cciss_scsi_proc_info,
.queuecommand = cciss_scsi_queue_command,
.can_queue = SCSI_CCISS_CAN_QUEUE,
.this_id = 7,
.cmd_per_lun = 1,
.use_clustering = DISABLE_CLUSTERING,
Expand All @@ -108,16 +107,13 @@ struct cciss_scsi_cmd_stack_elem_t {

#pragma pack()

#define CMD_STACK_SIZE (SCSI_CCISS_CAN_QUEUE * \
CCISS_MAX_SCSI_DEVS_PER_HBA + 2)
// plus two for init time usage

#pragma pack(1)
struct cciss_scsi_cmd_stack_t {
struct cciss_scsi_cmd_stack_elem_t *pool;
struct cciss_scsi_cmd_stack_elem_t *elem[CMD_STACK_SIZE];
struct cciss_scsi_cmd_stack_elem_t **elem;
dma_addr_t cmd_pool_handle;
int top;
int nelems;
};
#pragma pack()

Expand Down Expand Up @@ -191,7 +187,7 @@ scsi_cmd_free(ctlr_info_t *h, CommandList_struct *c)
sa = h->scsi_ctlr;
stk = &sa->cmd_stack;
stk->top++;
if (stk->top >= CMD_STACK_SIZE) {
if (stk->top >= stk->nelems) {
dev_err(&h->pdev->dev,
"scsi_cmd_free called too many times.\n");
BUG();
Expand All @@ -206,13 +202,14 @@ scsi_cmd_stack_setup(ctlr_info_t *h, struct cciss_scsi_adapter_data_t *sa)
struct cciss_scsi_cmd_stack_t *stk;
size_t size;

stk = &sa->cmd_stack;
stk->nelems = cciss_tape_cmds + 2;
sa->cmd_sg_list = cciss_allocate_sg_chain_blocks(h,
h->chainsize, CMD_STACK_SIZE);
h->chainsize, stk->nelems);
if (!sa->cmd_sg_list && h->chainsize > 0)
return -ENOMEM;

stk = &sa->cmd_stack;
size = sizeof(struct cciss_scsi_cmd_stack_elem_t) * CMD_STACK_SIZE;
size = sizeof(struct cciss_scsi_cmd_stack_elem_t) * stk->nelems;

/* Check alignment, see cciss_cmd.h near CommandList_struct def. */
BUILD_BUG_ON((sizeof(*stk->pool) % COMMANDLIST_ALIGNMENT) != 0);
Expand All @@ -221,18 +218,23 @@ scsi_cmd_stack_setup(ctlr_info_t *h, struct cciss_scsi_adapter_data_t *sa)
pci_alloc_consistent(h->pdev, size, &stk->cmd_pool_handle);

if (stk->pool == NULL) {
cciss_free_sg_chain_blocks(sa->cmd_sg_list, CMD_STACK_SIZE);
cciss_free_sg_chain_blocks(sa->cmd_sg_list, stk->nelems);
sa->cmd_sg_list = NULL;
return -ENOMEM;
}

for (i=0; i<CMD_STACK_SIZE; i++) {
stk->elem = kmalloc(sizeof(stk->elem[0]) * stk->nelems, GFP_KERNEL);
if (!stk->elem) {
pci_free_consistent(h->pdev, size, stk->pool,
stk->cmd_pool_handle);
return -1;
}
for (i = 0; i < stk->nelems; i++) {
stk->elem[i] = &stk->pool[i];
stk->elem[i]->busaddr = (__u32) (stk->cmd_pool_handle +
(sizeof(struct cciss_scsi_cmd_stack_elem_t) * i));
stk->elem[i]->cmdindex = i;
}
stk->top = CMD_STACK_SIZE-1;
stk->top = stk->nelems-1;
return 0;
}

Expand All @@ -245,16 +247,18 @@ scsi_cmd_stack_free(ctlr_info_t *h)

sa = h->scsi_ctlr;
stk = &sa->cmd_stack;
if (stk->top != CMD_STACK_SIZE-1) {
if (stk->top != stk->nelems-1) {
dev_warn(&h->pdev->dev,
"bug: %d scsi commands are still outstanding.\n",
CMD_STACK_SIZE - stk->top);
stk->nelems - stk->top);
}
size = sizeof(struct cciss_scsi_cmd_stack_elem_t) * CMD_STACK_SIZE;
size = sizeof(struct cciss_scsi_cmd_stack_elem_t) * stk->nelems;

pci_free_consistent(h->pdev, size, stk->pool, stk->cmd_pool_handle);
stk->pool = NULL;
cciss_free_sg_chain_blocks(sa->cmd_sg_list, CMD_STACK_SIZE);
cciss_free_sg_chain_blocks(sa->cmd_sg_list, stk->nelems);
kfree(stk->elem);
stk->elem = NULL;
}

#if 0
Expand Down Expand Up @@ -859,6 +863,7 @@ cciss_scsi_detect(ctlr_info_t *h)
sh->io_port = 0; // good enough? FIXME,
sh->n_io_port = 0; // I don't think we use these two...
sh->this_id = SELF_SCSI_ID;
sh->can_queue = cciss_tape_cmds;
sh->sg_tablesize = h->maxsgentries;
sh->max_cmd_len = MAX_COMMAND_SIZE;

Expand Down
4 changes: 0 additions & 4 deletions trunk/drivers/block/cciss_scsi.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,9 @@
addressible natively, and may in fact turn
out to be not scsi at all. */

#define SCSI_CCISS_CAN_QUEUE 2

/*
Note, cmd_per_lun could give us some trouble, so I'm setting it very low.
Likewise, SCSI_CCISS_CAN_QUEUE is set very conservatively.
If the upper scsi layer tries to track how many commands we have
outstanding, it will be operating under the misapprehension that it is
the only one sending us requests. We also have the block interface,
Expand Down

0 comments on commit 02ca01e

Please sign in to comment.