#include <linux/slab.h>
#include <linux/string.h>
-#include <asm/atomic.h>
+#include <linux/atomic.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_device.h>
int length, /* length of data in buffer */
int func); /* 0 == read, 1 == write */
-static int cciss_scsi_queue_command (struct scsi_cmnd *cmd,
- void (* done)(struct scsi_cmnd *));
+static int cciss_scsi_queue_command (struct Scsi_Host *h,
+ struct scsi_cmnd *cmd);
static int cciss_eh_device_reset_handler(struct scsi_cmnd *);
static int cciss_eh_abort_handler(struct scsi_cmnd *);
.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,
#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()
sa = h->scsi_ctlr;
stk = &sa->cmd_stack;
stk->top++;
- if (stk->top >= CMD_STACK_SIZE) {
- printk("cciss: scsi_cmd_free called too many times.\n");
+ if (stk->top >= stk->nelems) {
+ dev_err(&h->pdev->dev,
+ "scsi_cmd_free called too many times.\n");
BUG();
}
stk->elem[stk->top] = (struct cciss_scsi_cmd_stack_elem_t *) c;
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);
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;
}
sa = h->scsi_ctlr;
stk = &sa->cmd_stack;
- if (stk->top != CMD_STACK_SIZE-1) {
- printk( "cciss: %d scsi commands are still outstanding.\n",
- CMD_STACK_SIZE - stk->top);
- // BUG();
- printk("WE HAVE A BUG HERE!!! stk=0x%p\n", stk);
+ if (stk->top != stk->nelems-1) {
+ dev_warn(&h->pdev->dev,
+ "bug: %d scsi commands are still outstanding.\n",
+ 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
unsigned char addr1[8], addr2[8];
if (n >= CCISS_MAX_SCSI_DEVS_PER_HBA) {
- printk("cciss%d: Too many devices, "
- "some will be inaccessible.\n", h->ctlr);
+ dev_warn(&h->pdev->dev, "Too many devices, "
+ "some will be inaccessible.\n");
return -1;
}
know our hostno and we don't want to print anything first
time anyway (the scsi layer's inquiries will show that info) */
if (hostno != -1)
- printk("cciss%d: %s device c%db%dt%dl%d added.\n",
- h->ctlr, scsi_device_type(sd->devtype), hostno,
+ dev_info(&h->pdev->dev, "%s device c%db%dt%dl%d added.\n",
+ scsi_device_type(sd->devtype), hostno,
sd->bus, sd->target, sd->lun);
return 0;
}
for (i = entry; i < ccissscsi[h->ctlr].ndevices-1; i++)
ccissscsi[h->ctlr].dev[i] = ccissscsi[h->ctlr].dev[i+1];
ccissscsi[h->ctlr].ndevices--;
- printk("cciss%d: %s device c%db%dt%dl%d removed.\n",
- h->ctlr, scsi_device_type(sd.devtype), hostno,
+ dev_info(&h->pdev->dev, "%s device c%db%dt%dl%d removed.\n",
+ scsi_device_type(sd.devtype), hostno,
sd.bus, sd.target, sd.lun);
}
GFP_KERNEL);
if (!added || !removed) {
- printk(KERN_WARNING "cciss%d: Out of memory in "
- "adjust_cciss_scsi_table\n", h->ctlr);
+ dev_warn(&h->pdev->dev,
+ "Out of memory in adjust_cciss_scsi_table\n");
goto free_and_out;
}
if (found == 0) { /* device no longer present. */
changes++;
- /* printk("cciss%d: %s device c%db%dt%dl%d removed.\n",
- h->ctlr, scsi_device_type(csd->devtype), hostno,
- csd->bus, csd->target, csd->lun); */
cciss_scsi_remove_entry(h, hostno, i,
removed, &nremoved);
/* remove ^^^, hence i not incremented */
} else if (found == 1) { /* device is different in some way */
changes++;
- printk("cciss%d: device c%db%dt%dl%d has changed.\n",
- h->ctlr, hostno,
- csd->bus, csd->target, csd->lun);
+ dev_info(&h->pdev->dev,
+ "device c%db%dt%dl%d has changed.\n",
+ hostno, csd->bus, csd->target, csd->lun);
cciss_scsi_remove_entry(h, hostno, i,
removed, &nremoved);
/* remove ^^^, hence i not incremented */
} else if (found == 1) {
/* should never happen... */
changes++;
- printk(KERN_WARNING "cciss%d: device "
- "unexpectedly changed\n", h->ctlr);
+ dev_warn(&h->pdev->dev,
+ "device unexpectedly changed\n");
/* but if it does happen, we just ignore that device */
}
}
/* We don't expect to get here. */
/* future cmds to this device will get selection */
/* timeout as if the device was gone. */
- printk(KERN_WARNING "cciss%d: didn't find "
+ dev_warn(&h->pdev->dev, "didn't find "
"c%db%dt%dl%d\n for removal.",
- h->ctlr, hostno, removed[i].bus,
+ hostno, removed[i].bus,
removed[i].target, removed[i].lun);
}
}
added[i].target, added[i].lun);
if (rc == 0)
continue;
- printk(KERN_WARNING "cciss%d: scsi_add_device "
+ dev_warn(&h->pdev->dev, "scsi_add_device "
"c%db%dt%dl%d failed, device not added.\n",
- h->ctlr, hostno,
- added[i].bus, added[i].target, added[i].lun);
+ hostno, added[i].bus, added[i].target, added[i].lun);
/* now we have to remove it from ccissscsi, */
/* since it didn't get added to scsi mid layer */
fixup_botched_add(h, added[i].scsi3addr);
case CMD_DATA_UNDERRUN: /* let mid layer handle it. */
break;
case CMD_DATA_OVERRUN:
- printk(KERN_WARNING "cciss: %p has"
+ dev_warn(&h->pdev->dev, "%p has"
" completed with data overrun "
"reported\n", c);
break;
}
break;
case CMD_PROTOCOL_ERR:
- printk(KERN_WARNING "cciss: %p has "
- "protocol error\n", c);
+ dev_warn(&h->pdev->dev,
+ "%p has protocol error\n", c);
break;
case CMD_HARDWARE_ERR:
cmd->result = DID_ERROR << 16;
- printk(KERN_WARNING "cciss: %p had "
- " hardware error\n", c);
+ dev_warn(&h->pdev->dev,
+ "%p had hardware error\n", c);
break;
case CMD_CONNECTION_LOST:
cmd->result = DID_ERROR << 16;
- printk(KERN_WARNING "cciss: %p had "
- "connection lost\n", c);
+ dev_warn(&h->pdev->dev,
+ "%p had connection lost\n", c);
break;
case CMD_ABORTED:
cmd->result = DID_ABORT << 16;
- printk(KERN_WARNING "cciss: %p was "
- "aborted\n", c);
+ dev_warn(&h->pdev->dev, "%p was aborted\n", c);
break;
case CMD_ABORT_FAILED:
cmd->result = DID_ERROR << 16;
- printk(KERN_WARNING "cciss: %p reports "
- "abort failed\n", c);
+ dev_warn(&h->pdev->dev,
+ "%p reports abort failed\n", c);
break;
case CMD_UNSOLICITED_ABORT:
cmd->result = DID_ABORT << 16;
- printk(KERN_WARNING "cciss: %p aborted "
- "do to an unsolicited abort\n", c);
+ dev_warn(&h->pdev->dev, "%p aborted due to an "
+ "unsolicited abort\n", c);
break;
case CMD_TIMEOUT:
cmd->result = DID_TIME_OUT << 16;
- printk(KERN_WARNING "cciss: %p timedout\n",
- c);
+ dev_warn(&h->pdev->dev, "%p timedout\n", c);
+ break;
+ case CMD_UNABORTABLE:
+ cmd->result = DID_ERROR << 16;
+ dev_warn(&h->pdev->dev, "c %p command "
+ "unabortable\n", c);
break;
default:
cmd->result = DID_ERROR << 16;
- printk(KERN_WARNING "cciss: %p returned "
- "unknown status %x\n", c,
+ dev_warn(&h->pdev->dev,
+ "%p returned unknown status %x\n", c,
ei->CommandStatus);
}
}
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;
+ sh->max_sectors = h->cciss_max_sectors;
((struct cciss_scsi_adapter_data_t *)
h->scsi_ctlr)->scsi_host = sh;
}
static void
-cciss_scsi_interpret_error(CommandList_struct *c)
+cciss_scsi_interpret_error(ctlr_info_t *h, CommandList_struct *c)
{
ErrorInfo_struct *ei;
switch(ei->CommandStatus)
{
case CMD_TARGET_STATUS:
- printk(KERN_WARNING "cciss: cmd %p has "
- "completed with errors\n", c);
- printk(KERN_WARNING "cciss: cmd %p "
- "has SCSI Status = %x\n",
- c, ei->ScsiStatus);
+ dev_warn(&h->pdev->dev,
+ "cmd %p has completed with errors\n", c);
+ dev_warn(&h->pdev->dev,
+ "cmd %p has SCSI Status = %x\n",
+ c, ei->ScsiStatus);
if (ei->ScsiStatus == 0)
- printk(KERN_WARNING
- "cciss:SCSI status is abnormally zero. "
+ dev_warn(&h->pdev->dev,
+ "SCSI status is abnormally zero. "
"(probably indicates selection timeout "
"reported incorrectly due to a known "
"firmware bug, circa July, 2001.)\n");
break;
case CMD_DATA_UNDERRUN: /* let mid layer handle it. */
- printk("UNDERRUN\n");
+ dev_info(&h->pdev->dev, "UNDERRUN\n");
break;
case CMD_DATA_OVERRUN:
- printk(KERN_WARNING "cciss: %p has"
+ dev_warn(&h->pdev->dev, "%p has"
" completed with data overrun "
"reported\n", c);
break;
case CMD_INVALID: {
/* controller unfortunately reports SCSI passthru's */
/* to non-existent targets as invalid commands. */
- printk(KERN_WARNING "cciss: %p is "
- "reported invalid (probably means "
+ dev_warn(&h->pdev->dev,
+ "%p is reported invalid (probably means "
"target device no longer present)\n", c);
/* print_bytes((unsigned char *) c, sizeof(*c), 1, 0);
print_cmd(c); */
}
break;
case CMD_PROTOCOL_ERR:
- printk(KERN_WARNING "cciss: %p has "
- "protocol error\n", c);
+ dev_warn(&h->pdev->dev, "%p has protocol error\n", c);
break;
case CMD_HARDWARE_ERR:
/* cmd->result = DID_ERROR << 16; */
- printk(KERN_WARNING "cciss: %p had "
- " hardware error\n", c);
+ dev_warn(&h->pdev->dev, "%p had hardware error\n", c);
break;
case CMD_CONNECTION_LOST:
- printk(KERN_WARNING "cciss: %p had "
- "connection lost\n", c);
+ dev_warn(&h->pdev->dev, "%p had connection lost\n", c);
break;
case CMD_ABORTED:
- printk(KERN_WARNING "cciss: %p was "
- "aborted\n", c);
+ dev_warn(&h->pdev->dev, "%p was aborted\n", c);
break;
case CMD_ABORT_FAILED:
- printk(KERN_WARNING "cciss: %p reports "
- "abort failed\n", c);
+ dev_warn(&h->pdev->dev,
+ "%p reports abort failed\n", c);
break;
case CMD_UNSOLICITED_ABORT:
- printk(KERN_WARNING "cciss: %p aborted "
- "do to an unsolicited abort\n", c);
+ dev_warn(&h->pdev->dev,
+ "%p aborted due to an unsolicited abort\n", c);
break;
case CMD_TIMEOUT:
- printk(KERN_WARNING "cciss: %p timedout\n", c);
+ dev_warn(&h->pdev->dev, "%p timedout\n", c);
+ break;
+ case CMD_UNABORTABLE:
+ dev_warn(&h->pdev->dev,
+ "%p unabortable\n", c);
break;
default:
- printk(KERN_WARNING "cciss: %p returned "
- "unknown status %x\n", c, ei->CommandStatus);
+ dev_warn(&h->pdev->dev,
+ "%p returned unknown status %x\n",
+ c, ei->CommandStatus);
}
}
if (ei->CommandStatus != 0 &&
ei->CommandStatus != CMD_DATA_UNDERRUN) {
- cciss_scsi_interpret_error(c);
+ cciss_scsi_interpret_error(h, c);
rc = -1;
}
spin_lock_irqsave(&h->lock, flags);
ei = c->err_info;
if (ei->CommandStatus != 0 &&
ei->CommandStatus != CMD_DATA_UNDERRUN) {
- cciss_scsi_interpret_error(c);
+ cciss_scsi_interpret_error(h, c);
rc = -1;
}
spin_lock_irqsave(&h->lock, flags);
/* track how many SG entries we are using */
if (request_nsgs > h->maxSG)
h->maxSG = request_nsgs;
- c->Header.SGTotal = (__u8) request_nsgs + chained;
+ c->Header.SGTotal = (u16) request_nsgs + chained;
if (request_nsgs > h->max_cmd_sgentries)
c->Header.SGList = h->max_cmd_sgentries;
else
static int
-cciss_scsi_queue_command (struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
+cciss_scsi_queue_command_lck(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
{
ctlr_info_t *h;
int rc;
c = scsi_cmd_alloc(h);
spin_unlock_irqrestore(&h->lock, flags);
if (c == NULL) { /* trouble... */
- printk("scsi_cmd_alloc returned NULL!\n");
+ dev_warn(&h->pdev->dev, "scsi_cmd_alloc returned NULL!\n");
/* FIXME: next 3 lines are -> BAD! <- */
cmd->result = DID_NO_CONNECT << 16;
done(cmd);
break;
default:
- printk("cciss: unknown data direction: %d\n",
+ dev_warn(&h->pdev->dev, "unknown data direction: %d\n",
cmd->sc_data_direction);
BUG();
break;
return 0;
}
+static DEF_SCSI_QCMD(cciss_scsi_queue_command)
+
static void cciss_unregister_scsi(ctlr_info_t *h)
{
struct cciss_scsi_adapter_data_t *sa;
stk = &sa->cmd_stack;
if (sa->registered) {
- printk(KERN_INFO "cciss%d: SCSI subsystem already engaged.\n",
- h->ctlr);
+ dev_info(&h->pdev->dev, "SCSI subsystem already engaged.\n");
spin_unlock_irqrestore(&h->lock, flags);
return -ENXIO;
}
c = cmd_alloc(h);
if (!c) {
- printk(KERN_WARNING "cciss%d: out of memory in "
- "wait_for_device_to_become_ready.\n", h->ctlr);
+ dev_warn(&h->pdev->dev, "out of memory in "
+ "wait_for_device_to_become_ready.\n");
return IO_ERROR;
}
}
}
retry_tur:
- printk(KERN_WARNING "cciss%d: Waiting %d secs "
+ dev_warn(&h->pdev->dev, "Waiting %d secs "
"for device to become ready.\n",
- h->ctlr, waittime / HZ);
+ waittime / HZ);
rc = 1; /* device not ready. */
}
if (rc)
- printk("cciss%d: giving up on device.\n", h->ctlr);
+ dev_warn(&h->pdev->dev, "giving up on device.\n");
else
- printk(KERN_WARNING "cciss%d: device is ready.\n", h->ctlr);
+ dev_warn(&h->pdev->dev, "device is ready.\n");
cmd_free(h, c);
return rc;
h = (ctlr_info_t *) scsicmd->device->host->hostdata[0];
if (h == NULL) /* paranoia */
return FAILED;
- printk(KERN_WARNING
- "cciss%d: resetting tape drive or medium changer.\n", h->ctlr);
+ dev_warn(&h->pdev->dev, "resetting tape drive or medium changer.\n");
/* find the command that's giving us trouble */
cmd_in_trouble = (CommandList_struct *) scsicmd->host_scribble;
if (cmd_in_trouble == NULL) /* paranoia */
TYPE_MSG);
if (rc == 0 && wait_for_device_to_become_ready(h, lunaddr) == 0)
return SUCCESS;
- printk(KERN_WARNING "cciss%d: resetting device failed.\n", h->ctlr);
+ dev_warn(&h->pdev->dev, "resetting device failed.\n");
return FAILED;
}
h = (ctlr_info_t *) scsicmd->device->host->hostdata[0];
if (h == NULL) /* paranoia */
return FAILED;
- printk(KERN_WARNING "cciss%d: aborting tardy SCSI cmd\n", h->ctlr);
+ dev_warn(&h->pdev->dev, "aborting tardy SCSI cmd\n");
/* find the command to be aborted */
cmd_to_abort = (CommandList_struct *) scsicmd->host_scribble;
/* If no tape support, then these become defined out of existence */
#define cciss_scsi_setup(cntl_num)
+#define cciss_engage_scsi(h)
#endif /* CONFIG_CISS_SCSI_TAPE */