Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 72f60acb authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'linus-plus-plus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/libata-dev

* 'linus-plus-plus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/libata-dev:
  libata: limit post SRST nsect/lbal wait to ~100ms
  libata: force PIO on IOMEGA ZIP 250 ATAPI
  libata passthru: update cached device paramters
  libata passthru: always enforce correct DEV bit
  libata passthru: map UDMA protocols
  libata passthru: support PIO multi commands
  libata passthru: update protocol numbers
  libata: Correct abuse of language
  libata-core/sff: Fix multiple assumptions about DMA
  ahci: Add MCP73/MCP77 support to AHCI driver
  libata: fix hw_sata_spd_limit initialization
  libata: print device model and firmware revision for ATAPI devices
  libata: fix probe time irq printouts
  libata: disable NCQ for HITACHI HTS541680J9SA00/SB21C7EP
  remove unused variable in pata_isapnp
parents b44c0267 e141d999
Loading
Loading
Loading
Loading
+24 −0
Original line number Diff line number Diff line
@@ -426,6 +426,30 @@ static const struct pci_device_id ahci_pci_tbl[] = {
	{ PCI_VDEVICE(NVIDIA, 0x0559), board_ahci },		/* MCP67 */
	{ PCI_VDEVICE(NVIDIA, 0x055a), board_ahci },		/* MCP67 */
	{ PCI_VDEVICE(NVIDIA, 0x055b), board_ahci },		/* MCP67 */
	{ PCI_VDEVICE(NVIDIA, 0x07f0), board_ahci },		/* MCP73 */
	{ PCI_VDEVICE(NVIDIA, 0x07f1), board_ahci },		/* MCP73 */
	{ PCI_VDEVICE(NVIDIA, 0x07f2), board_ahci },		/* MCP73 */
	{ PCI_VDEVICE(NVIDIA, 0x07f3), board_ahci },		/* MCP73 */
	{ PCI_VDEVICE(NVIDIA, 0x07f4), board_ahci },		/* MCP73 */
	{ PCI_VDEVICE(NVIDIA, 0x07f5), board_ahci },		/* MCP73 */
	{ PCI_VDEVICE(NVIDIA, 0x07f6), board_ahci },		/* MCP73 */
	{ PCI_VDEVICE(NVIDIA, 0x07f7), board_ahci },		/* MCP73 */
	{ PCI_VDEVICE(NVIDIA, 0x07f8), board_ahci },		/* MCP73 */
	{ PCI_VDEVICE(NVIDIA, 0x07f9), board_ahci },		/* MCP73 */
	{ PCI_VDEVICE(NVIDIA, 0x07fa), board_ahci },		/* MCP73 */
	{ PCI_VDEVICE(NVIDIA, 0x07fb), board_ahci },		/* MCP73 */
	{ PCI_VDEVICE(NVIDIA, 0x0ad0), board_ahci },		/* MCP77 */
	{ PCI_VDEVICE(NVIDIA, 0x0ad1), board_ahci },		/* MCP77 */
	{ PCI_VDEVICE(NVIDIA, 0x0ad2), board_ahci },		/* MCP77 */
	{ PCI_VDEVICE(NVIDIA, 0x0ad3), board_ahci },		/* MCP77 */
	{ PCI_VDEVICE(NVIDIA, 0x0ad4), board_ahci },		/* MCP77 */
	{ PCI_VDEVICE(NVIDIA, 0x0ad5), board_ahci },		/* MCP77 */
	{ PCI_VDEVICE(NVIDIA, 0x0ad6), board_ahci },		/* MCP77 */
	{ PCI_VDEVICE(NVIDIA, 0x0ad7), board_ahci },		/* MCP77 */
	{ PCI_VDEVICE(NVIDIA, 0x0ad8), board_ahci },		/* MCP77 */
	{ PCI_VDEVICE(NVIDIA, 0x0ad9), board_ahci },		/* MCP77 */
	{ PCI_VDEVICE(NVIDIA, 0x0ada), board_ahci },		/* MCP77 */
	{ PCI_VDEVICE(NVIDIA, 0x0adb), board_ahci },		/* MCP77 */

	/* SiS */
	{ PCI_VDEVICE(SI, 0x1184), board_ahci }, /* SiS 966 */
+39 −23
Original line number Diff line number Diff line
@@ -1727,7 +1727,7 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,

	/* sanity check */
	rc = -EINVAL;
	reason = "device reports illegal type";
	reason = "device reports invalid type";

	if (class == ATA_DEV_ATA) {
		if (!ata_id_is_ata(id) && !ata_id_is_cfa(id))
@@ -1900,6 +1900,13 @@ int ata_dev_configure(struct ata_device *dev)
	if (ata_msg_probe(ap))
		ata_dump_id(id);

	/* SCSI only uses 4-char revisions, dump full 8 chars from ATA */
	ata_id_c_string(dev->id, fwrevbuf, ATA_ID_FW_REV,
			sizeof(fwrevbuf));

	ata_id_c_string(dev->id, modelbuf, ATA_ID_PROD,
			sizeof(modelbuf));

	/* ATA-specific feature tests */
	if (dev->class == ATA_DEV_ATA) {
		if (ata_id_is_cfa(id)) {
@@ -1914,13 +1921,6 @@ int ata_dev_configure(struct ata_device *dev)

		dev->n_sectors = ata_id_n_sectors(id);

		/* SCSI only uses 4-char revisions, dump full 8 chars from ATA */
		ata_id_c_string(dev->id, fwrevbuf, ATA_ID_FW_REV,
				sizeof(fwrevbuf));

		ata_id_c_string(dev->id, modelbuf, ATA_ID_PROD,
				sizeof(modelbuf));

		if (dev->id[59] & 0x100)
			dev->multi_count = dev->id[59] & 0xff;

@@ -2009,7 +2009,9 @@ int ata_dev_configure(struct ata_device *dev)

		/* print device info to dmesg */
		if (ata_msg_drv(ap) && print_info)
			ata_dev_printk(dev, KERN_INFO, "ATAPI, max %s%s\n",
			ata_dev_printk(dev, KERN_INFO,
				       "ATAPI: %s, %s, max %s%s\n",
				       modelbuf, fwrevbuf,
				       ata_mode_string(xfer_mask),
				       cdb_intr_string);
	}
@@ -3059,22 +3061,28 @@ static int ata_bus_post_reset(struct ata_port *ap, unsigned int devmask,
		}
	}

	/* if device 1 was found in ata_devchk, wait for
	 * register access, then wait for BSY to clear
	/* if device 1 was found in ata_devchk, wait for register
	 * access briefly, then wait for BSY to clear.
	 */
	while (dev1) {
		u8 nsect, lbal;
	if (dev1) {
		int i;

		ap->ops->dev_select(ap, 1);

		/* Wait for register access.  Some ATAPI devices fail
		 * to set nsect/lbal after reset, so don't waste too
		 * much time on it.  We're gonna wait for !BSY anyway.
		 */
		for (i = 0; i < 2; i++) {
			u8 nsect, lbal;

			nsect = ioread8(ioaddr->nsect_addr);
			lbal = ioread8(ioaddr->lbal_addr);
			if ((nsect == 1) && (lbal == 1))
				break;
		if (time_after(jiffies, deadline))
			return -EBUSY;
			msleep(50);	/* give drive a breather */
		}
	if (dev1) {

		rc = ata_wait_ready(ap, deadline);
		if (rc) {
			if (rc != -ENODEV)
@@ -3769,6 +3777,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
	{ "_NEC DV5800A", 	NULL,		ATA_HORKAGE_NODMA },
	{ "SAMSUNG CD-ROM SN-124","N001",	ATA_HORKAGE_NODMA },
	{ "Seagate STT20000A", NULL,		ATA_HORKAGE_NODMA },
	{ "IOMEGA  ZIP 250       ATAPI", NULL,	ATA_HORKAGE_NODMA }, /* temporary fix */

	/* Weird ATAPI devices */
	{ "TORiSAN DVD-ROM DRD-N216", NULL,	ATA_HORKAGE_MAX_SEC_128 |
@@ -3791,6 +3800,8 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
	{ "HTS541060G9SA00",    "MB3OC60D",     ATA_HORKAGE_NONCQ, },
	{ "HTS541080G9SA00",    "MB4OC60D",     ATA_HORKAGE_NONCQ, },
	{ "HTS541010G9SA00",    "MBZOC60D",     ATA_HORKAGE_NONCQ, },
	/* Drives which do spurious command completion */
	{ "HTS541680J9SA00",	"SB2IC7EP",	ATA_HORKAGE_NONCQ, },

	/* Devices with NCQ limits */

@@ -6313,6 +6324,7 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
		/* init sata_spd_limit to the current value */
		if (sata_scr_read(ap, SCR_CONTROL, &scontrol) == 0) {
			int spd = (scontrol >> 4) & 0xf;
			if (spd)
				ap->hw_sata_spd_limit &= (1 << spd) - 1;
		}
		ap->sata_spd_limit = ap->hw_sata_spd_limit;
@@ -6433,6 +6445,9 @@ int ata_host_activate(struct ata_host *host, int irq,
	if (rc)
		devm_free_irq(host->dev, irq, host);

	/* Used to print device info at probe */
	host->irq = irq;

	return rc;
}

@@ -6818,6 +6833,7 @@ EXPORT_SYMBOL_GPL(ata_check_status);
EXPORT_SYMBOL_GPL(ata_altstatus);
EXPORT_SYMBOL_GPL(ata_exec_command);
EXPORT_SYMBOL_GPL(ata_port_start);
EXPORT_SYMBOL_GPL(ata_sff_port_start);
EXPORT_SYMBOL_GPL(ata_interrupt);
EXPORT_SYMBOL_GPL(ata_do_set_mode);
EXPORT_SYMBOL_GPL(ata_data_xfer);
+43 −24
Original line number Diff line number Diff line
@@ -1363,13 +1363,23 @@ static void ata_scsi_qc_complete(struct ata_queued_cmd *qc)
	 * schedule EH_REVALIDATE operation to update the IDENTIFY DEVICE
	 * cache
	 */
	if (ap->ops->error_handler &&
	    !need_sense && (qc->tf.command == ATA_CMD_SET_FEATURES) &&
	    ((qc->tf.feature == SETFEATURES_WC_ON) ||
	     (qc->tf.feature == SETFEATURES_WC_OFF))) {
	if (ap->ops->error_handler && !need_sense) {
		switch (qc->tf.command) {
		case ATA_CMD_SET_FEATURES:
			if ((qc->tf.feature == SETFEATURES_WC_ON) ||
			    (qc->tf.feature == SETFEATURES_WC_OFF)) {
				ap->eh_info.action |= ATA_EH_REVALIDATE;
				ata_port_schedule_eh(ap);
			}
			break;

		case ATA_CMD_INIT_DEV_PARAMS: /* CHS translation changed */
		case ATA_CMD_SET_MULTI: /* multi_count changed */
			ap->eh_info.action |= ATA_EH_REVALIDATE;
			ata_port_schedule_eh(ap);
			break;
		}
	}

	/* For ATA pass thru (SAT) commands, generate a sense block if
	 * user mandated it or if there's an error.  Note that if we
@@ -2506,22 +2516,21 @@ ata_scsi_map_proto(u8 byte1)
			return ATA_PROT_NODATA;

		case 6:		/* DMA */
		case 10:	/* UDMA Data-in */
		case 11:	/* UDMA Data-Out */
			return ATA_PROT_DMA;

		case 4:		/* PIO Data-in */
		case 5:		/* PIO Data-out */
			return ATA_PROT_PIO;

		case 10:	/* Device Reset */
		case 0:		/* Hard Reset */
		case 1:		/* SRST */
		case 2:		/* Bus Idle */
		case 7:		/* Packet */
		case 8:		/* DMA Queued */
		case 9:		/* Device Diagnostic */
		case 11:	/* UDMA Data-in */
		case 12:	/* UDMA Data-Out */
		case 13:	/* FPDMA */
		case 8:		/* Device Diagnostic */
		case 9:		/* Device Reset */
		case 7:		/* DMA Queued */
		case 12:	/* FPDMA */
		case 15:	/* Return Response Info */
		default:	/* Reserved */
			break;
	}
@@ -2552,10 +2561,6 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc)
	if (tf->protocol == ATA_PROT_DMA && dev->dma_mode == 0)
		goto invalid_fld;

	if (cdb[1] & 0xe0)
		/* PIO multi not supported yet */
		goto invalid_fld;

	/*
	 * 12 and 16 byte CDBs use different offsets to
	 * provide the various register values.
@@ -2600,13 +2605,27 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc)
		tf->device = cdb[8];
		tf->command = cdb[9];
	}
	/*
	 * If slave is possible, enforce correct master/slave bit
	*/
	if (qc->ap->flags & ATA_FLAG_SLAVE_POSS)
		tf->device = qc->dev->devno ?

	/* enforce correct master/slave bit */
	tf->device = dev->devno ?
		tf->device | ATA_DEV1 : tf->device & ~ATA_DEV1;

	/* sanity check for pio multi commands */
	if ((cdb[1] & 0xe0) && !is_multi_taskfile(tf))
		goto invalid_fld;

	if (is_multi_taskfile(tf)) {
		unsigned int multi_count = 1 << (cdb[1] >> 5);

		/* compare the passed through multi_count
		 * with the cached multi_count of libata
		 */
		if (multi_count != dev->multi_count)
			ata_dev_printk(dev, KERN_WARNING,
				       "invalid multi_count %u ignored\n",
				       multi_count);
	}	

	/* READ/WRITE LONG use a non-standard sect_size */
	qc->sect_size = ATA_SECT_SIZE;
	switch (tf->command) {
+29 −8
Original line number Diff line number Diff line
@@ -80,25 +80,25 @@ u8 ata_dummy_irq_on (struct ata_port *ap) { return 0; }
u8 ata_irq_ack(struct ata_port *ap, unsigned int chk_drq)
{
	unsigned int bits = chk_drq ? ATA_BUSY | ATA_DRQ : ATA_BUSY;
	u8 host_stat, post_stat, status;
	u8 host_stat = 0, post_stat = 0, status;

	status = ata_busy_wait(ap, bits, 1000);
	if (status & bits)
		if (ata_msg_err(ap))
			printk(KERN_ERR "abnormal status 0x%X\n", status);

	if (ap->ioaddr.bmdma_addr) {
		/* get controller status; clear intr, err bits */
		host_stat = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
		iowrite8(host_stat | ATA_DMA_INTR | ATA_DMA_ERR,
			 ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);

		post_stat = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);

	}
	if (ata_msg_intr(ap))
		printk(KERN_INFO "%s: irq ack: host_stat 0x%X, new host_stat 0x%X, drv_stat 0x%X\n",
			__FUNCTION__,
			host_stat, post_stat, status);

	return status;
}

@@ -516,6 +516,27 @@ void ata_bmdma_post_internal_cmd(struct ata_queued_cmd *qc)
		ata_bmdma_stop(qc);
}

/**
 *	ata_sff_port_start - Set port up for dma.
 *	@ap: Port to initialize
 *
 *	Called just after data structures for each port are
 *	initialized.  Allocates space for PRD table if the device
 *	is DMA capable SFF.
 *
 *	May be used as the port_start() entry in ata_port_operations.
 *
 *	LOCKING:
 *	Inherited from caller.
 */

int ata_sff_port_start(struct ata_port *ap)
{
	if (ap->ioaddr.bmdma_addr)
		return ata_port_start(ap);
	return 0;
}

#ifdef CONFIG_PCI

static int ata_resources_present(struct pci_dev *pdev, int port)
+0 −1
Original line number Diff line number Diff line
@@ -77,7 +77,6 @@ static int isapnp_init_one(struct pnp_dev *idev, const struct pnp_device_id *dev
	struct ata_host *host;
	struct ata_port *ap;
	void __iomem *cmd_addr, *ctl_addr;
	int rc;

	if (pnp_port_valid(idev, 0) == 0)
		return -ENODEV;
Loading