Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 21801
b: refs/heads/master
c: a62c0fc
h: refs/heads/master
i:
  21799: f469cd7
v: v3
  • Loading branch information
Tejun Heo authored and Jeff Garzik committed Jan 28, 2006
1 parent 582bad8 commit cbfd041
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: c19ba8af4f104cca28d548cac55c128b28dd31fb
refs/heads/master: a62c0fc526c344d8163f7a9e45e68cc63826ffd3
89 changes: 89 additions & 0 deletions trunk/drivers/scsi/libata-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -2233,6 +2233,94 @@ void ata_bus_reset(struct ata_port *ap)
DPRINTK("EXIT\n");
}

static int do_probe_reset(struct ata_port *ap, ata_reset_fn_t reset,
ata_postreset_fn_t postreset,
unsigned int *classes)
{
int i, rc;

for (i = 0; i < ATA_MAX_DEVICES; i++)
classes[i] = ATA_DEV_UNKNOWN;

rc = reset(ap, 0, classes);
if (rc)
return rc;

/* If any class isn't ATA_DEV_UNKNOWN, consider classification
* is complete and convert all ATA_DEV_UNKNOWN to
* ATA_DEV_NONE.
*/
for (i = 0; i < ATA_MAX_DEVICES; i++)
if (classes[i] != ATA_DEV_UNKNOWN)
break;

if (i < ATA_MAX_DEVICES)
for (i = 0; i < ATA_MAX_DEVICES; i++)
if (classes[i] == ATA_DEV_UNKNOWN)
classes[i] = ATA_DEV_NONE;

if (postreset)
postreset(ap, classes);

return classes[0] != ATA_DEV_UNKNOWN ? 0 : -ENODEV;
}

/**
* ata_drive_probe_reset - Perform probe reset with given methods
* @ap: port to reset
* @softreset: softreset method (can be NULL)
* @hardreset: hardreset method (can be NULL)
* @postreset: postreset method (can be NULL)
* @classes: resulting classes of attached devices
*
* Reset the specified port and classify attached devices using
* given methods. This function prefers softreset but tries all
* possible reset sequences to reset and classify devices. This
* function is intended to be used for constructing ->probe_reset
* callback by low level drivers.
*
* Reset methods should follow the following rules.
*
* - Return 0 on sucess, -errno on failure.
* - If classification is supported, fill classes[] with
* recognized class codes.
* - If classification is not supported, leave classes[] alone.
* - If verbose is non-zero, print error message on failure;
* otherwise, shut up.
*
* LOCKING:
* Kernel thread context (may sleep)
*
* RETURNS:
* 0 on success, -EINVAL if no reset method is avaliable, -ENODEV
* if classification fails, and any error code from reset
* methods.
*/
int ata_drive_probe_reset(struct ata_port *ap,
ata_reset_fn_t softreset, ata_reset_fn_t hardreset,
ata_postreset_fn_t postreset, unsigned int *classes)
{
int rc = -EINVAL;

if (softreset) {
rc = do_probe_reset(ap, softreset, postreset, classes);
if (rc == 0)
return 0;
}

if (!hardreset)
return rc;

rc = do_probe_reset(ap, hardreset, postreset, classes);
if (rc == 0 || rc != -ENODEV)
return rc;

if (softreset)
rc = do_probe_reset(ap, softreset, postreset, classes);

return rc;
}

static void ata_pr_blacklisted(const struct ata_port *ap,
const struct ata_device *dev)
{
Expand Down Expand Up @@ -5180,6 +5268,7 @@ EXPORT_SYMBOL_GPL(ata_port_probe);
EXPORT_SYMBOL_GPL(sata_phy_reset);
EXPORT_SYMBOL_GPL(__sata_phy_reset);
EXPORT_SYMBOL_GPL(ata_bus_reset);
EXPORT_SYMBOL_GPL(ata_drive_probe_reset);
EXPORT_SYMBOL_GPL(ata_port_disable);
EXPORT_SYMBOL_GPL(ata_ratelimit);
EXPORT_SYMBOL_GPL(ata_busy_sleep);
Expand Down
5 changes: 5 additions & 0 deletions trunk/include/linux/libata.h
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,8 @@ struct ata_queued_cmd;

/* typedefs */
typedef void (*ata_qc_cb_t) (struct ata_queued_cmd *qc);
typedef int (*ata_reset_fn_t)(struct ata_port *, int, unsigned int *);
typedef void (*ata_postreset_fn_t)(struct ata_port *ap, unsigned int *);

struct ata_ioports {
unsigned long cmd_addr;
Expand Down Expand Up @@ -478,6 +480,9 @@ extern void ata_port_probe(struct ata_port *);
extern void __sata_phy_reset(struct ata_port *ap);
extern void sata_phy_reset(struct ata_port *ap);
extern void ata_bus_reset(struct ata_port *ap);
extern int ata_drive_probe_reset(struct ata_port *ap,
ata_reset_fn_t softreset, ata_reset_fn_t hardreset,
ata_postreset_fn_t postreset, unsigned int *classes);
extern void ata_port_disable(struct ata_port *);
extern void ata_std_ports(struct ata_ioports *ioaddr);
#ifdef CONFIG_PCI
Expand Down

0 comments on commit cbfd041

Please sign in to comment.