aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/sata_nv.c30
-rw-r--r--drivers/scsi/scsi.c109
-rw-r--r--drivers/scsi/scsi_lib.c36
-rw-r--r--drivers/scsi/scsi_priv.h1
-rw-r--r--drivers/scsi/sd.c21
5 files changed, 74 insertions, 123 deletions
diff --git a/drivers/scsi/sata_nv.c b/drivers/scsi/sata_nv.c
index c0cf52cb975a..bbbb55eeb73a 100644
--- a/drivers/scsi/sata_nv.c
+++ b/drivers/scsi/sata_nv.c
@@ -29,6 +29,12 @@
29 * NV-specific details such as register offsets, SATA phy location, 29 * NV-specific details such as register offsets, SATA phy location,
30 * hotplug info, etc. 30 * hotplug info, etc.
31 * 31 *
32 * 0.10
33 * - Fixed spurious interrupts issue seen with the Maxtor 6H500F0 500GB
34 * drive. Also made the check_hotplug() callbacks return whether there
35 * was a hotplug interrupt or not. This was not the source of the
36 * spurious interrupts, but is the right thing to do anyway.
37 *
32 * 0.09 38 * 0.09
33 * - Fixed bug introduced by 0.08's MCP51 and MCP55 support. 39 * - Fixed bug introduced by 0.08's MCP51 and MCP55 support.
34 * 40 *
@@ -124,10 +130,10 @@ static void nv_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
124static void nv_host_stop (struct ata_host_set *host_set); 130static void nv_host_stop (struct ata_host_set *host_set);
125static void nv_enable_hotplug(struct ata_probe_ent *probe_ent); 131static void nv_enable_hotplug(struct ata_probe_ent *probe_ent);
126static void nv_disable_hotplug(struct ata_host_set *host_set); 132static void nv_disable_hotplug(struct ata_host_set *host_set);
127static void nv_check_hotplug(struct ata_host_set *host_set); 133static int nv_check_hotplug(struct ata_host_set *host_set);
128static void nv_enable_hotplug_ck804(struct ata_probe_ent *probe_ent); 134static void nv_enable_hotplug_ck804(struct ata_probe_ent *probe_ent);
129static void nv_disable_hotplug_ck804(struct ata_host_set *host_set); 135static void nv_disable_hotplug_ck804(struct ata_host_set *host_set);
130static void nv_check_hotplug_ck804(struct ata_host_set *host_set); 136static int nv_check_hotplug_ck804(struct ata_host_set *host_set);
131 137
132enum nv_host_type 138enum nv_host_type
133{ 139{
@@ -176,7 +182,7 @@ struct nv_host_desc
176 enum nv_host_type host_type; 182 enum nv_host_type host_type;
177 void (*enable_hotplug)(struct ata_probe_ent *probe_ent); 183 void (*enable_hotplug)(struct ata_probe_ent *probe_ent);
178 void (*disable_hotplug)(struct ata_host_set *host_set); 184 void (*disable_hotplug)(struct ata_host_set *host_set);
179 void (*check_hotplug)(struct ata_host_set *host_set); 185 int (*check_hotplug)(struct ata_host_set *host_set);
180 186
181}; 187};
182static struct nv_host_desc nv_device_tbl[] = { 188static struct nv_host_desc nv_device_tbl[] = {
@@ -309,12 +315,16 @@ static irqreturn_t nv_interrupt (int irq, void *dev_instance,
309 qc = ata_qc_from_tag(ap, ap->active_tag); 315 qc = ata_qc_from_tag(ap, ap->active_tag);
310 if (qc && (!(qc->tf.ctl & ATA_NIEN))) 316 if (qc && (!(qc->tf.ctl & ATA_NIEN)))
311 handled += ata_host_intr(ap, qc); 317 handled += ata_host_intr(ap, qc);
318 else
319 // No request pending? Clear interrupt status
320 // anyway, in case there's one pending.
321 ap->ops->check_status(ap);
312 } 322 }
313 323
314 } 324 }
315 325
316 if (host->host_desc->check_hotplug) 326 if (host->host_desc->check_hotplug)
317 host->host_desc->check_hotplug(host_set); 327 handled += host->host_desc->check_hotplug(host_set);
318 328
319 spin_unlock_irqrestore(&host_set->lock, flags); 329 spin_unlock_irqrestore(&host_set->lock, flags);
320 330
@@ -497,7 +507,7 @@ static void nv_disable_hotplug(struct ata_host_set *host_set)
497 outb(intr_mask, host_set->ports[0]->ioaddr.scr_addr + NV_INT_ENABLE); 507 outb(intr_mask, host_set->ports[0]->ioaddr.scr_addr + NV_INT_ENABLE);
498} 508}
499 509
500static void nv_check_hotplug(struct ata_host_set *host_set) 510static int nv_check_hotplug(struct ata_host_set *host_set)
501{ 511{
502 u8 intr_status; 512 u8 intr_status;
503 513
@@ -522,7 +532,11 @@ static void nv_check_hotplug(struct ata_host_set *host_set)
522 if (intr_status & NV_INT_STATUS_SDEV_REMOVED) 532 if (intr_status & NV_INT_STATUS_SDEV_REMOVED)
523 printk(KERN_WARNING "nv_sata: " 533 printk(KERN_WARNING "nv_sata: "
524 "Secondary device removed\n"); 534 "Secondary device removed\n");
535
536 return 1;
525 } 537 }
538
539 return 0;
526} 540}
527 541
528static void nv_enable_hotplug_ck804(struct ata_probe_ent *probe_ent) 542static void nv_enable_hotplug_ck804(struct ata_probe_ent *probe_ent)
@@ -560,7 +574,7 @@ static void nv_disable_hotplug_ck804(struct ata_host_set *host_set)
560 pci_write_config_byte(pdev, NV_MCP_SATA_CFG_20, regval); 574 pci_write_config_byte(pdev, NV_MCP_SATA_CFG_20, regval);
561} 575}
562 576
563static void nv_check_hotplug_ck804(struct ata_host_set *host_set) 577static int nv_check_hotplug_ck804(struct ata_host_set *host_set)
564{ 578{
565 u8 intr_status; 579 u8 intr_status;
566 580
@@ -585,7 +599,11 @@ static void nv_check_hotplug_ck804(struct ata_host_set *host_set)
585 if (intr_status & NV_INT_STATUS_SDEV_REMOVED) 599 if (intr_status & NV_INT_STATUS_SDEV_REMOVED)
586 printk(KERN_WARNING "nv_sata: " 600 printk(KERN_WARNING "nv_sata: "
587 "Secondary device removed\n"); 601 "Secondary device removed\n");
602
603 return 1;
588 } 604 }
605
606 return 0;
589} 607}
590 608
591static int __init nv_init(void) 609static int __init nv_init(void)
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index 180676d7115a..ee5f4dfdab14 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -69,7 +69,6 @@
69#include "scsi_logging.h" 69#include "scsi_logging.h"
70 70
71static void scsi_done(struct scsi_cmnd *cmd); 71static void scsi_done(struct scsi_cmnd *cmd);
72static int scsi_retry_command(struct scsi_cmnd *cmd);
73 72
74/* 73/*
75 * Definitions and constants. 74 * Definitions and constants.
@@ -752,7 +751,7 @@ static void scsi_done(struct scsi_cmnd *cmd)
752 * isn't running --- used by scsi_times_out */ 751 * isn't running --- used by scsi_times_out */
753void __scsi_done(struct scsi_cmnd *cmd) 752void __scsi_done(struct scsi_cmnd *cmd)
754{ 753{
755 unsigned long flags; 754 struct request *rq = cmd->request;
756 755
757 /* 756 /*
758 * Set the serial numbers back to zero 757 * Set the serial numbers back to zero
@@ -763,71 +762,14 @@ void __scsi_done(struct scsi_cmnd *cmd)
763 if (cmd->result) 762 if (cmd->result)
764 atomic_inc(&cmd->device->ioerr_cnt); 763 atomic_inc(&cmd->device->ioerr_cnt);
765 764
765 BUG_ON(!rq);
766
766 /* 767 /*
767 * Next, enqueue the command into the done queue. 768 * The uptodate/nbytes values don't matter, as we allow partial
768 * It is a per-CPU queue, so we just disable local interrupts 769 * completes and thus will check this in the softirq callback
769 * and need no spinlock.
770 */ 770 */
771 local_irq_save(flags); 771 rq->completion_data = cmd;
772 list_add_tail(&cmd->eh_entry, &__get_cpu_var(scsi_done_q)); 772 blk_complete_request(rq);
773 raise_softirq_irqoff(SCSI_SOFTIRQ);
774 local_irq_restore(flags);
775}
776
777/**
778 * scsi_softirq - Perform post-interrupt processing of finished SCSI commands.
779 *
780 * This is the consumer of the done queue.
781 *
782 * This is called with all interrupts enabled. This should reduce
783 * interrupt latency, stack depth, and reentrancy of the low-level
784 * drivers.
785 */
786static void scsi_softirq(struct softirq_action *h)
787{
788 int disposition;
789 LIST_HEAD(local_q);
790
791 local_irq_disable();
792 list_splice_init(&__get_cpu_var(scsi_done_q), &local_q);
793 local_irq_enable();
794
795 while (!list_empty(&local_q)) {
796 struct scsi_cmnd *cmd = list_entry(local_q.next,
797 struct scsi_cmnd, eh_entry);
798 /* The longest time any command should be outstanding is the
799 * per command timeout multiplied by the number of retries.
800 *
801 * For a typical command, this is 2.5 minutes */
802 unsigned long wait_for
803 = cmd->allowed * cmd->timeout_per_command;
804 list_del_init(&cmd->eh_entry);
805
806 disposition = scsi_decide_disposition(cmd);
807 if (disposition != SUCCESS &&
808 time_before(cmd->jiffies_at_alloc + wait_for, jiffies)) {
809 sdev_printk(KERN_ERR, cmd->device,
810 "timing out command, waited %lus\n",
811 wait_for/HZ);
812 disposition = SUCCESS;
813 }
814
815 scsi_log_completion(cmd, disposition);
816 switch (disposition) {
817 case SUCCESS:
818 scsi_finish_command(cmd);
819 break;
820 case NEEDS_RETRY:
821 scsi_retry_command(cmd);
822 break;
823 case ADD_TO_MLQUEUE:
824 scsi_queue_insert(cmd, SCSI_MLQUEUE_DEVICE_BUSY);
825 break;
826 default:
827 if (!scsi_eh_scmd_add(cmd, 0))
828 scsi_finish_command(cmd);
829 }
830 }
831} 773}
832 774
833/* 775/*
@@ -840,7 +782,7 @@ static void scsi_softirq(struct softirq_action *h)
840 * level drivers should not become re-entrant as a result of 782 * level drivers should not become re-entrant as a result of
841 * this. 783 * this.
842 */ 784 */
843static int scsi_retry_command(struct scsi_cmnd *cmd) 785int scsi_retry_command(struct scsi_cmnd *cmd)
844{ 786{
845 /* 787 /*
846 * Restore the SCSI command state. 788 * Restore the SCSI command state.
@@ -1273,38 +1215,6 @@ int scsi_device_cancel(struct scsi_device *sdev, int recovery)
1273} 1215}
1274EXPORT_SYMBOL(scsi_device_cancel); 1216EXPORT_SYMBOL(scsi_device_cancel);
1275 1217
1276#ifdef CONFIG_HOTPLUG_CPU
1277static int scsi_cpu_notify(struct notifier_block *self,
1278 unsigned long action, void *hcpu)
1279{
1280 int cpu = (unsigned long)hcpu;
1281
1282 switch(action) {
1283 case CPU_DEAD:
1284 /* Drain scsi_done_q. */
1285 local_irq_disable();
1286 list_splice_init(&per_cpu(scsi_done_q, cpu),
1287 &__get_cpu_var(scsi_done_q));
1288 raise_softirq_irqoff(SCSI_SOFTIRQ);
1289 local_irq_enable();
1290 break;
1291 default:
1292 break;
1293 }
1294 return NOTIFY_OK;
1295}
1296
1297static struct notifier_block __devinitdata scsi_cpu_nb = {
1298 .notifier_call = scsi_cpu_notify,
1299};
1300
1301#define register_scsi_cpu() register_cpu_notifier(&scsi_cpu_nb)
1302#define unregister_scsi_cpu() unregister_cpu_notifier(&scsi_cpu_nb)
1303#else
1304#define register_scsi_cpu()
1305#define unregister_scsi_cpu()
1306#endif /* CONFIG_HOTPLUG_CPU */
1307
1308MODULE_DESCRIPTION("SCSI core"); 1218MODULE_DESCRIPTION("SCSI core");
1309MODULE_LICENSE("GPL"); 1219MODULE_LICENSE("GPL");
1310 1220
@@ -1338,8 +1248,6 @@ static int __init init_scsi(void)
1338 INIT_LIST_HEAD(&per_cpu(scsi_done_q, i)); 1248 INIT_LIST_HEAD(&per_cpu(scsi_done_q, i));
1339 1249
1340 devfs_mk_dir("scsi"); 1250 devfs_mk_dir("scsi");
1341 open_softirq(SCSI_SOFTIRQ, scsi_softirq, NULL);
1342 register_scsi_cpu();
1343 printk(KERN_NOTICE "SCSI subsystem initialized\n"); 1251 printk(KERN_NOTICE "SCSI subsystem initialized\n");
1344 return 0; 1252 return 0;
1345 1253
@@ -1367,7 +1275,6 @@ static void __exit exit_scsi(void)
1367 devfs_remove("scsi"); 1275 devfs_remove("scsi");
1368 scsi_exit_procfs(); 1276 scsi_exit_procfs();
1369 scsi_exit_queue(); 1277 scsi_exit_queue();
1370 unregister_scsi_cpu();
1371} 1278}
1372 1279
1373subsys_initcall(init_scsi); 1280subsys_initcall(init_scsi);
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index ba93d6e66d48..00c9bf383e23 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -1493,6 +1493,41 @@ static void scsi_kill_request(struct request *req, request_queue_t *q)
1493 __scsi_done(cmd); 1493 __scsi_done(cmd);
1494} 1494}
1495 1495
1496static void scsi_softirq_done(struct request *rq)
1497{
1498 struct scsi_cmnd *cmd = rq->completion_data;
1499 unsigned long wait_for = cmd->allowed * cmd->timeout_per_command;
1500 int disposition;
1501
1502 INIT_LIST_HEAD(&cmd->eh_entry);
1503
1504 disposition = scsi_decide_disposition(cmd);
1505 if (disposition != SUCCESS &&
1506 time_before(cmd->jiffies_at_alloc + wait_for, jiffies)) {
1507 sdev_printk(KERN_ERR, cmd->device,
1508 "timing out command, waited %lus\n",
1509 wait_for/HZ);
1510 disposition = SUCCESS;
1511 }
1512
1513 scsi_log_completion(cmd, disposition);
1514
1515 switch (disposition) {
1516 case SUCCESS:
1517 scsi_finish_command(cmd);
1518 break;
1519 case NEEDS_RETRY:
1520 scsi_retry_command(cmd);
1521 break;
1522 case ADD_TO_MLQUEUE:
1523 scsi_queue_insert(cmd, SCSI_MLQUEUE_DEVICE_BUSY);
1524 break;
1525 default:
1526 if (!scsi_eh_scmd_add(cmd, 0))
1527 scsi_finish_command(cmd);
1528 }
1529}
1530
1496/* 1531/*
1497 * Function: scsi_request_fn() 1532 * Function: scsi_request_fn()
1498 * 1533 *
@@ -1667,6 +1702,7 @@ struct request_queue *scsi_alloc_queue(struct scsi_device *sdev)
1667 blk_queue_bounce_limit(q, scsi_calculate_bounce_limit(shost)); 1702 blk_queue_bounce_limit(q, scsi_calculate_bounce_limit(shost));
1668 blk_queue_segment_boundary(q, shost->dma_boundary); 1703 blk_queue_segment_boundary(q, shost->dma_boundary);
1669 blk_queue_issue_flush_fn(q, scsi_issue_flush_fn); 1704 blk_queue_issue_flush_fn(q, scsi_issue_flush_fn);
1705 blk_queue_softirq_done(q, scsi_softirq_done);
1670 1706
1671 if (!shost->use_clustering) 1707 if (!shost->use_clustering)
1672 clear_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags); 1708 clear_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags);
diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h
index f04e7e11f57a..14a6198cb8d2 100644
--- a/drivers/scsi/scsi_priv.h
+++ b/drivers/scsi/scsi_priv.h
@@ -44,6 +44,7 @@ extern void scsi_init_cmd_from_req(struct scsi_cmnd *cmd,
44 struct scsi_request *sreq); 44 struct scsi_request *sreq);
45extern void __scsi_release_request(struct scsi_request *sreq); 45extern void __scsi_release_request(struct scsi_request *sreq);
46extern void __scsi_done(struct scsi_cmnd *cmd); 46extern void __scsi_done(struct scsi_cmnd *cmd);
47extern int scsi_retry_command(struct scsi_cmnd *cmd);
47#ifdef CONFIG_SCSI_LOGGING 48#ifdef CONFIG_SCSI_LOGGING
48void scsi_log_send(struct scsi_cmnd *cmd); 49void scsi_log_send(struct scsi_cmnd *cmd);
49void scsi_log_completion(struct scsi_cmnd *cmd, int disposition); 50void scsi_log_completion(struct scsi_cmnd *cmd, int disposition);
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 32d4d8d7b9f3..4c5127ed379c 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -527,7 +527,7 @@ static int sd_release(struct inode *inode, struct file *filp)
527 return 0; 527 return 0;
528} 528}
529 529
530static int sd_hdio_getgeo(struct block_device *bdev, struct hd_geometry __user *loc) 530static int sd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
531{ 531{
532 struct scsi_disk *sdkp = scsi_disk(bdev->bd_disk); 532 struct scsi_disk *sdkp = scsi_disk(bdev->bd_disk);
533 struct scsi_device *sdp = sdkp->device; 533 struct scsi_device *sdp = sdkp->device;
@@ -545,15 +545,9 @@ static int sd_hdio_getgeo(struct block_device *bdev, struct hd_geometry __user *
545 else 545 else
546 scsicam_bios_param(bdev, sdkp->capacity, diskinfo); 546 scsicam_bios_param(bdev, sdkp->capacity, diskinfo);
547 547
548 if (put_user(diskinfo[0], &loc->heads)) 548 geo->heads = diskinfo[0];
549 return -EFAULT; 549 geo->sectors = diskinfo[1];
550 if (put_user(diskinfo[1], &loc->sectors)) 550 geo->cylinders = diskinfo[2];
551 return -EFAULT;
552 if (put_user(diskinfo[2], &loc->cylinders))
553 return -EFAULT;
554 if (put_user((unsigned)get_start_sect(bdev),
555 (unsigned long __user *)&loc->start))
556 return -EFAULT;
557 return 0; 551 return 0;
558} 552}
559 553
@@ -593,12 +587,6 @@ static int sd_ioctl(struct inode * inode, struct file * filp,
593 if (!scsi_block_when_processing_errors(sdp) || !error) 587 if (!scsi_block_when_processing_errors(sdp) || !error)
594 return error; 588 return error;
595 589
596 if (cmd == HDIO_GETGEO) {
597 if (!arg)
598 return -EINVAL;
599 return sd_hdio_getgeo(bdev, p);
600 }
601
602 /* 590 /*
603 * Send SCSI addressing ioctls directly to mid level, send other 591 * Send SCSI addressing ioctls directly to mid level, send other
604 * ioctls to block level and then onto mid level if they can't be 592 * ioctls to block level and then onto mid level if they can't be
@@ -800,6 +788,7 @@ static struct block_device_operations sd_fops = {
800 .open = sd_open, 788 .open = sd_open,
801 .release = sd_release, 789 .release = sd_release,
802 .ioctl = sd_ioctl, 790 .ioctl = sd_ioctl,
791 .getgeo = sd_getgeo,
803#ifdef CONFIG_COMPAT 792#ifdef CONFIG_COMPAT
804 .compat_ioctl = sd_compat_ioctl, 793 .compat_ioctl = sd_compat_ioctl,
805#endif 794#endif