浏览代码

Merge branch 'upstream-greg' of gregkh@master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/libata-dev

Greg Kroah-Hartman 19 年之前
父节点
当前提交
897e11a40b
共有 4 个文件被更改,包括 24 次插入29 次删除
  1. 3 2
      drivers/scsi/ata_piix.c
  2. 8 26
      drivers/scsi/libata-core.c
  3. 13 0
      drivers/scsi/libata-scsi.c
  4. 0 1
      drivers/scsi/sata_sil24.c

+ 3 - 2
drivers/scsi/ata_piix.c

@@ -567,8 +567,8 @@ static int piix_sata_prereset(struct ata_port *ap)
 			present = 1;
 	}
 
-	DPRINTK("ata%u: LEAVE, pcs=0x%x present_mask=0x%x\n",
-		ap->id, pcs, present_mask);
+	DPRINTK("ata%u: LEAVE, pcs=0x%x present=0x%x\n",
+		ap->id, pcs, present);
 
 	if (!present) {
 		ata_port_printk(ap, KERN_INFO, "SATA port has no device.\n");
@@ -828,6 +828,7 @@ static void __devinit piix_init_sata_map(struct pci_dev *pdev,
 		case IDE:
 			WARN_ON((i & 1) || map[i + 1] != IDE);
 			pinfo[i / 2] = piix_port_info[ich5_pata];
+			pinfo[i / 2].private_data = hpriv;
 			i++;
 			printk(" IDE IDE");
 			break;

+ 8 - 26
drivers/scsi/libata-core.c

@@ -5185,28 +5185,6 @@ void ata_host_stop (struct ata_host_set *host_set)
 		iounmap(host_set->mmio_base);
 }
 
-
-/**
- *	ata_host_remove - Unregister SCSI host structure with upper layers
- *	@ap: Port to unregister
- *	@do_unregister: 1 if we fully unregister, 0 to just stop the port
- *
- *	LOCKING:
- *	Inherited from caller.
- */
-
-static void ata_host_remove(struct ata_port *ap, unsigned int do_unregister)
-{
-	struct Scsi_Host *sh = ap->host;
-
-	DPRINTK("ENTER\n");
-
-	if (do_unregister)
-		scsi_remove_host(sh);
-
-	ap->ops->port_stop(ap);
-}
-
 /**
  *	ata_dev_init - Initialize an ata_device structure
  *	@dev: Device structure to initialize
@@ -5532,8 +5510,11 @@ int ata_device_add(const struct ata_probe_ent *ent)
 
 err_out:
 	for (i = 0; i < count; i++) {
-		ata_host_remove(host_set->ports[i], 1);
-		scsi_host_put(host_set->ports[i]->host);
+		struct ata_port *ap = host_set->ports[i];
+		if (ap) {
+			ap->ops->port_stop(ap);
+			scsi_host_put(ap->host);
+		}
 	}
 err_free_ret:
 	kfree(host_set);
@@ -5558,7 +5539,7 @@ void ata_port_detach(struct ata_port *ap)
 	int i;
 
 	if (!ap->ops->error_handler)
-		return;
+		goto skip_eh;
 
 	/* tell EH we're leaving & flush EH */
 	spin_lock_irqsave(ap->lock, flags);
@@ -5594,6 +5575,7 @@ void ata_port_detach(struct ata_port *ap)
 	cancel_delayed_work(&ap->hotplug_task);
 	flush_workqueue(ata_aux_wq);
 
+ skip_eh:
 	/* remove the associated SCSI host */
 	scsi_remove_host(ap->host);
 }
@@ -5662,7 +5644,7 @@ int ata_scsi_release(struct Scsi_Host *host)
 	DPRINTK("ENTER\n");
 
 	ap->ops->port_disable(ap);
-	ata_host_remove(ap, 0);
+	ap->ops->port_stop(ap);
 
 	DPRINTK("EXIT\n");
 	return 1;

+ 13 - 0
drivers/scsi/libata-scsi.c

@@ -2353,6 +2353,19 @@ static void atapi_qc_complete(struct ata_queued_cmd *qc)
 			ata_gen_ata_desc_sense(qc);
 		}
 
+		/* SCSI EH automatically locks door if sdev->locked is
+		 * set.  Sometimes door lock request continues to
+		 * fail, for example, when no media is present.  This
+		 * creates a loop - SCSI EH issues door lock which
+		 * fails and gets invoked again to acquire sense data
+		 * for the failed command.
+		 *
+		 * If door lock fails, always clear sdev->locked to
+		 * avoid this infinite loop.
+		 */
+		if (qc->cdb[0] == ALLOW_MEDIUM_REMOVAL)
+			qc->dev->sdev->locked = 0;
+
 		qc->scsicmd->result = SAM_STAT_CHECK_CONDITION;
 		qc->scsidone(cmd);
 		ata_qc_free(qc);

+ 0 - 1
drivers/scsi/sata_sil24.c

@@ -1106,7 +1106,6 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 
 	probe_ent->irq = pdev->irq;
 	probe_ent->irq_flags = IRQF_SHARED;
-	probe_ent->mmio_base = port_base;
 	probe_ent->private_data = hpriv;
 
 	hpriv->host_base = host_base;