aboutsummaryrefslogtreecommitdiff
path: root/drivers/scsi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/hptiop.c568
-rw-r--r--drivers/scsi/iscsi_tcp.c209
-rw-r--r--drivers/scsi/iscsi_tcp.h2
-rw-r--r--drivers/scsi/libiscsi.c214
-rw-r--r--drivers/scsi/lpfc/lpfc_attr.c101
-rw-r--r--drivers/scsi/lpfc/lpfc_crtn.h1
-rw-r--r--drivers/scsi/lpfc/lpfc_ct.c13
-rw-r--r--drivers/scsi/lpfc/lpfc_els.c21
-rw-r--r--drivers/scsi/lpfc/lpfc_hbadisc.c15
-rw-r--r--drivers/scsi/lpfc/lpfc_init.c13
-rw-r--r--drivers/scsi/lpfc/lpfc_mbox.c16
-rw-r--r--drivers/scsi/lpfc/lpfc_nportdisc.c24
-rw-r--r--drivers/scsi/lpfc/lpfc_scsi.c21
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c57
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.h20
-rw-r--r--drivers/scsi/lpfc/lpfc_version.h2
-rw-r--r--drivers/scsi/megaraid/mega_common.h6
-rw-r--r--drivers/scsi/megaraid/megaraid_ioctl.h4
-rw-r--r--drivers/scsi/megaraid/megaraid_mbox.c42
-rw-r--r--drivers/scsi/megaraid/megaraid_mbox.h4
-rw-r--r--drivers/scsi/megaraid/megaraid_mm.c2
-rw-r--r--drivers/scsi/megaraid/megaraid_mm.h4
-rw-r--r--drivers/scsi/qla2xxx/qla_def.h1
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c11
-rw-r--r--drivers/scsi/qla2xxx/qla_iocb.c1
-rw-r--r--drivers/scsi/qla2xxx/qla_isr.c5
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c15
-rw-r--r--drivers/scsi/qla2xxx/qla_version.h4
-rw-r--r--drivers/scsi/scsi_error.c18
-rw-r--r--drivers/scsi/scsi_transport_iscsi.c15
-rw-r--r--drivers/scsi/sg.c8
-rw-r--r--drivers/scsi/sym53c8xx_2/sym_glue.c2
32 files changed, 551 insertions, 888 deletions
diff --git a/drivers/scsi/hptiop.c b/drivers/scsi/hptiop.c
index ab2f8b26790..bcb3444f1dc 100644
--- a/drivers/scsi/hptiop.c
+++ b/drivers/scsi/hptiop.c
@@ -45,10 +45,6 @@ static char driver_name[] = "hptiop";
static const char driver_name_long[] = "RocketRAID 3xxx SATA Controller driver";
static const char driver_ver[] = "v1.0 (060426)";
-static DEFINE_SPINLOCK(hptiop_hba_list_lock);
-static LIST_HEAD(hptiop_hba_list);
-static int hptiop_cdev_major = -1;
-
static void hptiop_host_request_callback(struct hptiop_hba *hba, u32 tag);
static void hptiop_iop_request_callback(struct hptiop_hba *hba, u32 tag);
static void hptiop_message_callback(struct hptiop_hba *hba, u32 msg);
@@ -577,7 +573,7 @@ static int hptiop_reset_hba(struct hptiop_hba *hba)
if (atomic_xchg(&hba->resetting, 1) == 0) {
atomic_inc(&hba->reset_count);
writel(IOPMU_INBOUND_MSG0_RESET,
- &hba->iop->outbound_msgaddr0);
+ &hba->iop->inbound_msgaddr0);
hptiop_pci_posting_flush(hba->iop);
}
@@ -620,532 +616,11 @@ static int hptiop_adjust_disk_queue_depth(struct scsi_device *sdev,
return queue_depth;
}
-struct hptiop_getinfo {
- char __user *buffer;
- loff_t buflength;
- loff_t bufoffset;
- loff_t buffillen;
- loff_t filpos;
-};
-
-static void hptiop_copy_mem_info(struct hptiop_getinfo *pinfo,
- char *data, int datalen)
-{
- if (pinfo->filpos < pinfo->bufoffset) {
- if (pinfo->filpos + datalen <= pinfo->bufoffset) {
- pinfo->filpos += datalen;
- return;
- } else {
- data += (pinfo->bufoffset - pinfo->filpos);
- datalen -= (pinfo->bufoffset - pinfo->filpos);
- pinfo->filpos = pinfo->bufoffset;
- }
- }
-
- pinfo->filpos += datalen;
- if (pinfo->buffillen == pinfo->buflength)
- return;
-
- if (pinfo->buflength - pinfo->buffillen < datalen)
- datalen = pinfo->buflength - pinfo->buffillen;
-
- if (copy_to_user(pinfo->buffer + pinfo->buffillen, data, datalen))
- return;
-
- pinfo->buffillen += datalen;
-}
-
-static int hptiop_copy_info(struct hptiop_getinfo *pinfo, char *fmt, ...)
-{
- va_list args;
- char buf[128];
- int len;
-
- va_start(args, fmt);
- len = vsnprintf(buf, sizeof(buf), fmt, args);
- va_end(args);
- hptiop_copy_mem_info(pinfo, buf, len);
- return len;
-}
-
-static void hptiop_ioctl_done(struct hpt_ioctl_k *arg)
-{
- arg->done = NULL;
- wake_up(&arg->hba->ioctl_wq);
-}
-
-static void hptiop_do_ioctl(struct hpt_ioctl_k *arg)
-{
- struct hptiop_hba *hba = arg->hba;
- u32 val;
- struct hpt_iop_request_ioctl_command __iomem *req;
- int ioctl_retry = 0;
-
- dprintk("scsi%d: hptiop_do_ioctl\n", hba->host->host_no);
-
- /*
- * check (in + out) buff size from application.
- * outbuf must be dword aligned.
- */
- if (((arg->inbuf_size + 3) & ~3) + arg->outbuf_size >
- hba->max_request_size
- - sizeof(struct hpt_iop_request_header)
- - 4 * sizeof(u32)) {
- dprintk("scsi%d: ioctl buf size (%d/%d) is too large\n",
- hba->host->host_no,
- arg->inbuf_size, arg->outbuf_size);
- arg->result = HPT_IOCTL_RESULT_FAILED;
- return;
- }
-
-retry:
- spin_lock_irq(hba->host->host_lock);
-
- val = readl(&hba->iop->inbound_queue);
- if (val == IOPMU_QUEUE_EMPTY) {
- spin_unlock_irq(hba->host->host_lock);
- dprintk("scsi%d: no free req for ioctl\n", hba->host->host_no);
- arg->result = -1;
- return;
- }
-
- req = (struct hpt_iop_request_ioctl_command __iomem *)
- ((unsigned long)hba->iop + val);
-
- writel(HPT_CTL_CODE_LINUX_TO_IOP(arg->ioctl_code),
- &req->ioctl_code);
- writel(arg->inbuf_size, &req->inbuf_size);
- writel(arg->outbuf_size, &req->outbuf_size);
-
- /*
- * use the buffer on the IOP local memory first, then copy it
- * back to host.
- * the caller's request buffer shoudl be little-endian.
- */
- if (arg->inbuf_size)
- memcpy_toio(req->buf, arg->inbuf, arg->inbuf_size);
-
- /* correct the controller ID for IOP */
- if ((arg->ioctl_code == HPT_IOCTL_GET_CHANNEL_INFO ||
- arg->ioctl_code == HPT_IOCTL_GET_CONTROLLER_INFO_V2 ||
- arg->ioctl_code == HPT_IOCTL_GET_CONTROLLER_INFO)
- && arg->inbuf_size >= sizeof(u32))
- writel(0, req->buf);
-
- writel(IOP_REQUEST_TYPE_IOCTL_COMMAND, &req->header.type);
- writel(0, &req->header.flags);
- writel(offsetof(struct hpt_iop_request_ioctl_command, buf)
- + arg->inbuf_size, &req->header.size);
- writel((u32)(unsigned long)arg, &req->header.context);
- writel(BITS_PER_LONG > 32 ? (u32)((unsigned long)arg>>32) : 0,
- &req->header.context_hi32);
- writel(IOP_RESULT_PENDING, &req->header.result);
-
- arg->result = HPT_IOCTL_RESULT_FAILED;
- arg->done = hptiop_ioctl_done;
-
- writel(val, &hba->iop->inbound_queue);
- hptiop_pci_posting_flush(hba->iop);
-
- spin_unlock_irq(hba->host->host_lock);
-
- wait_event_timeout(hba->ioctl_wq, arg->done == NULL, 60 * HZ);
-
- if (arg->done != NULL) {
- hptiop_reset_hba(hba);
- if (ioctl_retry++ < 3)
- goto retry;
- }
-
- dprintk("hpt_iop_ioctl %x result %d\n",
- arg->ioctl_code, arg->result);
-}
-
-static int __hpt_do_ioctl(struct hptiop_hba *hba, u32 code, void *inbuf,
- u32 insize, void *outbuf, u32 outsize)
-{
- struct hpt_ioctl_k arg;
- arg.hba = hba;
- arg.ioctl_code = code;
- arg.inbuf = inbuf;
- arg.outbuf = outbuf;
- arg.inbuf_size = insize;
- arg.outbuf_size = outsize;
- arg.bytes_returned = NULL;
- hptiop_do_ioctl(&arg);
- return arg.result;
-}
-
-static inline int hpt_id_valid(__le32 id)
-{
- return id != 0 && id != cpu_to_le32(0xffffffff);
-}
-
-static int hptiop_get_controller_info(struct hptiop_hba *hba,
- struct hpt_controller_info *pinfo)
-{
- int id = 0;
-
- return __hpt_do_ioctl(hba, HPT_IOCTL_GET_CONTROLLER_INFO,
- &id, sizeof(int), pinfo, sizeof(*pinfo));
-}
-
-
-static int hptiop_get_channel_info(struct hptiop_hba *hba, int bus,
- struct hpt_channel_info *pinfo)
-{
- u32 ids[2];
-
- ids[0] = 0;
- ids[1] = bus;
- return __hpt_do_ioctl(hba, HPT_IOCTL_GET_CHANNEL_INFO,
- ids, sizeof(ids), pinfo, sizeof(*pinfo));
-
-}
-
-static int hptiop_get_logical_devices(struct hptiop_hba *hba,
- __le32 *pids, int maxcount)
-{
- int i;
- u32 count = maxcount - 1;
-
- if (__hpt_do_ioctl(hba, HPT_IOCTL_GET_LOGICAL_DEVICES,
- &count, sizeof(u32),
- pids, sizeof(u32) * maxcount))
- return -1;
-
- maxcount = le32_to_cpu(pids[0]);
- for (i = 0; i < maxcount; i++)
- pids[i] = pids[i+1];
-
- return maxcount;
-}
-
-static int hptiop_get_device_info_v3(struct hptiop_hba *hba, __le32 id,
- struct hpt_logical_device_info_v3 *pinfo)
-{
- return __hpt_do_ioctl(hba, HPT_IOCTL_GET_DEVICE_INFO_V3,
- &id, sizeof(u32),
- pinfo, sizeof(*pinfo));
-}
-
-static const char *get_array_status(struct hpt_logical_device_info_v3 *devinfo)
-{
- static char s[64];
- u32 flags = le32_to_cpu(devinfo->u.array.flags);
- u32 trans_prog = le32_to_cpu(devinfo->u.array.transforming_progress);
- u32 reb_prog = le32_to_cpu(devinfo->u.array.rebuilding_progress);
-
- if (flags & ARRAY_FLAG_DISABLED)
- return "Disabled";
- else if (flags & ARRAY_FLAG_TRANSFORMING)
- sprintf(s, "Expanding/Migrating %d.%d%%%s%s",
- trans_prog / 100,
- trans_prog % 100,
- (flags & (ARRAY_FLAG_NEEDBUILDING|ARRAY_FLAG_BROKEN))?
- ", Critical" : "",
- ((flags & ARRAY_FLAG_NEEDINITIALIZING) &&
- !(flags & ARRAY_FLAG_REBUILDING) &&
- !(flags & ARRAY_FLAG_INITIALIZING))?
- ", Unintialized" : "");
- else if ((flags & ARRAY_FLAG_BROKEN) &&
- devinfo->u.array.array_type != AT_RAID6)
- return "Critical";
- else if (flags & ARRAY_FLAG_REBUILDING)
- sprintf(s,
- (flags & ARRAY_FLAG_NEEDINITIALIZING)?
- "%sBackground initializing %d.%d%%" :
- "%sRebuilding %d.%d%%",
- (flags & ARRAY_FLAG_BROKEN)? "Critical, " : "",
- reb_prog / 100,
- reb_prog % 100);
- else if (flags & ARRAY_FLAG_VERIFYING)
- sprintf(s, "%sVerifying %d.%d%%",
- (flags & ARRAY_FLAG_BROKEN)? "Critical, " : "",
- reb_prog / 100,
- reb_prog % 100);
- else if (flags & ARRAY_FLAG_INITIALIZING)
- sprintf(s, "%sForground initializing %d.%d%%",
- (flags & ARRAY_FLAG_BROKEN)? "Critical, " : "",
- reb_prog / 100,
- reb_prog % 100);
- else if (flags & ARRAY_FLAG_NEEDTRANSFORM)
- sprintf(s,"%s%s%s", "Need Expanding/Migrating",
- (flags & ARRAY_FLAG_BROKEN)? "Critical, " : "",
- ((flags & ARRAY_FLAG_NEEDINITIALIZING) &&
- !(flags & ARRAY_FLAG_REBUILDING) &&
- !(flags & ARRAY_FLAG_INITIALIZING))?
- ", Unintialized" : "");
- else if (flags & ARRAY_FLAG_NEEDINITIALIZING &&
- !(flags & ARRAY_FLAG_REBUILDING) &&
- !(flags & ARRAY_FLAG_INITIALIZING))
- sprintf(s,"%sUninitialized",
- (flags & ARRAY_FLAG_BROKEN)? "Critical, " : "");
- else if ((flags & ARRAY_FLAG_NEEDBUILDING) ||
- (flags & ARRAY_FLAG_BROKEN))
- return "Critical";
- else
- return "Normal";
- return s;
-}
-
-static void hptiop_dump_devinfo(struct hptiop_hba *hba,
- struct hptiop_getinfo *pinfo, __le32 id, int indent)
-{
- struct hpt_logical_device_info_v3 devinfo;
- int i;
- u64 capacity;
-
- for (i = 0; i < indent; i++)
- hptiop_copy_info(pinfo, "\t");
-
- if (hptiop_get_device_info_v3(hba, id, &devinfo)) {
- hptiop_copy_info(pinfo, "unknown\n");
- return;
- }
-
- switch (devinfo.type) {
-
- case LDT_DEVICE: {
- struct hd_driveid *driveid;
- u32 flags = le32_to_cpu(devinfo.u.device.flags);
-
- driveid = (struct hd_driveid *)devinfo.u.device.ident;
- /* model[] is 40 chars long, but we just want 20 chars here */
- driveid->model[20] = 0;
-
- if (indent)
- if (flags & DEVICE_FLAG_DISABLED)
- hptiop_copy_info(pinfo,"Missing\n");
- else
- hptiop_copy_info(pinfo, "CH%d %s\n",
- devinfo.u.device.path_id + 1,
- driveid->model);
- else {
- capacity = le64_to_cpu(devinfo.capacity) * 512;
- do_div(capacity, 1000000);
- hptiop_copy_info(pinfo,
- "CH%d %s, %lluMB, %s %s%s%s%s\n",
- devinfo.u.device.path_id + 1,
- driveid->model,
- capacity,
- (flags & DEVICE_FLAG_DISABLED)?
- "Disabled" : "Normal",
- devinfo.u.device.read_ahead_enabled?
- "[RA]" : "",
- devinfo.u.device.write_cache_enabled?
- "[WC]" : "",
- devinfo.u.device.TCQ_enabled?
- "[TCQ]" : "",
- devinfo.u.device.NCQ_enabled?
- "[NCQ]" : ""
- );
- }
- break;
- }
-
- case LDT_ARRAY:
- if (devinfo.target_id != INVALID_TARGET_ID)
- hptiop_copy_info(pinfo, "[DISK %d_%d] ",
- devinfo.vbus_id, devinfo.target_id);
-
- capacity = le64_to_cpu(devinfo.capacity) * 512;
- do_div(capacity, 1000000);
- hptiop_copy_info(pinfo, "%s (%s), %lluMB, %s\n",
- devinfo.u.array.name,
- devinfo.u.array.array_type==AT_RAID0? "RAID0" :
- devinfo.u.array.array_type==AT_RAID1? "RAID1" :
- devinfo.u.array.array_type==AT_RAID5? "RAID5" :
- devinfo.u.array.array_type==AT_RAID6? "RAID6" :
- devinfo.u.array.array_type==AT_JBOD? "JBOD" :
- "unknown",
- capacity,
- get_array_status(&devinfo));
- for (i = 0; i < devinfo.u.array.ndisk; i++) {
- if (hpt_id_valid(devinfo.u.array.members[i])) {
- if (cpu_to_le16(1<<i) &
- devinfo.u.array.critical_members)
- hptiop_copy_info(pinfo, "\t*");
- hptiop_dump_devinfo(hba, pinfo,
- devinfo.u.array.members[i], indent+1);
- }
- else
- hptiop_copy_info(pinfo, "\tMissing\n");
- }
- if (id == devinfo.u.array.transform_source) {
- hptiop_copy_info(pinfo, "\tExpanding/Migrating to:\n");
- hptiop_dump_devinfo(hba, pinfo,
- devinfo.u.array.transform_target, indent+1);
- }
- break;
- }
-}
-
static ssize_t hptiop_show_version(struct class_device *class_dev, char *buf)
{
return snprintf(buf, PAGE_SIZE, "%s\n", driver_ver);
}
-static ssize_t hptiop_cdev_read(struct file *filp, char __user *buf,
- size_t count, loff_t *ppos)
-{
- struct hptiop_hba *hba = filp->private_data;
- struct hptiop_getinfo info;
- int i, j, ndev;
- struct hpt_controller_info con_info;
- struct hpt_channel_info chan_info;
- __le32 ids[32];
-
- info.buffer = buf;
- info.buflength = count;
- info.bufoffset = ppos ? *ppos : 0;
- info.filpos = 0;
- info.buffillen = 0;
-
- if (hptiop_get_controller_info(hba, &con_info))
- return -EIO;
-
- for (i = 0; i < con_info.num_buses; i++) {
- if (hptiop_get_channel_info(hba, i, &chan_info) == 0) {
- if (hpt_id_valid(chan_info.devices[0]))
- hptiop_dump_devinfo(hba, &info,
- chan_info.devices[0], 0);
- if (hpt_id_valid(chan_info.devices[1]))
- hptiop_dump_devinfo(hba, &info,
- chan_info.devices[1], 0);
- }
- }
-
- ndev = hptiop_get_logical_devices(hba, ids,
- sizeof(ids) / sizeof(ids[0]));
-
- /*
- * if hptiop_get_logical_devices fails, ndev==-1 and it just
- * output nothing here
- */
- for (j = 0; j < ndev; j++)
- hptiop_dump_devinfo(hba, &info, ids[j], 0);
-
- if (ppos)
- *ppos += info.buffillen;
-
- return info.buffillen;
-}
-
-static int hptiop_cdev_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
-{
- struct hptiop_hba *hba = file->private_data;
- struct hpt_ioctl_u ioctl_u;
- struct hpt_ioctl_k ioctl_k;
- u32 bytes_returned;
- int err = -EINVAL;
-
- if (copy_from_user(&ioctl_u,
- (void __user *)arg, sizeof(struct hpt_ioctl_u)))
- return -EINVAL;
-
- if (ioctl_u.magic != HPT_IOCTL_MAGIC)
- return -EINVAL;
-
- ioctl_k.ioctl_code = ioctl_u.ioctl_code;
- ioctl_k.inbuf = NULL;
- ioctl_k.inbuf_size = ioctl_u.inbuf_size;
- ioctl_k.outbuf = NULL;
- ioctl_k.outbuf_size = ioctl_u.outbuf_size;
- ioctl_k.hba = hba;
- ioctl_k.bytes_returned = &bytes_returned;
-
- /* verify user buffer */
- if ((ioctl_k.inbuf_size && !access_ok(VERIFY_READ,
- ioctl_u.inbuf, ioctl_k.inbuf_size)) ||
- (ioctl_k.outbuf_size && !access_ok(VERIFY_WRITE,
- ioctl_u.outbuf, ioctl_k.outbuf_size)) ||
- (ioctl_u.bytes_returned && !access_ok(VERIFY_WRITE,
- ioctl_u.bytes_returned, sizeof(u32))) ||
- ioctl_k.inbuf_size + ioctl_k.outbuf_size > 0x10000) {
-
- dprintk("scsi%d: got bad user address\n", hba->host->host_no);
- return -EINVAL;
- }
-
- /* map buffer to kernel. */
- if (ioctl_k.inbuf_size) {
- ioctl_k.inbuf = kmalloc(ioctl_k.inbuf_size, GFP_KERNEL);
- if (!ioctl_k.inbuf) {
- dprintk("scsi%d: fail to alloc inbuf\n",
- hba->host->host_no);
- err = -ENOMEM;
- goto err_exit;
- }
-
- if (copy_from_user(ioctl_k.inbuf,
- ioctl_u.inbuf, ioctl_k.inbuf_size)) {
- goto err_exit;
- }
- }
-
- if (ioctl_k.outbuf_size) {
- ioctl_k.outbuf = kmalloc(ioctl_k.outbuf_size, GFP_KERNEL);
- if (!ioctl_k.outbuf) {
- dprintk("scsi%d: fail to alloc outbuf\n",
- hba->host->host_no);
- err = -ENOMEM;
- goto err_exit;
- }
- }
-
- hptiop_do_ioctl(&ioctl_k);
-
- if (ioctl_k.result == HPT_IOCTL_RESULT_OK) {
- if (ioctl_k.outbuf_size &&
- copy_to_user(ioctl_u.outbuf,
- ioctl_k.outbuf, ioctl_k.outbuf_size))
- goto err_exit;
-
- if (ioctl_u.bytes_returned &&
- copy_to_user(ioctl_u.bytes_returned,
- &bytes_returned, sizeof(u32)))
- goto err_exit;
-
- err = 0;
- }
-
-err_exit:
- kfree(ioctl_k.inbuf);
- kfree(ioctl_k.outbuf);
-
- return err;
-}
-
-static int hptiop_cdev_open(struct inode *inode, struct file *file)
-{
- struct hptiop_hba *hba;
- unsigned i = 0, minor = iminor(inode);
- int ret = -ENODEV;
-
- spin_lock(&hptiop_hba_list_lock);
- list_for_each_entry(hba, &hptiop_hba_list, link) {
- if (i == minor) {
- file->private_data = hba;
- ret = 0;
- goto out;
- }
- i++;
- }
-
-out:
- spin_unlock(&hptiop_hba_list_lock);
- return ret;
-}
-
-static struct file_operations hptiop_cdev_fops = {
- .owner = THIS_MODULE,
- .read = hptiop_cdev_read,
- .ioctl = hptiop_cdev_ioctl,
- .open = hptiop_cdev_open,
-};
-
static ssize_t hptiop_show_fw_version(struct class_device *class_dev, char *buf)
{
struct Scsi_Host *host = class_to_shost(class_dev);
@@ -1296,19 +771,13 @@ static int __devinit hptiop_probe(struct pci_dev *pcidev,
goto unmap_pci_bar;
}
- if (scsi_add_host(host, &pcidev->dev)) {
- printk(KERN_ERR "scsi%d: scsi_add_host failed\n",
- hba->host->host_no);
- goto unmap_pci_bar;
- }
-
pci_set_drvdata(pcidev, host);
if (request_irq(pcidev->irq, hptiop_intr, IRQF_SHARED,
driver_name, hba)) {
printk(KERN_ERR "scsi%d: request irq %d failed\n",
hba->host->host_no, pcidev->irq);
- goto remove_scsi_host;
+ goto unmap_pci_bar;
}
/* Allocate request mem */
@@ -1355,9 +824,12 @@ static int __devinit hptiop_probe(struct pci_dev *pcidev,
if (hptiop_initialize_iop(hba))
goto free_request_mem;
- spin_lock(&hptiop_hba_list_lock);
- list_add_tail(&hba->link, &hptiop_hba_list);
- spin_unlock(&hptiop_hba_list_lock);
+ if (scsi_add_host(host, &pcidev->dev)) {
+ printk(KERN_ERR "scsi%d: scsi_add_host failed\n",
+ hba->host->host_no);
+ goto free_request_mem;
+ }
+
scsi_scan_host(host);
@@ -1372,9 +844,6 @@ free_request_mem:
free_request_irq:
free_irq(hba->pcidev->irq, hba);
-remove_scsi_host:
- scsi_remove_host(host);
-
unmap_pci_bar:
iounmap(hba->iop);
@@ -1422,10 +891,6 @@ static void hptiop_remove(struct pci_dev *pcidev)
scsi_remove_host(host);
- spin_lock(&hptiop_hba_list_lock);
- list_del_init(&hba->link);
- spin_unlock(&hptiop_hba_list_lock);
-
hptiop_shutdown(pcidev);
free_irq(hba->pcidev->irq, hba);
@@ -1462,27 +927,12 @@ static struct pci_driver hptiop_pci_driver = {
static int __init hptiop_module_init(void)
{
- int error;
-
printk(KERN_INFO "%s %s\n", driver_name_long, driver_ver);
-
- error = pci_register_driver(&hptiop_pci_driver);
- if (error < 0)
- return error;
-
- hptiop_cdev_major = register_chrdev(0, "hptiop", &hptiop_cdev_fops);
- if (hptiop_cdev_major < 0) {
- printk(KERN_WARNING "unable to register hptiop device.\n");
- return hptiop_cdev_major;
- }
-
- return 0;
+ return pci_register_driver(&hptiop_pci_driver);
}
static void __exit hptiop_module_exit(void)
{
- dprintk("hptiop_module_exit\n");
- unregister_chrdev(hptiop_cdev_major, "hptiop");
pci_unregister_driver(&hptiop_pci_driver);
}
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index 848fb2aa4ca..058f094f945 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -43,13 +43,10 @@
#include "iscsi_tcp.h"
-#define ISCSI_TCP_VERSION "1.0-595"
-
MODULE_AUTHOR("Dmitry Yusupov <dmitry_yus@yahoo.com>, "
"Alex Aizman <itn780@yahoo.com>");
MODULE_DESCRIPTION("iSCSI/TCP data-path");
MODULE_LICENSE("GPL");
-MODULE_VERSION(ISCSI_TCP_VERSION);
/* #define DEBUG_TCP */
#define DEBUG_ASSERT
@@ -185,11 +182,19 @@ iscsi_hdr_extract(struct iscsi_tcp_conn *tcp_conn)
* must be called with session lock
*/
static void
-__iscsi_ctask_cleanup(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
+iscsi_tcp_cleanup_ctask(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
{
struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
+ struct iscsi_r2t_info *r2t;
struct scsi_cmnd *sc;
+ /* flush ctask's r2t queues */
+ while (__kfifo_get(tcp_ctask->r2tqueue, (void*)&r2t, sizeof(void*))) {
+ __kfifo_put(tcp_ctask->r2tpool.queue, (void*)&r2t,
+ sizeof(void*));
+ debug_scsi("iscsi_tcp_cleanup_ctask pending r2t dropped\n");
+ }
+
sc = ctask->sc;
if (unlikely(!sc))
return;
@@ -374,6 +379,7 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
spin_unlock(&session->lock);
return 0;
}
+
rc = __kfifo_get(tcp_ctask->r2tpool.queue, (void*)&r2t, sizeof(void*));
BUG_ON(!rc);
@@ -399,7 +405,7 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
tcp_ctask->exp_r2tsn = r2tsn + 1;
tcp_ctask->xmstate |= XMSTATE_SOL_HDR;
__kfifo_put(tcp_ctask->r2tqueue, (void*)&r2t, sizeof(void*));
- __kfifo_put(conn->xmitqueue, (void*)&ctask, sizeof(void*));
+ list_move_tail(&ctask->running, &conn->xmitqueue);
scsi_queue_work(session->host, &conn->xmitwork);
conn->r2t_pdus_cnt++;
@@ -477,6 +483,8 @@ iscsi_tcp_hdr_recv(struct iscsi_conn *conn)
case ISCSI_OP_SCSI_DATA_IN:
tcp_conn->in.ctask = session->cmds[itt];
rc = iscsi_data_rsp(conn, tcp_conn->in.ctask);
+ if (rc)
+ return rc;
/* fall through */
case ISCSI_OP_SCSI_CMD_RSP:
tcp_conn->in.ctask = session->cmds[itt];
@@ -484,7 +492,7 @@ iscsi_tcp_hdr_recv(struct iscsi_conn *conn)
goto copy_hdr;
spin_lock(&session->lock);
- __iscsi_ctask_cleanup(conn, tcp_conn->in.ctask);
+ iscsi_tcp_cleanup_ctask(conn, tcp_conn->in.ctask);
rc = __iscsi_complete_pdu(conn, hdr, NULL, 0);
spin_unlock(&session->lock);
break;
@@ -500,13 +508,28 @@ iscsi_tcp_hdr_recv(struct iscsi_conn *conn)
break;
case ISCSI_OP_LOGIN_RSP:
case ISCSI_OP_TEXT_RSP:
- case ISCSI_OP_LOGOUT_RSP:
- case ISCSI_OP_NOOP_IN:
case ISCSI_OP_REJECT:
case ISCSI_OP_ASYNC_EVENT:
+ /*
+ * It is possible that we could get a PDU with a buffer larger
+ * than 8K, but there are no targets that currently do this.
+ * For now we fail until we find a vendor that needs it
+ */
+ if (DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH <
+ tcp_conn->in.datalen) {
+ printk(KERN_ERR "iscsi_tcp: received buffer of len %u "
+ "but conn buffer is only %u (opcode %0x)\n",
+ tcp_conn->in.datalen,
+ DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH, opcode);
+ rc = ISCSI_ERR_PROTO;
+ break;
+ }
+
if (tcp_conn->in.datalen)
goto copy_hdr;
/* fall through */
+ case ISCSI_OP_LOGOUT_RSP:
+ case ISCSI_OP_NOOP_IN:
case ISCSI_OP_SCSI_TMFUNC_RSP:
rc = iscsi_complete_pdu(conn, hdr, NULL, 0);
break;
@@ -523,7 +546,7 @@ copy_hdr:
* skbs to complete the command then we have to copy the header
* for later use
*/
- if (tcp_conn->in.zero_copy_hdr && tcp_conn->in.copy <
+ if (tcp_conn->in.zero_copy_hdr && tcp_conn->in.copy <=
(tcp_conn->in.datalen + tcp_conn->in.padding +
(conn->datadgst_en ? 4 : 0))) {
debug_tcp("Copying header for later use. in.copy %d in.datalen"
@@ -614,9 +637,9 @@ iscsi_ctask_copy(struct iscsi_tcp_conn *tcp_conn, struct iscsi_cmd_task *ctask,
* byte counters.
**/
static inline int
-iscsi_tcp_copy(struct iscsi_tcp_conn *tcp_conn)
+iscsi_tcp_copy(struct iscsi_conn *conn)
{
- void *buf = tcp_conn->data;
+ struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
int buf_size = tcp_conn->in.datalen;
int buf_left = buf_size - tcp_conn->data_copied;
int size = min(tcp_conn->in.copy, buf_left);
@@ -627,7 +650,7 @@ iscsi_tcp_copy(struct iscsi_tcp_conn *tcp_conn)
BUG_ON(size <= 0);
rc = skb_copy_bits(tcp_conn->in.skb, tcp_conn->in.offset,
- (char*)buf + tcp_conn->data_copied, size);
+ (char*)conn->data + tcp_conn->data_copied, size);
BUG_ON(rc);
tcp_conn->in.offset += size;
@@ -745,10 +768,11 @@ static int iscsi_scsi_data_in(struct iscsi_conn *conn)
done:
/* check for non-exceptional status */
if (tcp_conn->in.hdr->flags & ISCSI_FLAG_DATA_STATUS) {
- debug_scsi("done [sc %lx res %d itt 0x%x]\n",
- (long)sc, sc->result, ctask->itt);
+ debug_scsi("done [sc %lx res %d itt 0x%x flags 0x%x]\n",
+ (long)sc, sc->result, ctask->itt,
+ tcp_conn->in.hdr->flags);
spin_lock(&conn->session->lock);
- __iscsi_ctask_cleanup(conn, ctask);
+ iscsi_tcp_cleanup_ctask(conn, ctask);
__iscsi_complete_pdu(conn, tcp_conn->in.hdr, NULL, 0);
spin_unlock(&conn->session->lock);
}
@@ -769,26 +793,25 @@ iscsi_data_recv(struct iscsi_conn *conn)
break;
case ISCSI_OP_SCSI_CMD_RSP:
spin_lock(&conn->session->lock);
- __iscsi_ctask_cleanup(conn, tcp_conn->in.ctask);
+ iscsi_tcp_cleanup_ctask(conn, tcp_conn->in.ctask);
spin_unlock(&conn->session->lock);
case ISCSI_OP_TEXT_RSP:
case ISCSI_OP_LOGIN_RSP:
- case ISCSI_OP_NOOP_IN:
case ISCSI_OP_ASYNC_EVENT:
case ISCSI_OP_REJECT:
/*
* Collect data segment to the connection's data
* placeholder
*/
- if (iscsi_tcp_copy(tcp_conn)) {
+ if (iscsi_tcp_copy(conn)) {
rc = -EAGAIN;
goto exit;
}
- rc = iscsi_complete_pdu(conn, tcp_conn->in.hdr, tcp_conn->data,
+ rc = iscsi_complete_pdu(conn, tcp_conn->in.hdr, conn->data,
tcp_conn->in.datalen);
if (!rc && conn->datadgst_en && opcode != ISCSI_OP_LOGIN_RSP)
- iscsi_recv_digest_update(tcp_conn, tcp_conn->data,
+ iscsi_recv_digest_update(tcp_conn, conn->data,
tcp_conn->in.datalen);
break;
default:
@@ -843,7 +866,7 @@ more:
if (rc == -EAGAIN)
goto nomore;
else {
- iscsi_conn_failure(conn, rc);
+ iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
return 0;
}
}
@@ -897,7 +920,7 @@ more:
if (rc) {
if (rc == -EAGAIN)
goto again;
- iscsi_conn_failure(conn, rc);
+ iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
return 0;
}
tcp_conn->in.copy -= tcp_conn->in.padding;
@@ -1028,9 +1051,8 @@ iscsi_conn_set_callbacks(struct iscsi_conn *conn)
}
static void
-iscsi_conn_restore_callbacks(struct iscsi_conn *conn)
+iscsi_conn_restore_callbacks(struct iscsi_tcp_conn *tcp_conn)
{
- struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
struct sock *sk = tcp_conn->sock->sk;
/* restore socket callbacks, see also: iscsi_conn_set_callbacks() */
@@ -1308,7 +1330,7 @@ iscsi_tcp_cmd_init(struct iscsi_cmd_task *ctask)
ctask->imm_count -
ctask->unsol_count;
- debug_scsi("cmd [itt %x total %d imm %d imm_data %d "
+ debug_scsi("cmd [itt 0x%x total %d imm %d imm_data %d "
"r2t_data %d]\n",
ctask->itt, ctask->total_length, ctask->imm_count,
ctask->unsol_count, tcp_ctask->r2t_data_count);
@@ -1636,7 +1658,7 @@ handle_xmstate_sol_data(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
}
solicit_again:
/*
- * send Data-Out whitnin this R2T sequence.
+ * send Data-Out within this R2T sequence.
*/
if (!r2t->data_count)
goto data_out_done;
@@ -1731,7 +1753,7 @@ handle_xmstate_w_pad(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
struct iscsi_data_task *dtask = tcp_ctask->dtask;
- int sent, rc;
+ int sent = 0, rc;
tcp_ctask->xmstate &= ~XMSTATE_W_PAD;
iscsi_buf_init_iov(&tcp_ctask->sendbuf, (char*)&tcp_ctask->pad,
@@ -1900,27 +1922,32 @@ iscsi_tcp_conn_create(struct iscsi_cls_session *cls_session, uint32_t conn_idx)
tcp_conn->in_progress = IN_PROGRESS_WAIT_HEADER;
/* initial operational parameters */
tcp_conn->hdr_size = sizeof(struct iscsi_hdr);
- tcp_conn->data_size = DEFAULT_MAX_RECV_DATA_SEG