Commit b2cd6415 authored by Linus Torvalds's avatar Linus Torvalds

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

* 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/libata-dev:
  libata: track spindown status and skip spindown_compat if possible
  libata: fix shutdown warning message printing
  libata-acpi: add ATA_FLAG_ACPI_SATA port flag
  libata: during revalidation, check n_sectors after device is configured
  libata: separate out ata_dev_reread_id()
  pata_scc had been missed by ata_std_prereset() switch
parents b17bfca5 13b8d09f
...@@ -173,7 +173,8 @@ enum { ...@@ -173,7 +173,8 @@ enum {
AHCI_FLAG_COMMON = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | AHCI_FLAG_COMMON = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA | ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
ATA_FLAG_SKIP_D2H_BSY, ATA_FLAG_SKIP_D2H_BSY |
ATA_FLAG_ACPI_SATA,
}; };
struct ahci_cmd_hdr { struct ahci_cmd_hdr {
......
...@@ -321,7 +321,7 @@ static int do_drive_get_GTF(struct ata_device *dev, unsigned int *gtf_length, ...@@ -321,7 +321,7 @@ static int do_drive_get_GTF(struct ata_device *dev, unsigned int *gtf_length,
/* Don't continue if device has no _ADR method. /* Don't continue if device has no _ADR method.
* _GTF is intended for known motherboard devices. */ * _GTF is intended for known motherboard devices. */
if (!(ap->cbl == ATA_CBL_SATA)) { if (!(ap->flags & ATA_FLAG_ACPI_SATA)) {
err = pata_get_dev_handle(gdev, &dev_handle, &pcidevfn); err = pata_get_dev_handle(gdev, &dev_handle, &pcidevfn);
if (err < 0) { if (err < 0) {
if (ata_msg_probe(ap)) if (ata_msg_probe(ap))
...@@ -343,7 +343,7 @@ static int do_drive_get_GTF(struct ata_device *dev, unsigned int *gtf_length, ...@@ -343,7 +343,7 @@ static int do_drive_get_GTF(struct ata_device *dev, unsigned int *gtf_length,
/* Get this drive's _ADR info. if not already known. */ /* Get this drive's _ADR info. if not already known. */
if (!dev->obj_handle) { if (!dev->obj_handle) {
if (!(ap->cbl == ATA_CBL_SATA)) { if (!(ap->flags & ATA_FLAG_ACPI_SATA)) {
/* get child objects of dev_handle == channel objects, /* get child objects of dev_handle == channel objects,
* + _their_ children == drive objects */ * + _their_ children == drive objects */
/* channel is ap->port_no */ /* channel is ap->port_no */
...@@ -528,7 +528,7 @@ static int do_drive_set_taskfiles(struct ata_device *dev, ...@@ -528,7 +528,7 @@ static int do_drive_set_taskfiles(struct ata_device *dev,
ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER: port#: %d\n", ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER: port#: %d\n",
__FUNCTION__, ap->port_no); __FUNCTION__, ap->port_no);
if (libata_noacpi || !(ap->cbl == ATA_CBL_SATA)) if (libata_noacpi || !(ap->flags & ATA_FLAG_ACPI_SATA))
return 0; return 0;
if (!ata_dev_enabled(dev) || (ap->flags & ATA_FLAG_DISABLED)) if (!ata_dev_enabled(dev) || (ap->flags & ATA_FLAG_DISABLED))
...@@ -578,7 +578,7 @@ int ata_acpi_exec_tfs(struct ata_port *ap) ...@@ -578,7 +578,7 @@ int ata_acpi_exec_tfs(struct ata_port *ap)
* we should not run GTF on PATA devices since some * we should not run GTF on PATA devices since some
* PATA require execution of GTM/STM before GTF. * PATA require execution of GTM/STM before GTF.
*/ */
if (!(ap->cbl == ATA_CBL_SATA)) if (!(ap->flags & ATA_FLAG_ACPI_SATA))
return 0; return 0;
for (ix = 0; ix < ATA_MAX_DEVICES; ix++) { for (ix = 0; ix < ATA_MAX_DEVICES; ix++) {
...@@ -641,7 +641,7 @@ int ata_acpi_push_id(struct ata_device *dev) ...@@ -641,7 +641,7 @@ int ata_acpi_push_id(struct ata_device *dev)
__FUNCTION__, dev->devno, ap->port_no); __FUNCTION__, dev->devno, ap->port_no);
/* Don't continue if not a SATA device. */ /* Don't continue if not a SATA device. */
if (!(ap->cbl == ATA_CBL_SATA)) { if (!(ap->flags & ATA_FLAG_ACPI_SATA)) {
if (ata_msg_probe(ap)) if (ata_msg_probe(ap))
ata_dev_printk(dev, KERN_DEBUG, ata_dev_printk(dev, KERN_DEBUG,
"%s: Not a SATA device\n", __FUNCTION__); "%s: Not a SATA device\n", __FUNCTION__);
......
...@@ -1919,7 +1919,6 @@ int ata_dev_configure(struct ata_device *dev) ...@@ -1919,7 +1919,6 @@ int ata_dev_configure(struct ata_device *dev)
snprintf(revbuf, 7, "ATA-%d", ata_id_major_version(id)); snprintf(revbuf, 7, "ATA-%d", ata_id_major_version(id));
dev->n_sectors = ata_id_n_sectors(id); dev->n_sectors = ata_id_n_sectors(id);
dev->n_sectors_boot = dev->n_sectors;
/* SCSI only uses 4-char revisions, dump full 8 chars from ATA */ /* SCSI only uses 4-char revisions, dump full 8 chars from ATA */
ata_id_c_string(dev->id, fwrevbuf, ATA_ID_FW_REV, ata_id_c_string(dev->id, fwrevbuf, ATA_ID_FW_REV,
...@@ -3632,7 +3631,6 @@ static int ata_dev_same_device(struct ata_device *dev, unsigned int new_class, ...@@ -3632,7 +3631,6 @@ static int ata_dev_same_device(struct ata_device *dev, unsigned int new_class,
const u16 *old_id = dev->id; const u16 *old_id = dev->id;
unsigned char model[2][ATA_ID_PROD_LEN + 1]; unsigned char model[2][ATA_ID_PROD_LEN + 1];
unsigned char serial[2][ATA_ID_SERNO_LEN + 1]; unsigned char serial[2][ATA_ID_SERNO_LEN + 1];
u64 new_n_sectors;
if (dev->class != new_class) { if (dev->class != new_class) {
ata_dev_printk(dev, KERN_INFO, "class mismatch %d != %d\n", ata_dev_printk(dev, KERN_INFO, "class mismatch %d != %d\n",
...@@ -3644,7 +3642,6 @@ static int ata_dev_same_device(struct ata_device *dev, unsigned int new_class, ...@@ -3644,7 +3642,6 @@ static int ata_dev_same_device(struct ata_device *dev, unsigned int new_class,
ata_id_c_string(new_id, model[1], ATA_ID_PROD, sizeof(model[1])); ata_id_c_string(new_id, model[1], ATA_ID_PROD, sizeof(model[1]));
ata_id_c_string(old_id, serial[0], ATA_ID_SERNO, sizeof(serial[0])); ata_id_c_string(old_id, serial[0], ATA_ID_SERNO, sizeof(serial[0]));
ata_id_c_string(new_id, serial[1], ATA_ID_SERNO, sizeof(serial[1])); ata_id_c_string(new_id, serial[1], ATA_ID_SERNO, sizeof(serial[1]));
new_n_sectors = ata_id_n_sectors(new_id);
if (strcmp(model[0], model[1])) { if (strcmp(model[0], model[1])) {
ata_dev_printk(dev, KERN_INFO, "model number mismatch " ata_dev_printk(dev, KERN_INFO, "model number mismatch "
...@@ -3658,25 +3655,12 @@ static int ata_dev_same_device(struct ata_device *dev, unsigned int new_class, ...@@ -3658,25 +3655,12 @@ static int ata_dev_same_device(struct ata_device *dev, unsigned int new_class,
return 0; return 0;
} }
if (dev->class == ATA_DEV_ATA && dev->n_sectors != new_n_sectors) {
ata_dev_printk(dev, KERN_INFO, "n_sectors mismatch "
"%llu != %llu\n",
(unsigned long long)dev->n_sectors,
(unsigned long long)new_n_sectors);
/* Are we the boot time size - if so we appear to be the
same disk at this point and our HPA got reapplied */
if (ata_ignore_hpa && dev->n_sectors_boot == new_n_sectors
&& ata_id_hpa_enabled(new_id))
return 1;
return 0;
}
return 1; return 1;
} }
/** /**
* ata_dev_revalidate - Revalidate ATA device * ata_dev_reread_id - Re-read IDENTIFY data
* @dev: device to revalidate * @adev: target ATA device
* @readid_flags: read ID flags * @readid_flags: read ID flags
* *
* Re-read IDENTIFY page and make sure @dev is still attached to * Re-read IDENTIFY page and make sure @dev is still attached to
...@@ -3688,34 +3672,68 @@ static int ata_dev_same_device(struct ata_device *dev, unsigned int new_class, ...@@ -3688,34 +3672,68 @@ static int ata_dev_same_device(struct ata_device *dev, unsigned int new_class,
* RETURNS: * RETURNS:
* 0 on success, negative errno otherwise * 0 on success, negative errno otherwise
*/ */
int ata_dev_revalidate(struct ata_device *dev, unsigned int readid_flags) int ata_dev_reread_id(struct ata_device *dev, unsigned int readid_flags)
{ {
unsigned int class = dev->class; unsigned int class = dev->class;
u16 *id = (void *)dev->ap->sector_buf; u16 *id = (void *)dev->ap->sector_buf;
int rc; int rc;
if (!ata_dev_enabled(dev)) {
rc = -ENODEV;
goto fail;
}
/* read ID data */ /* read ID data */
rc = ata_dev_read_id(dev, &class, readid_flags, id); rc = ata_dev_read_id(dev, &class, readid_flags, id);
if (rc) if (rc)
goto fail; return rc;
/* is the device still there? */ /* is the device still there? */
if (!ata_dev_same_device(dev, class, id)) { if (!ata_dev_same_device(dev, class, id))
rc = -ENODEV; return -ENODEV;
goto fail;
}
memcpy(dev->id, id, sizeof(id[0]) * ATA_ID_WORDS); memcpy(dev->id, id, sizeof(id[0]) * ATA_ID_WORDS);
return 0;
}
/**
* ata_dev_revalidate - Revalidate ATA device
* @dev: device to revalidate
* @readid_flags: read ID flags
*
* Re-read IDENTIFY page, make sure @dev is still attached to the
* port and reconfigure it according to the new IDENTIFY page.
*
* LOCKING:
* Kernel thread context (may sleep)
*
* RETURNS:
* 0 on success, negative errno otherwise
*/
int ata_dev_revalidate(struct ata_device *dev, unsigned int readid_flags)
{
u64 n_sectors = dev->n_sectors;
int rc;
if (!ata_dev_enabled(dev))
return -ENODEV;
/* re-read ID */
rc = ata_dev_reread_id(dev, readid_flags);
if (rc)
goto fail;
/* configure device according to the new ID */ /* configure device according to the new ID */
rc = ata_dev_configure(dev); rc = ata_dev_configure(dev);
if (rc == 0) if (rc)
return 0; goto fail;
/* verify n_sectors hasn't changed */
if (dev->class == ATA_DEV_ATA && dev->n_sectors != n_sectors) {
ata_dev_printk(dev, KERN_INFO, "n_sectors mismatch "
"%llu != %llu\n",
(unsigned long long)n_sectors,
(unsigned long long)dev->n_sectors);
rc = -ENODEV;
goto fail;
}
return 0;
fail: fail:
ata_dev_printk(dev, KERN_ERR, "revalidation failed (errno=%d)\n", rc); ata_dev_printk(dev, KERN_ERR, "revalidation failed (errno=%d)\n", rc);
......
...@@ -893,6 +893,23 @@ int ata_scsi_change_queue_depth(struct scsi_device *sdev, int queue_depth) ...@@ -893,6 +893,23 @@ int ata_scsi_change_queue_depth(struct scsi_device *sdev, int queue_depth)
return queue_depth; return queue_depth;
} }
/* XXX: for ata_spindown_compat */
static void ata_delayed_done_timerfn(unsigned long arg)
{
struct scsi_cmnd *scmd = (void *)arg;
scmd->scsi_done(scmd);
}
/* XXX: for ata_spindown_compat */
static void ata_delayed_done(struct scsi_cmnd *scmd)
{
static struct timer_list timer;
setup_timer(&timer, ata_delayed_done_timerfn, (unsigned long)scmd);
mod_timer(&timer, jiffies + 5 * HZ);
}
/** /**
* ata_scsi_start_stop_xlat - Translate SCSI START STOP UNIT command * ata_scsi_start_stop_xlat - Translate SCSI START STOP UNIT command
* @qc: Storage for translated ATA taskfile * @qc: Storage for translated ATA taskfile
...@@ -950,21 +967,24 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc) ...@@ -950,21 +967,24 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc)
* for more info. * for more info.
*/ */
if (ata_spindown_compat && if (ata_spindown_compat &&
(qc->dev->flags & ATA_DFLAG_SPUNDOWN) &&
(system_state == SYSTEM_HALT || (system_state == SYSTEM_HALT ||
system_state == SYSTEM_POWER_OFF)) { system_state == SYSTEM_POWER_OFF)) {
static int warned = 0; static unsigned long warned = 0;
if (!warned) { if (!test_and_set_bit(0, &warned)) {
spin_unlock_irq(qc->ap->lock);
ata_dev_printk(qc->dev, KERN_WARNING, ata_dev_printk(qc->dev, KERN_WARNING,
"DISK MIGHT NOT BE SPUN DOWN PROPERLY. " "DISK MIGHT NOT BE SPUN DOWN PROPERLY. "
"UPDATE SHUTDOWN UTILITY\n"); "UPDATE SHUTDOWN UTILITY\n");
ata_dev_printk(qc->dev, KERN_WARNING, ata_dev_printk(qc->dev, KERN_WARNING,
"For more info, visit " "For more info, visit "
"http://linux-ata.org/shutdown.html\n"); "http://linux-ata.org/shutdown.html\n");
warned = 1;
ssleep(5); /* ->scsi_done is not used, use it for
spin_lock_irq(qc->ap->lock); * delayed completion.
*/
scmd->scsi_done = qc->scsidone;
qc->scsidone = ata_delayed_done;
} }
scmd->result = SAM_STAT_GOOD; scmd->result = SAM_STAT_GOOD;
return 1; return 1;
...@@ -1375,6 +1395,14 @@ static void ata_scsi_qc_complete(struct ata_queued_cmd *qc) ...@@ -1375,6 +1395,14 @@ static void ata_scsi_qc_complete(struct ata_queued_cmd *qc)
} }
} }
/* XXX: track spindown state for spindown_compat */
if (unlikely(qc->tf.command == ATA_CMD_STANDBY ||
qc->tf.command == ATA_CMD_STANDBYNOW1))
qc->dev->flags |= ATA_DFLAG_SPUNDOWN;
else if (likely(system_state != SYSTEM_HALT &&
system_state != SYSTEM_POWER_OFF))
qc->dev->flags &= ~ATA_DFLAG_SPUNDOWN;
if (need_sense && !ap->ops->error_handler) if (need_sense && !ap->ops->error_handler)
ata_dump_status(ap->print_id, &qc->result_tf); ata_dump_status(ap->print_id, &qc->result_tf);
...@@ -1488,14 +1516,14 @@ static int ata_scsi_translate(struct ata_device *dev, struct scsi_cmnd *cmd, ...@@ -1488,14 +1516,14 @@ static int ata_scsi_translate(struct ata_device *dev, struct scsi_cmnd *cmd,
early_finish: early_finish:
ata_qc_free(qc); ata_qc_free(qc);
done(cmd); qc->scsidone(cmd);
DPRINTK("EXIT - early finish (good or error)\n"); DPRINTK("EXIT - early finish (good or error)\n");
return 0; return 0;
err_did: err_did:
ata_qc_free(qc); ata_qc_free(qc);
cmd->result = (DID_ERROR << 16); cmd->result = (DID_ERROR << 16);
done(cmd); qc->scsidone(cmd);
err_mem: err_mem:
DPRINTK("EXIT - internal\n"); DPRINTK("EXIT - internal\n");
return 0; return 0;
......
...@@ -76,7 +76,8 @@ extern unsigned ata_exec_internal_sg(struct ata_device *dev, ...@@ -76,7 +76,8 @@ extern unsigned ata_exec_internal_sg(struct ata_device *dev,
extern unsigned int ata_do_simple_cmd(struct ata_device *dev, u8 cmd); extern unsigned int ata_do_simple_cmd(struct ata_device *dev, u8 cmd);
extern int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class, extern int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
unsigned int flags, u16 *id); unsigned int flags, u16 *id);
extern int ata_dev_revalidate(struct ata_device *dev, unsigned int flags); extern int ata_dev_reread_id(struct ata_device *dev, unsigned int readid_flags);
extern int ata_dev_revalidate(struct ata_device *dev, unsigned int readid_flags);
extern int ata_dev_configure(struct ata_device *dev); extern int ata_dev_configure(struct ata_device *dev);
extern int sata_down_spd_limit(struct ata_port *ap); extern int sata_down_spd_limit(struct ata_port *ap);
extern int sata_set_spd_needed(struct ata_port *ap); extern int sata_set_spd_needed(struct ata_port *ap);
......
...@@ -864,10 +864,10 @@ static void scc_bmdma_freeze (struct ata_port *ap) ...@@ -864,10 +864,10 @@ static void scc_bmdma_freeze (struct ata_port *ap)
* @ap: ATA port to be reset * @ap: ATA port to be reset
*/ */
static int scc_pata_prereset (struct ata_port *ap) static int scc_pata_prereset (struct ata_port *ap, unsigned long deadline)
{ {
ap->cbl = ATA_CBL_PATA80; ap->cbl = ATA_CBL_PATA80;
return ata_std_prereset(ap); return ata_std_prereset(ap, deadline);
} }
/** /**
......
...@@ -237,7 +237,8 @@ enum { ...@@ -237,7 +237,8 @@ enum {
/* host flags */ /* host flags */
SIL24_COMMON_FLAGS = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | SIL24_COMMON_FLAGS = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA | ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
ATA_FLAG_NCQ | ATA_FLAG_SKIP_D2H_BSY, ATA_FLAG_NCQ | ATA_FLAG_SKIP_D2H_BSY |
ATA_FLAG_ACPI_SATA,
SIL24_FLAG_PCIX_IRQ_WOC = (1 << 24), /* IRQ loss errata on PCI-X */ SIL24_FLAG_PCIX_IRQ_WOC = (1 << 24), /* IRQ loss errata on PCI-X */
IRQ_STAT_4PORTS = 0xf, IRQ_STAT_4PORTS = 0xf,
......
...@@ -140,6 +140,7 @@ enum { ...@@ -140,6 +140,7 @@ enum {
ATA_DFLAG_PIO = (1 << 8), /* device limited to PIO mode */ ATA_DFLAG_PIO = (1 << 8), /* device limited to PIO mode */
ATA_DFLAG_NCQ_OFF = (1 << 9), /* device limited to non-NCQ mode */ ATA_DFLAG_NCQ_OFF = (1 << 9), /* device limited to non-NCQ mode */
ATA_DFLAG_SPUNDOWN = (1 << 10), /* XXX: for spindown_compat */
ATA_DFLAG_INIT_MASK = (1 << 16) - 1, ATA_DFLAG_INIT_MASK = (1 << 16) - 1,
ATA_DFLAG_DETACH = (1 << 16), ATA_DFLAG_DETACH = (1 << 16),
...@@ -173,6 +174,7 @@ enum { ...@@ -173,6 +174,7 @@ enum {
ATA_FLAG_SETXFER_POLLING= (1 << 14), /* use polling for SETXFER */ ATA_FLAG_SETXFER_POLLING= (1 << 14), /* use polling for SETXFER */
ATA_FLAG_IGN_SIMPLEX = (1 << 15), /* ignore SIMPLEX */ ATA_FLAG_IGN_SIMPLEX = (1 << 15), /* ignore SIMPLEX */
ATA_FLAG_NO_IORDY = (1 << 16), /* controller lacks iordy */ ATA_FLAG_NO_IORDY = (1 << 16), /* controller lacks iordy */
ATA_FLAG_ACPI_SATA = (1 << 17), /* need native SATA ACPI layout */
/* The following flag belongs to ap->pflags but is kept in /* The following flag belongs to ap->pflags but is kept in
* ap->flags because it's referenced in many LLDs and will be * ap->flags because it's referenced in many LLDs and will be
...@@ -431,7 +433,6 @@ struct ata_device { ...@@ -431,7 +433,6 @@ struct ata_device {
struct scsi_device *sdev; /* attached SCSI device */ struct scsi_device *sdev; /* attached SCSI device */
/* n_sector is used as CLEAR_OFFSET, read comment above CLEAR_OFFSET */ /* n_sector is used as CLEAR_OFFSET, read comment above CLEAR_OFFSET */
u64 n_sectors; /* size of device, if ATA */ u64 n_sectors; /* size of device, if ATA */
u64 n_sectors_boot; /* size of ATA device at startup */
unsigned int class; /* ATA_DEV_xxx */ unsigned int class; /* ATA_DEV_xxx */
u16 id[ATA_ID_WORDS]; /* IDENTIFY xxx DEVICE data */ u16 id[ATA_ID_WORDS]; /* IDENTIFY xxx DEVICE data */
u8 pio_mode; u8 pio_mode;
......
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