Skip to content

Commit

Permalink
Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/k…
Browse files Browse the repository at this point in the history
…ernel/git/jgarzik/libata-dev

* 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/libata-dev: (28 commits)
  drivers/ata: trim trailing whitespace
  Fixups to ATA ACPI hotplug
  libata: ignore SIMG4726 config pseudo device
  sata_sil24: don't use NCQ if marvell 4140 PMP is attached
  libata: don't schedule LPM action seperately during probing
  libata: make sure PMP notification is turned off during recovery
  libata: increase PMP register access timeout to 3s
  libata: ignore recovered PHY errors
  libata: kill hotplug related race condition
  libata: move reset freeze/thaw handling into ata_eh_reset()
  libata: reorganize ata_eh_reset() no reset method path
  libata: fix sata_link_hardreset() @online out parameter handling
  sata_promise: other cleanups
  sata_promise: mmio access cleanups
  sata_promise: fix irq clearing buglets
  ata: remove FIT() macro
  sata_mv: ensure empty request queue for FBS-NCQ EH
  sata_mv: cache main_irq_mask register in hpriv
  sata_mv: disregard masked irqs
  sata_mv: fix pmp drives not found
  ...
  • Loading branch information
Linus Torvalds committed May 19, 2008
2 parents 8c4bab3 + c85665f commit 88e6c94
Show file tree
Hide file tree
Showing 21 changed files with 453 additions and 384 deletions.
75 changes: 49 additions & 26 deletions drivers/ata/libata-acpi.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,48 +118,76 @@ static void ata_acpi_associate_ide_port(struct ata_port *ap)
ap->pflags |= ATA_PFLAG_INIT_GTM_VALID;
}

static void ata_acpi_handle_hotplug(struct ata_port *ap, struct ata_device *dev,
u32 event)
static void ata_acpi_handle_hotplug(struct ata_port *ap, struct ata_device
*dev, u32 event)
{
char event_string[12];
char *envp[] = { event_string, NULL };
struct ata_eh_info *ehi;
struct kobject *kobj = NULL;
int wait = 0;
unsigned long flags;
acpi_handle handle, tmphandle;
unsigned long sta;
acpi_status status;

if (!ap)
ap = dev->link->ap;
ehi = &ap->link.eh_info;

spin_lock_irqsave(ap->lock, flags);

if (dev)
handle = dev->acpi_handle;
else
handle = ap->acpi_handle;

status = acpi_get_handle(handle, "_EJ0", &tmphandle);
if (ACPI_FAILURE(status)) {
/* This device is not ejectable */
spin_unlock_irqrestore(ap->lock, flags);
return;
}

status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
if (ACPI_FAILURE(status)) {
printk ("Unable to determine bay status\n");
spin_unlock_irqrestore(ap->lock, flags);
return;
}

switch (event) {
case ACPI_NOTIFY_BUS_CHECK:
case ACPI_NOTIFY_DEVICE_CHECK:
ata_ehi_push_desc(ehi, "ACPI event");
ata_ehi_hotplugged(ehi);
ata_port_freeze(ap);
break;

case ACPI_NOTIFY_EJECT_REQUEST:
ata_ehi_push_desc(ehi, "ACPI event");
if (dev)
dev->flags |= ATA_DFLAG_DETACH;
else {
struct ata_link *tlink;
struct ata_device *tdev;

ata_port_for_each_link(tlink, ap)
ata_link_for_each_dev(tdev, tlink)
tdev->flags |= ATA_DFLAG_DETACH;
if (!sta) {
/* Device has been unplugged */
if (dev)
dev->flags |= ATA_DFLAG_DETACH;
else {
struct ata_link *tlink;
struct ata_device *tdev;

ata_port_for_each_link(tlink, ap) {
ata_link_for_each_dev(tdev, tlink) {
tdev->flags |=
ATA_DFLAG_DETACH;
}
}
}
ata_port_schedule_eh(ap);
wait = 1;
} else {
ata_ehi_hotplugged(ehi);
ata_port_freeze(ap);
}

ata_port_schedule_eh(ap);
wait = 1;
break;
}

spin_unlock_irqrestore(ap->lock, flags);

if (wait)
ata_port_wait_eh(ap);

if (dev) {
if (dev->sdev)
kobj = &dev->sdev->sdev_gendev.kobj;
Expand All @@ -170,11 +198,6 @@ static void ata_acpi_handle_hotplug(struct ata_port *ap, struct ata_device *dev,
sprintf(event_string, "BAY_EVENT=%d", event);
kobject_uevent_env(kobj, KOBJ_CHANGE, envp);
}

spin_unlock_irqrestore(ap->lock, flags);

if (wait)
ata_port_wait_eh(ap);
}

static void ata_acpi_dev_notify(acpi_handle handle, u32 event, void *data)
Expand Down
40 changes: 22 additions & 18 deletions drivers/ata/libata-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -2126,6 +2126,13 @@ int ata_dev_configure(struct ata_device *dev)
dev->horkage |= ata_dev_blacklisted(dev);
ata_force_horkage(dev);

if (dev->horkage & ATA_HORKAGE_DISABLE) {
ata_dev_printk(dev, KERN_INFO,
"unsupported device, disabling\n");
ata_dev_disable(dev);
return 0;
}

/* let ACPI work its magic */
rc = ata_acpi_on_devcfg(dev);
if (rc)
Expand Down Expand Up @@ -3490,22 +3497,11 @@ int sata_link_resume(struct ata_link *link, const unsigned long *params,
if ((rc = sata_link_debounce(link, params, deadline)))
return rc;

/* Clear SError. PMP and some host PHYs require this to
* operate and clearing should be done before checking PHY
* online status to avoid race condition (hotplugging between
* link resume and status check).
*/
/* clear SError, some PHYs require this even for SRST to work */
if (!(rc = sata_scr_read(link, SCR_ERROR, &serror)))
rc = sata_scr_write(link, SCR_ERROR, serror);
if (rc == 0 || rc == -EINVAL) {
unsigned long flags;

spin_lock_irqsave(link->ap->lock, flags);
link->eh_info.serror = 0;
spin_unlock_irqrestore(link->ap->lock, flags);
rc = 0;
}
return rc;
return rc != -EINVAL ? rc : 0;
}

/**
Expand Down Expand Up @@ -3653,9 +3649,13 @@ int sata_link_hardreset(struct ata_link *link, const unsigned long *timing,
if (check_ready)
rc = ata_wait_ready(link, deadline, check_ready);
out:
if (rc && rc != -EAGAIN)
if (rc && rc != -EAGAIN) {
/* online is set iff link is online && reset succeeded */
if (online)
*online = false;
ata_link_printk(link, KERN_ERR,
"COMRESET failed (errno=%d)\n", rc);
}
DPRINTK("EXIT, rc=%d\n", rc);
return rc;
}
Expand Down Expand Up @@ -3700,8 +3700,14 @@ int sata_std_hardreset(struct ata_link *link, unsigned int *class,
*/
void ata_std_postreset(struct ata_link *link, unsigned int *classes)
{
u32 serror;

DPRINTK("ENTER\n");

/* reset complete, clear SError */
if (!sata_scr_read(link, SCR_ERROR, &serror))
sata_scr_write(link, SCR_ERROR, serror);

/* print link status */
sata_print_link_status(link);

Expand Down Expand Up @@ -3894,8 +3900,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
{ "SAMSUNG CD-ROM SN-124", "N001", ATA_HORKAGE_NODMA },
{ "Seagate STT20000A", NULL, ATA_HORKAGE_NODMA },
/* Odd clown on sil3726/4726 PMPs */
{ "Config Disk", NULL, ATA_HORKAGE_NODMA |
ATA_HORKAGE_SKIP_PM },
{ "Config Disk", NULL, ATA_HORKAGE_DISABLE },

/* Weird ATAPI devices */
{ "TORiSAN DVD-ROM DRD-N216", NULL, ATA_HORKAGE_MAX_SEC_128 },
Expand Down Expand Up @@ -5616,7 +5621,7 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
spin_lock_irqsave(ap->lock, flags);

ehi->probe_mask |= ATA_ALL_DEVICES;
ehi->action |= ATA_EH_RESET;
ehi->action |= ATA_EH_RESET | ATA_EH_LPM;
ehi->flags |= ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET;

ap->pflags &= ~ATA_PFLAG_INITIALIZING;
Expand Down Expand Up @@ -5649,7 +5654,6 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
struct ata_port *ap = host->ports[i];

ata_scsi_scan_host(ap, 1);
ata_lpm_schedule(ap, ap->pm_policy);
}

return 0;
Expand Down
Loading

0 comments on commit 88e6c94

Please sign in to comment.