Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 293027
b: refs/heads/master
c: 9508a66
h: refs/heads/master
i:
  293025: ad88902
  293023: dbb5886
v: v3
  • Loading branch information
Dan Williams authored and James Bottomley committed Feb 29, 2012
1 parent e9b5518 commit 8a9633a
Show file tree
Hide file tree
Showing 15 changed files with 124 additions and 67 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 92625f9bff3853951cc75f5bc084ee67c1317d2f
refs/heads/master: 9508a66f898d46e726a318469312b45e0b1d078b
34 changes: 18 additions & 16 deletions trunk/drivers/ata/libata-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -5936,29 +5936,31 @@ void ata_host_init(struct ata_host *host, struct device *dev,
host->ops = ops;
}

int ata_port_probe(struct ata_port *ap)
void __ata_port_probe(struct ata_port *ap)
{
int rc = 0;
struct ata_eh_info *ehi = &ap->link.eh_info;
unsigned long flags;

/* probe */
if (ap->ops->error_handler) {
struct ata_eh_info *ehi = &ap->link.eh_info;
unsigned long flags;
/* kick EH for boot probing */
spin_lock_irqsave(ap->lock, flags);

/* kick EH for boot probing */
spin_lock_irqsave(ap->lock, flags);
ehi->probe_mask |= ATA_ALL_DEVICES;
ehi->action |= ATA_EH_RESET;
ehi->flags |= ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET;

ehi->probe_mask |= ATA_ALL_DEVICES;
ehi->action |= ATA_EH_RESET;
ehi->flags |= ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET;
ap->pflags &= ~ATA_PFLAG_INITIALIZING;
ap->pflags |= ATA_PFLAG_LOADING;
ata_port_schedule_eh(ap);

ap->pflags &= ~ATA_PFLAG_INITIALIZING;
ap->pflags |= ATA_PFLAG_LOADING;
ata_port_schedule_eh(ap);
spin_unlock_irqrestore(ap->lock, flags);
}

spin_unlock_irqrestore(ap->lock, flags);
int ata_port_probe(struct ata_port *ap)
{
int rc = 0;

/* wait for EH to finish */
if (ap->ops->error_handler) {
__ata_port_probe(ap);
ata_port_wait_eh(ap);
} else {
DPRINTK("ata%u: bus probe begin\n", ap->print_id);
Expand Down
13 changes: 13 additions & 0 deletions trunk/drivers/ata/libata-scsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -3838,6 +3838,19 @@ void ata_sas_port_stop(struct ata_port *ap)
}
EXPORT_SYMBOL_GPL(ata_sas_port_stop);

int ata_sas_async_port_init(struct ata_port *ap)
{
int rc = ap->ops->port_start(ap);

if (!rc) {
ap->print_id = ata_print_id++;
__ata_port_probe(ap);
}

return rc;
}
EXPORT_SYMBOL_GPL(ata_sas_async_port_init);

/**
* ata_sas_port_init - Initialize a SATA device
* @ap: SATA port to initialize
Expand Down
1 change: 1 addition & 0 deletions trunk/drivers/ata/libata.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ extern int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg);
extern struct ata_port *ata_port_alloc(struct ata_host *host);
extern const char *sata_spd_string(unsigned int spd);
extern int ata_port_probe(struct ata_port *ap);
extern void __ata_port_probe(struct ata_port *ap);

/* libata-acpi.c */
#ifdef CONFIG_ATA_ACPI
Expand Down
1 change: 0 additions & 1 deletion trunk/drivers/scsi/aic94xx/aic94xx_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,6 @@ static struct scsi_host_template aic94xx_sht = {
.use_clustering = ENABLE_CLUSTERING,
.eh_device_reset_handler = sas_eh_device_reset_handler,
.eh_bus_reset_handler = sas_eh_bus_reset_handler,
.slave_alloc = sas_slave_alloc,
.target_destroy = sas_target_destroy,
.ioctl = sas_ioctl,
};
Expand Down
1 change: 0 additions & 1 deletion trunk/drivers/scsi/isci/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,6 @@ static struct scsi_host_template isci_sht = {
.sg_tablesize = SG_ALL,
.max_sectors = SCSI_DEFAULT_MAX_SECTORS,
.use_clustering = ENABLE_CLUSTERING,
.slave_alloc = sas_slave_alloc,
.target_destroy = sas_target_destroy,
.ioctl = sas_ioctl,
.shost_attrs = isci_host_attrs,
Expand Down
74 changes: 63 additions & 11 deletions trunk/drivers/scsi/libsas/sas_ata.c
Original file line number Diff line number Diff line change
Expand Up @@ -585,11 +585,10 @@ static struct ata_port_info sata_port_info = {
.port_ops = &sas_sata_ops
};

int sas_ata_init_host_and_port(struct domain_device *found_dev,
struct scsi_target *starget)
int sas_ata_init_host_and_port(struct domain_device *found_dev)
{
struct Scsi_Host *shost = dev_to_shost(&starget->dev);
struct sas_ha_struct *ha = SHOST_TO_SAS_HA(shost);
struct sas_ha_struct *ha = found_dev->port->ha;
struct Scsi_Host *shost = ha->core.shost;
struct ata_port *ap;

ata_host_init(&found_dev->sata_dev.ata_host,
Expand All @@ -607,6 +606,8 @@ int sas_ata_init_host_and_port(struct domain_device *found_dev,
ap->private_data = found_dev;
ap->cbl = ATA_CBL_SATA;
ap->scsi_host = shost;
/* publish initialized ata port */
smp_wmb();
found_dev->sata_dev.ap = ap;

return 0;
Expand Down Expand Up @@ -683,6 +684,38 @@ static void sas_get_ata_command_set(struct domain_device *dev)
dev->sata_dev.command_set = ATAPI_COMMAND_SET;
}

void sas_probe_sata(struct asd_sas_port *port)
{
struct domain_device *dev, *n;
int err;

mutex_lock(&port->ha->disco_mutex);
list_for_each_entry_safe(dev, n, &port->disco_list, disco_list_node) {
if (!dev_is_sata(dev))
continue;

err = sas_ata_init_host_and_port(dev);
if (err)
sas_fail_probe(dev, __func__, err);
else
ata_sas_async_port_init(dev->sata_dev.ap);
}
mutex_unlock(&port->ha->disco_mutex);

list_for_each_entry_safe(dev, n, &port->disco_list, disco_list_node) {
if (!dev_is_sata(dev))
continue;

sas_ata_wait_eh(dev);

/* if libata could not bring the link up, don't surface
* the device
*/
if (ata_dev_disabled(sas_to_ata_dev(dev)))
sas_fail_probe(dev, __func__, -ENODEV);
}
}

/**
* sas_discover_sata -- discover an STP/SATA domain device
* @dev: pointer to struct domain_device of interest
Expand Down Expand Up @@ -724,11 +757,23 @@ static void async_sas_ata_eh(void *data, async_cookie_t cookie)
sas_put_device(dev);
}

static bool sas_ata_dev_eh_valid(struct domain_device *dev)
{
struct ata_port *ap;

if (!dev_is_sata(dev))
return false;
ap = dev->sata_dev.ap;
/* consume fully initialized ata ports */
smp_rmb();
return !!ap;
}

void sas_ata_strategy_handler(struct Scsi_Host *shost)
{
struct scsi_device *sdev;
struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(shost);
LIST_HEAD(async);
int i;

/* it's ok to defer revalidation events during ata eh, these
* disks are in one of three states:
Expand All @@ -740,14 +785,21 @@ void sas_ata_strategy_handler(struct Scsi_Host *shost)
*/
sas_disable_revalidation(sas_ha);

shost_for_each_device(sdev, shost) {
struct domain_device *ddev = sdev_to_domain_dev(sdev);

if (!dev_is_sata(ddev))
continue;
spin_lock_irq(&sas_ha->phy_port_lock);
for (i = 0; i < sas_ha->num_phys; i++) {
struct asd_sas_port *port = sas_ha->sas_port[i];
struct domain_device *dev;

async_schedule_domain(async_sas_ata_eh, ddev, &async);
spin_lock(&port->dev_list_lock);
list_for_each_entry(dev, &port->dev_list, dev_list_node) {
if (!sas_ata_dev_eh_valid(dev))
continue;
async_schedule_domain(async_sas_ata_eh, dev, &async);
}
spin_unlock(&port->dev_list_lock);
}
spin_unlock_irq(&sas_ha->phy_port_lock);

async_synchronize_full_domain(&async);

sas_enable_revalidation(sas_ha);
Expand Down
22 changes: 11 additions & 11 deletions trunk/drivers/scsi/libsas/sas_discover.c
Original file line number Diff line number Diff line change
Expand Up @@ -207,22 +207,22 @@ static void sas_probe_devices(struct work_struct *work)

clear_bit(DISCE_PROBE, &port->disc.pending);

list_for_each_entry_safe(dev, n, &port->disco_list, disco_list_node) {
int err;

/* devices must be domain members before link recovery and probe */
list_for_each_entry(dev, &port->disco_list, disco_list_node) {
spin_lock_irq(&port->dev_list_lock);
list_add_tail(&dev->dev_list_node, &port->dev_list);
spin_unlock_irq(&port->dev_list_lock);
}

err = sas_rphy_add(dev->rphy);
sas_probe_sata(port);

if (err) {
SAS_DPRINTK("%s: for %s device %16llx returned %d\n",
__func__, dev->parent ? "exp-attached" :
"direct-attached",
SAS_ADDR(dev->sas_addr), err);
sas_unregister_dev(port, dev);
} else
list_for_each_entry_safe(dev, n, &port->disco_list, disco_list_node) {
int err;

err = sas_rphy_add(dev->rphy);
if (err)
sas_fail_probe(dev, __func__, err);
else
list_del_init(&dev->disco_list_node);
}
}
Expand Down
9 changes: 9 additions & 0 deletions trunk/drivers/scsi/libsas/sas_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,15 @@ static inline int sas_smp_host_handler(struct Scsi_Host *shost,
}
#endif

static inline void sas_fail_probe(struct domain_device *dev, const char *func, int err)
{
SAS_DPRINTK("%s: for %s device %16llx returned %d\n",
func, dev->parent ? "exp-attached" :
"direct-attached",
SAS_ADDR(dev->sas_addr), err);
sas_unregister_dev(dev->port, dev);
}

static inline void sas_fill_in_rphy(struct domain_device *dev,
struct sas_rphy *rphy)
{
Expand Down
18 changes: 0 additions & 18 deletions trunk/drivers/scsi/libsas/sas_scsi_host.c
Original file line number Diff line number Diff line change
Expand Up @@ -762,17 +762,10 @@ int sas_target_alloc(struct scsi_target *starget)
{
struct sas_rphy *rphy = dev_to_rphy(starget->dev.parent);
struct domain_device *found_dev = sas_find_dev_by_rphy(rphy);
int res;

if (!found_dev)
return -ENODEV;

if (dev_is_sata(found_dev)) {
res = sas_ata_init_host_and_port(found_dev, starget);
if (res)
return res;
}

kref_get(&found_dev->kref);
starget->hostdata = found_dev;
return 0;
Expand Down Expand Up @@ -1012,16 +1005,6 @@ void sas_task_abort(struct sas_task *task)
}
}

int sas_slave_alloc(struct scsi_device *scsi_dev)
{
struct domain_device *dev = sdev_to_domain_dev(scsi_dev);

if (dev_is_sata(dev))
return ata_sas_port_init(dev->sata_dev.ap);

return 0;
}

void sas_target_destroy(struct scsi_target *starget)
{
struct domain_device *found_dev = starget->hostdata;
Expand Down Expand Up @@ -1082,6 +1065,5 @@ EXPORT_SYMBOL_GPL(sas_task_abort);
EXPORT_SYMBOL_GPL(sas_phy_reset);
EXPORT_SYMBOL_GPL(sas_eh_device_reset_handler);
EXPORT_SYMBOL_GPL(sas_eh_bus_reset_handler);
EXPORT_SYMBOL_GPL(sas_slave_alloc);
EXPORT_SYMBOL_GPL(sas_target_destroy);
EXPORT_SYMBOL_GPL(sas_ioctl);
1 change: 0 additions & 1 deletion trunk/drivers/scsi/mvsas/mv_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@ static struct scsi_host_template mvs_sht = {
.use_clustering = ENABLE_CLUSTERING,
.eh_device_reset_handler = sas_eh_device_reset_handler,
.eh_bus_reset_handler = sas_eh_bus_reset_handler,
.slave_alloc = sas_slave_alloc,
.target_destroy = sas_target_destroy,
.ioctl = sas_ioctl,
.shost_attrs = mvst_host_attrs,
Expand Down
1 change: 0 additions & 1 deletion trunk/drivers/scsi/pm8001/pm8001_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@ static struct scsi_host_template pm8001_sht = {
.use_clustering = ENABLE_CLUSTERING,
.eh_device_reset_handler = sas_eh_device_reset_handler,
.eh_bus_reset_handler = sas_eh_bus_reset_handler,
.slave_alloc = sas_slave_alloc,
.target_destroy = sas_target_destroy,
.ioctl = sas_ioctl,
.shost_attrs = pm8001_host_attrs,
Expand Down
1 change: 1 addition & 0 deletions trunk/include/linux/libata.h
Original file line number Diff line number Diff line change
Expand Up @@ -996,6 +996,7 @@ extern int ata_sas_scsi_ioctl(struct ata_port *ap, struct scsi_device *dev,
extern void ata_sas_port_destroy(struct ata_port *);
extern struct ata_port *ata_sas_port_alloc(struct ata_host *,
struct ata_port_info *, struct Scsi_Host *);
extern int ata_sas_async_port_init(struct ata_port *);
extern int ata_sas_port_init(struct ata_port *);
extern int ata_sas_port_start(struct ata_port *ap);
extern void ata_sas_port_stop(struct ata_port *ap);
Expand Down
1 change: 0 additions & 1 deletion trunk/include/scsi/libsas.h
Original file line number Diff line number Diff line change
Expand Up @@ -646,7 +646,6 @@ int sas_phy_reset(struct sas_phy *phy, int hard_reset);
int sas_queue_up(struct sas_task *task);
extern int sas_queuecommand(struct Scsi_Host * ,struct scsi_cmnd *);
extern int sas_target_alloc(struct scsi_target *);
extern int sas_slave_alloc(struct scsi_device *);
extern int sas_slave_configure(struct scsi_device *);
extern int sas_change_queue_depth(struct scsi_device *, int new_depth,
int reason);
Expand Down
12 changes: 7 additions & 5 deletions trunk/include/scsi/sas_ata.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,24 +37,22 @@ static inline int dev_is_sata(struct domain_device *dev)
}

int sas_get_ata_info(struct domain_device *dev, struct ex_phy *phy);
int sas_ata_init_host_and_port(struct domain_device *found_dev,
struct scsi_target *starget);

int sas_ata_init_host_and_port(struct domain_device *found_dev);
void sas_ata_task_abort(struct sas_task *task);
void sas_ata_strategy_handler(struct Scsi_Host *shost);
void sas_ata_eh(struct Scsi_Host *shost, struct list_head *work_q,
struct list_head *done_q);
void sas_ata_schedule_reset(struct domain_device *dev);
void sas_ata_wait_eh(struct domain_device *dev);
void sas_probe_sata(struct asd_sas_port *port);
#else


static inline int dev_is_sata(struct domain_device *dev)
{
return 0;
}
static inline int sas_ata_init_host_and_port(struct domain_device *found_dev,
struct scsi_target *starget)
static inline int sas_ata_init_host_and_port(struct domain_device *found_dev)
{
return 0;
}
Expand All @@ -79,6 +77,10 @@ static inline void sas_ata_wait_eh(struct domain_device *dev)
{
}

static inline void sas_probe_sata(struct asd_sas_port *port)
{
}

static inline int sas_get_ata_info(struct domain_device *dev, struct ex_phy *phy)
{
return 0;
Expand Down

0 comments on commit 8a9633a

Please sign in to comment.