diff options
Diffstat (limited to 'drivers')
132 files changed, 1665 insertions, 5048 deletions
diff --git a/drivers/block/acsi.c b/drivers/block/acsi.c index 0e1f34fef0c..5d2d649f7e8 100644 --- a/drivers/block/acsi.c +++ b/drivers/block/acsi.c @@ -58,7 +58,6 @@ #include <linux/slab.h> #include <linux/interrupt.h> #include <scsi/scsi.h> /* for SCSI_IOCTL_GET_IDLUN */ -typedef void Scsi_Device; /* hack to avoid including scsi.h */ #include <scsi/scsi_ioctl.h> #include <linux/hdreg.h> /* for HDIO_GETGEO */ #include <linux/blkpg.h> diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index a97c80b5773..e239a6c2923 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -148,6 +148,7 @@ static struct board_type products[] = { static ctlr_info_t *hba[MAX_CTLR]; static void do_cciss_request(request_queue_t *q); +static irqreturn_t do_cciss_intr(int irq, void *dev_id, struct pt_regs *regs); static int cciss_open(struct inode *inode, struct file *filep); static int cciss_release(struct inode *inode, struct file *filep); static int cciss_ioctl(struct inode *inode, struct file *filep, @@ -1583,6 +1584,24 @@ static int fill_cmd(CommandList_struct *c, __u8 cmd, int ctlr, void *buff, } } else if (cmd_type == TYPE_MSG) { switch (cmd) { + case 0: /* ABORT message */ + c->Request.CDBLen = 12; + c->Request.Type.Attribute = ATTR_SIMPLE; + c->Request.Type.Direction = XFER_WRITE; + c->Request.Timeout = 0; + c->Request.CDB[0] = cmd; /* abort */ + c->Request.CDB[1] = 0; /* abort a command */ + /* buff contains the tag of the command to abort */ + memcpy(&c->Request.CDB[4], buff, 8); + break; + case 1: /* RESET message */ + c->Request.CDBLen = 12; + c->Request.Type.Attribute = ATTR_SIMPLE; + c->Request.Type.Direction = XFER_WRITE; + c->Request.Timeout = 0; + memset(&c->Request.CDB[0], 0, sizeof(c->Request.CDB)); + c->Request.CDB[0] = cmd; /* reset */ + c->Request.CDB[1] = 0x04; /* reset a LUN */ case 3: /* No-Op message */ c->Request.CDBLen = 1; c->Request.Type.Attribute = ATTR_SIMPLE; @@ -1869,6 +1888,52 @@ static unsigned long pollcomplete(int ctlr) /* Invalid address to tell caller we ran out of time */ return 1; } + +static int add_sendcmd_reject(__u8 cmd, int ctlr, unsigned long complete) +{ + /* We get in here if sendcmd() is polling for completions + and gets some command back that it wasn't expecting -- + something other than that which it just sent down. + Ordinarily, that shouldn't happen, but it can happen when + the scsi tape stuff gets into error handling mode, and + starts using sendcmd() to try to abort commands and + reset tape drives. In that case, sendcmd may pick up + completions of commands that were sent to logical drives + through the block i/o system, or cciss ioctls completing, etc. + In that case, we need to save those completions for later + processing by the interrupt handler. + */ + +#ifdef CONFIG_CISS_SCSI_TAPE + struct sendcmd_reject_list *srl = &hba[ctlr]->scsi_rejects; + + /* If it's not the scsi tape stuff doing error handling, (abort */ + /* or reset) then we don't expect anything weird. */ + if (cmd != CCISS_RESET_MSG && cmd != CCISS_ABORT_MSG) { +#endif + printk( KERN_WARNING "cciss cciss%d: SendCmd " + "Invalid command list address returned! (%lx)\n", + ctlr, complete); + /* not much we can do. */ +#ifdef CONFIG_CISS_SCSI_TAPE + return 1; + } + + /* We've sent down an abort or reset, but som |