Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 182942
b: refs/heads/master
c: 87c3a92
h: refs/heads/master
v: v3
  • Loading branch information
Stephen M. Cameron authored and Jens Axboe committed Feb 28, 2010
1 parent ff163a0 commit 9113578
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 27 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: bf8873781831c7799255e0932848401070185dd0
refs/heads/master: 87c3a922a7ee8cfb9ab837f4ae38c993e9b30711
85 changes: 59 additions & 26 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 = {
.queuecommand = cciss_scsi_queue_command,
.can_queue = SCSI_CCISS_CAN_QUEUE,
.this_id = 7,
.sg_tablesize = MAXSGENTRIES,
.cmd_per_lun = 1,
.use_clustering = DISABLE_CLUSTERING,
/* Can't have eh_bus_reset_handler or eh_host_reset_handler for cciss */
Expand All @@ -94,13 +93,14 @@ static struct scsi_host_template cciss_driver_template = {

#pragma pack(1)

#define SCSI_PAD_32 4
#define SCSI_PAD_64 4
#define SCSI_PAD_32 0
#define SCSI_PAD_64 0

struct cciss_scsi_cmd_stack_elem_t {
CommandList_struct cmd;
ErrorInfo_struct Err;
__u32 busaddr;
int cmdindex;
u8 pad[IS_32_BIT * SCSI_PAD_32 + IS_64_BIT * SCSI_PAD_64];
};

Expand All @@ -122,6 +122,7 @@ struct cciss_scsi_cmd_stack_t {
struct cciss_scsi_adapter_data_t {
struct Scsi_Host *scsi_host;
struct cciss_scsi_cmd_stack_t cmd_stack;
SGDescriptor_struct **cmd_sg_list;
int registered;
spinlock_t lock; // to protect ccissscsi[ctlr];
};
Expand Down Expand Up @@ -156,6 +157,7 @@ scsi_cmd_alloc(ctlr_info_t *h)
memset(&c->Err, 0, sizeof(c->Err));
/* set physical addr of cmd and addr of scsi parameters */
c->cmd.busaddr = c->busaddr;
c->cmd.cmdindex = c->cmdindex;
/* (__u32) (stk->cmd_pool_handle +
(sizeof(struct cciss_scsi_cmd_stack_elem_t)*stk->top)); */

Expand Down Expand Up @@ -201,6 +203,11 @@ scsi_cmd_stack_setup(int ctlr, struct cciss_scsi_adapter_data_t *sa)
struct cciss_scsi_cmd_stack_t *stk;
size_t size;

sa->cmd_sg_list = cciss_allocate_sg_chain_blocks(hba[ctlr],
hba[ctlr]->chainsize, CMD_STACK_SIZE);
if (!sa->cmd_sg_list && hba[ctlr]->chainsize > 0)
return -ENOMEM;

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

Expand All @@ -211,14 +218,16 @@ scsi_cmd_stack_setup(int ctlr, struct cciss_scsi_adapter_data_t *sa)
pci_alloc_consistent(hba[ctlr]->pdev, size, &stk->cmd_pool_handle);

if (stk->pool == NULL) {
printk("stk->pool is null\n");
return -1;
cciss_free_sg_chain_blocks(sa->cmd_sg_list, CMD_STACK_SIZE);
sa->cmd_sg_list = NULL;
return -ENOMEM;
}

for (i=0; i<CMD_STACK_SIZE; 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;
return 0;
Expand All @@ -243,6 +252,7 @@ scsi_cmd_stack_free(int ctlr)

pci_free_consistent(hba[ctlr]->pdev, size, stk->pool, stk->cmd_pool_handle);
stk->pool = NULL;
cciss_free_sg_chain_blocks(sa->cmd_sg_list, CMD_STACK_SIZE);
}

#if 0
Expand Down Expand Up @@ -726,6 +736,8 @@ complete_scsi_command( CommandList_struct *cp, int timeout, __u32 tag)
ctlr = hba[cp->ctlr];

scsi_dma_unmap(cmd);
if (cp->Header.SGTotal > ctlr->max_cmd_sgentries)
cciss_unmap_sg_chain_block(ctlr, cp);

cmd->result = (DID_OK << 16); /* host byte */
cmd->result |= (COMMAND_COMPLETE << 8); /* msg byte */
Expand Down Expand Up @@ -848,6 +860,7 @@ cciss_scsi_detect(int ctlr)
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->sg_tablesize = hba[ctlr]->maxsgentries;

((struct cciss_scsi_adapter_data_t *)
hba[ctlr]->scsi_ctlr)->scsi_host = sh;
Expand Down Expand Up @@ -1365,34 +1378,54 @@ cciss_scsi_proc_info(struct Scsi_Host *sh,
dma mapping and fills in the scatter gather entries of the
cciss command, cp. */

static void
cciss_scatter_gather(struct pci_dev *pdev,
CommandList_struct *cp,
struct scsi_cmnd *cmd)
static void cciss_scatter_gather(ctlr_info_t *h, CommandList_struct *cp,
struct scsi_cmnd *cmd)
{
unsigned int len;
struct scatterlist *sg;
__u64 addr64;
int use_sg, i;

BUG_ON(scsi_sg_count(cmd) > MAXSGENTRIES);

use_sg = scsi_dma_map(cmd);
if (use_sg) { /* not too many addrs? */
scsi_for_each_sg(cmd, sg, use_sg, i) {
int request_nsgs, i, chained, sg_index;
struct cciss_scsi_adapter_data_t *sa = h->scsi_ctlr;
SGDescriptor_struct *curr_sg;

BUG_ON(scsi_sg_count(cmd) > h->maxsgentries);

chained = 0;
sg_index = 0;
curr_sg = cp->SG;
request_nsgs = scsi_dma_map(cmd);
if (request_nsgs) {
scsi_for_each_sg(cmd, sg, request_nsgs, i) {
if (sg_index + 1 == h->max_cmd_sgentries &&
!chained && request_nsgs - i > 1) {
chained = 1;
sg_index = 0;
curr_sg = sa->cmd_sg_list[cp->cmdindex];
}
addr64 = (__u64) sg_dma_address(sg);
len = sg_dma_len(sg);
cp->SG[i].Addr.lower =
(__u32) (addr64 & (__u64) 0x00000000FFFFFFFF);
cp->SG[i].Addr.upper =
(__u32) ((addr64 >> 32) & (__u64) 0x00000000FFFFFFFF);
cp->SG[i].Len = len;
cp->SG[i].Ext = 0; // we are not chaining
curr_sg[sg_index].Addr.lower =
(__u32) (addr64 & 0x0FFFFFFFFULL);
curr_sg[sg_index].Addr.upper =
(__u32) ((addr64 >> 32) & 0x0FFFFFFFFULL);
curr_sg[sg_index].Len = len;
curr_sg[sg_index].Ext = 0;
++sg_index;
}
if (chained)
cciss_map_sg_chain_block(h, cp,
sa->cmd_sg_list[cp->cmdindex],
(request_nsgs - (h->max_cmd_sgentries - 1)) *
sizeof(SGDescriptor_struct));
}

cp->Header.SGList = (__u8) use_sg; /* no. SGs contig in this cmd */
cp->Header.SGTotal = (__u16) use_sg; /* total sgs in this cmd list */
/* track how many SG entries we are using */
if (request_nsgs > h->maxSG)
h->maxSG = request_nsgs;
cp->Header.SGTotal = (__u8) request_nsgs + chained;
if (request_nsgs > h->max_cmd_sgentries)
cp->Header.SGList = h->max_cmd_sgentries;
else
cp->Header.SGList = cp->Header.SGTotal;
return;
}

Expand Down Expand Up @@ -1490,7 +1523,7 @@ cciss_scsi_queue_command (struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd
BUG();
break;
}
cciss_scatter_gather(c->pdev, cp, cmd);
cciss_scatter_gather(c, cp, cmd);

/* Put the request on the tail of the request queue */

Expand Down

0 comments on commit 9113578

Please sign in to comment.