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

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
...@@ -426,6 +426,30 @@ static const struct pci_device_id ahci_pci_tbl[] = { ...@@ -426,6 +426,30 @@ static const struct pci_device_id ahci_pci_tbl[] = {
{ PCI_VDEVICE(NVIDIA, 0x0559), board_ahci }, /* MCP67 */ { PCI_VDEVICE(NVIDIA, 0x0559), board_ahci }, /* MCP67 */
{ PCI_VDEVICE(NVIDIA, 0x055a), board_ahci }, /* MCP67 */ { PCI_VDEVICE(NVIDIA, 0x055a), board_ahci }, /* MCP67 */
{ PCI_VDEVICE(NVIDIA, 0x055b), 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 */ /* SiS */
{ PCI_VDEVICE(SI, 0x1184), board_ahci }, /* SiS 966 */ { PCI_VDEVICE(SI, 0x1184), board_ahci }, /* SiS 966 */
......
...@@ -1727,7 +1727,7 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class, ...@@ -1727,7 +1727,7 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
/* sanity check */ /* sanity check */
rc = -EINVAL; rc = -EINVAL;
reason = "device reports illegal type"; reason = "device reports invalid type";
if (class == ATA_DEV_ATA) { if (class == ATA_DEV_ATA) {
if (!ata_id_is_ata(id) && !ata_id_is_cfa(id)) if (!ata_id_is_ata(id) && !ata_id_is_cfa(id))
...@@ -1900,6 +1900,13 @@ int ata_dev_configure(struct ata_device *dev) ...@@ -1900,6 +1900,13 @@ int ata_dev_configure(struct ata_device *dev)
if (ata_msg_probe(ap)) if (ata_msg_probe(ap))
ata_dump_id(id); 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 */ /* ATA-specific feature tests */
if (dev->class == ATA_DEV_ATA) { if (dev->class == ATA_DEV_ATA) {
if (ata_id_is_cfa(id)) { if (ata_id_is_cfa(id)) {
...@@ -1914,13 +1921,6 @@ int ata_dev_configure(struct ata_device *dev) ...@@ -1914,13 +1921,6 @@ int ata_dev_configure(struct ata_device *dev)
dev->n_sectors = ata_id_n_sectors(id); 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) if (dev->id[59] & 0x100)
dev->multi_count = dev->id[59] & 0xff; dev->multi_count = dev->id[59] & 0xff;
...@@ -2009,7 +2009,9 @@ int ata_dev_configure(struct ata_device *dev) ...@@ -2009,7 +2009,9 @@ int ata_dev_configure(struct ata_device *dev)
/* print device info to dmesg */ /* print device info to dmesg */
if (ata_msg_drv(ap) && print_info) 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), ata_mode_string(xfer_mask),
cdb_intr_string); cdb_intr_string);
} }
...@@ -3059,22 +3061,28 @@ static int ata_bus_post_reset(struct ata_port *ap, unsigned int devmask, ...@@ -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 /* if device 1 was found in ata_devchk, wait for register
* register access, then wait for BSY to clear * access briefly, then wait for BSY to clear.
*/ */
while (dev1) { if (dev1) {
u8 nsect, lbal; int i;
ap->ops->dev_select(ap, 1); ap->ops->dev_select(ap, 1);
nsect = ioread8(ioaddr->nsect_addr);
lbal = ioread8(ioaddr->lbal_addr); /* Wait for register access. Some ATAPI devices fail
if ((nsect == 1) && (lbal == 1)) * to set nsect/lbal after reset, so don't waste too
break; * much time on it. We're gonna wait for !BSY anyway.
if (time_after(jiffies, deadline)) */
return -EBUSY; for (i = 0; i < 2; i++) {
msleep(50); /* give drive a breather */ u8 nsect, lbal;
}
if (dev1) { nsect = ioread8(ioaddr->nsect_addr);
lbal = ioread8(ioaddr->lbal_addr);
if ((nsect == 1) && (lbal == 1))
break;
msleep(50); /* give drive a breather */
}
rc = ata_wait_ready(ap, deadline); rc = ata_wait_ready(ap, deadline);
if (rc) { if (rc) {
if (rc != -ENODEV) if (rc != -ENODEV)
...@@ -3769,6 +3777,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { ...@@ -3769,6 +3777,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
{ "_NEC DV5800A", NULL, ATA_HORKAGE_NODMA }, { "_NEC DV5800A", NULL, ATA_HORKAGE_NODMA },
{ "SAMSUNG CD-ROM SN-124","N001", ATA_HORKAGE_NODMA }, { "SAMSUNG CD-ROM SN-124","N001", ATA_HORKAGE_NODMA },
{ "Seagate STT20000A", NULL, ATA_HORKAGE_NODMA }, { "Seagate STT20000A", NULL, ATA_HORKAGE_NODMA },
{ "IOMEGA ZIP 250 ATAPI", NULL, ATA_HORKAGE_NODMA }, /* temporary fix */
/* Weird ATAPI devices */ /* Weird ATAPI devices */
{ "TORiSAN DVD-ROM DRD-N216", NULL, ATA_HORKAGE_MAX_SEC_128 | { "TORiSAN DVD-ROM DRD-N216", NULL, ATA_HORKAGE_MAX_SEC_128 |
...@@ -3791,6 +3800,8 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { ...@@ -3791,6 +3800,8 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
{ "HTS541060G9SA00", "MB3OC60D", ATA_HORKAGE_NONCQ, }, { "HTS541060G9SA00", "MB3OC60D", ATA_HORKAGE_NONCQ, },
{ "HTS541080G9SA00", "MB4OC60D", ATA_HORKAGE_NONCQ, }, { "HTS541080G9SA00", "MB4OC60D", ATA_HORKAGE_NONCQ, },
{ "HTS541010G9SA00", "MBZOC60D", ATA_HORKAGE_NONCQ, }, { "HTS541010G9SA00", "MBZOC60D", ATA_HORKAGE_NONCQ, },
/* Drives which do spurious command completion */
{ "HTS541680J9SA00", "SB2IC7EP", ATA_HORKAGE_NONCQ, },
/* Devices with NCQ limits */ /* Devices with NCQ limits */
...@@ -6313,7 +6324,8 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht) ...@@ -6313,7 +6324,8 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
/* init sata_spd_limit to the current value */ /* init sata_spd_limit to the current value */
if (sata_scr_read(ap, SCR_CONTROL, &scontrol) == 0) { if (sata_scr_read(ap, SCR_CONTROL, &scontrol) == 0) {
int spd = (scontrol >> 4) & 0xf; int spd = (scontrol >> 4) & 0xf;
ap->hw_sata_spd_limit &= (1 << spd) - 1; if (spd)
ap->hw_sata_spd_limit &= (1 << spd) - 1;
} }
ap->sata_spd_limit = ap->hw_sata_spd_limit; ap->sata_spd_limit = ap->hw_sata_spd_limit;
...@@ -6433,6 +6445,9 @@ int ata_host_activate(struct ata_host *host, int irq, ...@@ -6433,6 +6445,9 @@ int ata_host_activate(struct ata_host *host, int irq,
if (rc) if (rc)
devm_free_irq(host->dev, irq, host); devm_free_irq(host->dev, irq, host);
/* Used to print device info at probe */
host->irq = irq;
return rc; return rc;
} }
...@@ -6818,6 +6833,7 @@ EXPORT_SYMBOL_GPL(ata_check_status); ...@@ -6818,6 +6833,7 @@ EXPORT_SYMBOL_GPL(ata_check_status);
EXPORT_SYMBOL_GPL(ata_altstatus); EXPORT_SYMBOL_GPL(ata_altstatus);
EXPORT_SYMBOL_GPL(ata_exec_command); EXPORT_SYMBOL_GPL(ata_exec_command);
EXPORT_SYMBOL_GPL(ata_port_start); EXPORT_SYMBOL_GPL(ata_port_start);
EXPORT_SYMBOL_GPL(ata_sff_port_start);
EXPORT_SYMBOL_GPL(ata_interrupt); EXPORT_SYMBOL_GPL(ata_interrupt);
EXPORT_SYMBOL_GPL(ata_do_set_mode); EXPORT_SYMBOL_GPL(ata_do_set_mode);
EXPORT_SYMBOL_GPL(ata_data_xfer); EXPORT_SYMBOL_GPL(ata_data_xfer);
......
...@@ -1363,12 +1363,22 @@ static void ata_scsi_qc_complete(struct ata_queued_cmd *qc) ...@@ -1363,12 +1363,22 @@ static void ata_scsi_qc_complete(struct ata_queued_cmd *qc)
* schedule EH_REVALIDATE operation to update the IDENTIFY DEVICE * schedule EH_REVALIDATE operation to update the IDENTIFY DEVICE
* cache * cache
*/ */
if (ap->ops->error_handler && if (ap->ops->error_handler && !need_sense) {
!need_sense && (qc->tf.command == ATA_CMD_SET_FEATURES) && switch (qc->tf.command) {
((qc->tf.feature == SETFEATURES_WC_ON) || case ATA_CMD_SET_FEATURES:
(qc->tf.feature == SETFEATURES_WC_OFF))) { if ((qc->tf.feature == SETFEATURES_WC_ON) ||
ap->eh_info.action |= ATA_EH_REVALIDATE; (qc->tf.feature == SETFEATURES_WC_OFF)) {
ata_port_schedule_eh(ap); 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 /* For ATA pass thru (SAT) commands, generate a sense block if
...@@ -2506,22 +2516,21 @@ ata_scsi_map_proto(u8 byte1) ...@@ -2506,22 +2516,21 @@ ata_scsi_map_proto(u8 byte1)
return ATA_PROT_NODATA; return ATA_PROT_NODATA;
case 6: /* DMA */ case 6: /* DMA */
case 10: /* UDMA Data-in */
case 11: /* UDMA Data-Out */
return ATA_PROT_DMA; return ATA_PROT_DMA;
case 4: /* PIO Data-in */ case 4: /* PIO Data-in */
case 5: /* PIO Data-out */ case 5: /* PIO Data-out */
return ATA_PROT_PIO; return ATA_PROT_PIO;
case 10: /* Device Reset */
case 0: /* Hard Reset */ case 0: /* Hard Reset */
case 1: /* SRST */ case 1: /* SRST */
case 2: /* Bus Idle */ case 8: /* Device Diagnostic */
case 7: /* Packet */ case 9: /* Device Reset */
case 8: /* DMA Queued */ case 7: /* DMA Queued */
case 9: /* Device Diagnostic */ case 12: /* FPDMA */
case 11: /* UDMA Data-in */ case 15: /* Return Response Info */
case 12: /* UDMA Data-Out */
case 13: /* FPDMA */
default: /* Reserved */ default: /* Reserved */
break; break;
} }
...@@ -2552,10 +2561,6 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc) ...@@ -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) if (tf->protocol == ATA_PROT_DMA && dev->dma_mode == 0)
goto invalid_fld; goto invalid_fld;
if (cdb[1] & 0xe0)
/* PIO multi not supported yet */
goto invalid_fld;
/* /*
* 12 and 16 byte CDBs use different offsets to * 12 and 16 byte CDBs use different offsets to
* provide the various register values. * provide the various register values.
...@@ -2600,12 +2605,26 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc) ...@@ -2600,12 +2605,26 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc)
tf->device = cdb[8]; tf->device = cdb[8];
tf->command = cdb[9]; tf->command = cdb[9];
} }
/*
* If slave is possible, enforce correct master/slave bit /* enforce correct master/slave bit */
*/ tf->device = dev->devno ?
if (qc->ap->flags & ATA_FLAG_SLAVE_POSS) tf->device | ATA_DEV1 : tf->device & ~ATA_DEV1;
tf->device = qc->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 */ /* READ/WRITE LONG use a non-standard sect_size */
qc->sect_size = ATA_SECT_SIZE; qc->sect_size = ATA_SECT_SIZE;
......
...@@ -80,25 +80,25 @@ u8 ata_dummy_irq_on (struct ata_port *ap) { return 0; } ...@@ -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) u8 ata_irq_ack(struct ata_port *ap, unsigned int chk_drq)
{ {
unsigned int bits = chk_drq ? ATA_BUSY | ATA_DRQ : ATA_BUSY; 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); status = ata_busy_wait(ap, bits, 1000);
if (status & bits) if (status & bits)
if (ata_msg_err(ap)) if (ata_msg_err(ap))
printk(KERN_ERR "abnormal status 0x%X\n", status); printk(KERN_ERR "abnormal status 0x%X\n", status);
/* get controller status; clear intr, err bits */ if (ap->ioaddr.bmdma_addr) {
host_stat = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS); /* get controller status; clear intr, err bits */
iowrite8(host_stat | ATA_DMA_INTR | ATA_DMA_ERR, host_stat = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
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);
post_stat = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
}
if (ata_msg_intr(ap)) 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", printk(KERN_INFO "%s: irq ack: host_stat 0x%X, new host_stat 0x%X, drv_stat 0x%X\n",
__FUNCTION__, __FUNCTION__,
host_stat, post_stat, status); host_stat, post_stat, status);
return status; return status;
} }
...@@ -516,6 +516,27 @@ void ata_bmdma_post_internal_cmd(struct ata_queued_cmd *qc) ...@@ -516,6 +516,27 @@ void ata_bmdma_post_internal_cmd(struct ata_queued_cmd *qc)
ata_bmdma_stop(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 #ifdef CONFIG_PCI
static int ata_resources_present(struct pci_dev *pdev, int port) static int ata_resources_present(struct pci_dev *pdev, int port)
......
...@@ -77,7 +77,6 @@ static int isapnp_init_one(struct pnp_dev *idev, const struct pnp_device_id *dev ...@@ -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_host *host;
struct ata_port *ap; struct ata_port *ap;
void __iomem *cmd_addr, *ctl_addr; void __iomem *cmd_addr, *ctl_addr;
int rc;
if (pnp_port_valid(idev, 0) == 0) if (pnp_port_valid(idev, 0) == 0)
return -ENODEV; return -ENODEV;
......
...@@ -151,6 +151,7 @@ enum { ...@@ -151,6 +151,7 @@ enum {
ATA_CMD_WRITE_MULTI_EXT = 0x39, ATA_CMD_WRITE_MULTI_EXT = 0x39,
ATA_CMD_WRITE_MULTI_FUA_EXT = 0xCE, ATA_CMD_WRITE_MULTI_FUA_EXT = 0xCE,
ATA_CMD_SET_FEATURES = 0xEF, ATA_CMD_SET_FEATURES = 0xEF,
ATA_CMD_SET_MULTI = 0xC6,
ATA_CMD_PACKET = 0xA0, ATA_CMD_PACKET = 0xA0,
ATA_CMD_VERIFY = 0x40, ATA_CMD_VERIFY = 0x40,
ATA_CMD_VERIFY_EXT = 0x42, ATA_CMD_VERIFY_EXT = 0x42,
...@@ -249,7 +250,7 @@ enum ata_tf_protocols { ...@@ -249,7 +250,7 @@ enum ata_tf_protocols {
/* ATA taskfile protocols */ /* ATA taskfile protocols */
ATA_PROT_UNKNOWN, /* unknown/invalid */ ATA_PROT_UNKNOWN, /* unknown/invalid */
ATA_PROT_NODATA, /* no data */ ATA_PROT_NODATA, /* no data */
ATA_PROT_PIO, /* PIO single sector */ ATA_PROT_PIO, /* PIO data xfer */
ATA_PROT_DMA, /* DMA */ ATA_PROT_DMA, /* DMA */
ATA_PROT_NCQ, /* NCQ */ ATA_PROT_NCQ, /* NCQ */
ATA_PROT_ATAPI, /* packet command, PIO data xfer*/ ATA_PROT_ATAPI, /* packet command, PIO data xfer*/
......
...@@ -753,6 +753,7 @@ extern u8 ata_check_status(struct ata_port *ap); ...@@ -753,6 +753,7 @@ extern u8 ata_check_status(struct ata_port *ap);
extern u8 ata_altstatus(struct ata_port *ap); extern u8 ata_altstatus(struct ata_port *ap);
extern void ata_exec_command(struct ata_port *ap, const struct ata_taskfile *tf); extern void ata_exec_command(struct ata_port *ap, const struct ata_taskfile *tf);
extern int ata_port_start (struct ata_port *ap); extern int ata_port_start (struct ata_port *ap);
extern int ata_sff_port_start (struct ata_port *ap);
extern irqreturn_t ata_interrupt (int irq, void *dev_instance); extern irqreturn_t ata_interrupt (int irq, void *dev_instance);
extern void ata_data_xfer(struct ata_device *adev, unsigned char *buf, extern void ata_data_xfer(struct ata_device *adev, unsigned char *buf,
unsigned int buflen, int write_data); unsigned int buflen, int write_data);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment