Skip to content

Commit 2a559f4

Browse files
djbwJames Bottomley
authored andcommitted
[SCSI] libsas: sas_phy_enable via transport_sas_phy_reset
Execute the link-reset triggered by sas_phy_enable via transport_sas_phy_reset so that it can be managed by libata. Signed-off-by: Dan Williams <dan.j.williams@intel.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
1 parent 81c757b commit 2a559f4

File tree

4 files changed

+52
-10
lines changed

4 files changed

+52
-10
lines changed

drivers/scsi/libsas/sas_init.c

Lines changed: 49 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -249,15 +249,15 @@ static int transport_sas_phy_reset(struct sas_phy *phy, int hard_reset)
249249
return ret;
250250
}
251251

252-
int sas_phy_enable(struct sas_phy *phy, int enable)
252+
static int sas_phy_enable(struct sas_phy *phy, int enable)
253253
{
254254
int ret;
255-
enum phy_func command;
255+
enum phy_func cmd;
256256

257257
if (enable)
258-
command = PHY_FUNC_LINK_RESET;
258+
cmd = PHY_FUNC_LINK_RESET;
259259
else
260-
command = PHY_FUNC_DISABLE;
260+
cmd = PHY_FUNC_DISABLE;
261261

262262
if (scsi_is_sas_phy_local(phy)) {
263263
struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
@@ -266,15 +266,21 @@ int sas_phy_enable(struct sas_phy *phy, int enable)
266266
struct sas_internal *i =
267267
to_sas_internal(sas_ha->core.shost->transportt);
268268

269-
if (!enable) {
269+
if (enable)
270+
ret = transport_sas_phy_reset(phy, 0);
271+
else {
270272
sas_phy_disconnected(asd_phy);
271273
sas_ha->notify_phy_event(asd_phy, PHYE_LOSS_OF_SIGNAL);
274+
ret = i->dft->lldd_control_phy(asd_phy, cmd, NULL);
272275
}
273-
ret = i->dft->lldd_control_phy(asd_phy, command, NULL);
274276
} else {
275277
struct sas_rphy *rphy = dev_to_rphy(phy->dev.parent);
276278
struct domain_device *ddev = sas_find_dev_by_rphy(rphy);
277-
ret = sas_smp_phy_control(ddev, phy->number, command, NULL);
279+
280+
if (enable)
281+
ret = transport_sas_phy_reset(phy, 0);
282+
else
283+
ret = sas_smp_phy_control(ddev, phy->number, cmd, NULL);
278284
}
279285
return ret;
280286
}
@@ -357,6 +363,13 @@ static void phy_reset_work(struct work_struct *work)
357363
d->reset_result = transport_sas_phy_reset(d->phy, d->hard_reset);
358364
}
359365

366+
static void phy_enable_work(struct work_struct *work)
367+
{
368+
struct sas_phy_data *d = container_of(work, typeof(*d), enable_work);
369+
370+
d->enable_result = sas_phy_enable(d->phy, d->enable);
371+
}
372+
360373
static int sas_phy_setup(struct sas_phy *phy)
361374
{
362375
struct sas_phy_data *d = kzalloc(sizeof(*d), GFP_KERNEL);
@@ -366,6 +379,7 @@ static int sas_phy_setup(struct sas_phy *phy)
366379

367380
mutex_init(&d->event_lock);
368381
INIT_WORK(&d->reset_work, phy_reset_work);
382+
INIT_WORK(&d->enable_work, phy_enable_work);
369383
d->phy = phy;
370384
phy->hostdata = d;
371385

@@ -399,8 +413,35 @@ static int queue_phy_reset(struct sas_phy *phy, int hard_reset)
399413
return rc;
400414
}
401415

416+
static int queue_phy_enable(struct sas_phy *phy, int enable)
417+
{
418+
struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
419+
struct sas_ha_struct *ha = SHOST_TO_SAS_HA(shost);
420+
struct sas_phy_data *d = phy->hostdata;
421+
int rc;
422+
423+
if (!d)
424+
return -ENOMEM;
425+
426+
/* libsas workqueue coordinates ata-eh reset with discovery */
427+
mutex_lock(&d->event_lock);
428+
d->enable_result = 0;
429+
d->enable = enable;
430+
431+
spin_lock_irq(&ha->state_lock);
432+
sas_queue_work(ha, &d->enable_work);
433+
spin_unlock_irq(&ha->state_lock);
434+
435+
rc = sas_drain_work(ha);
436+
if (rc == 0)
437+
rc = d->enable_result;
438+
mutex_unlock(&d->event_lock);
439+
440+
return rc;
441+
}
442+
402443
static struct sas_function_template sft = {
403-
.phy_enable = sas_phy_enable,
444+
.phy_enable = queue_phy_enable,
404445
.phy_reset = queue_phy_reset,
405446
.phy_setup = sas_phy_setup,
406447
.phy_release = sas_phy_release,

drivers/scsi/libsas/sas_internal.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ struct sas_phy_data {
4545
int hard_reset;
4646
int reset_result;
4747
struct work_struct reset_work;
48+
int enable;
49+
int enable_result;
50+
struct work_struct enable_work;
4851
};
4952

5053
void sas_scsi_recover_host(struct Scsi_Host *shost);

drivers/scsi/libsas/sas_scsi_host.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1077,7 +1077,6 @@ EXPORT_SYMBOL_GPL(sas_change_queue_type);
10771077
EXPORT_SYMBOL_GPL(sas_bios_param);
10781078
EXPORT_SYMBOL_GPL(sas_task_abort);
10791079
EXPORT_SYMBOL_GPL(sas_phy_reset);
1080-
EXPORT_SYMBOL_GPL(sas_phy_enable);
10811080
EXPORT_SYMBOL_GPL(sas_eh_device_reset_handler);
10821081
EXPORT_SYMBOL_GPL(sas_eh_bus_reset_handler);
10831082
EXPORT_SYMBOL_GPL(sas_slave_alloc);

include/scsi/libsas.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -634,7 +634,6 @@ extern int sas_unregister_ha(struct sas_ha_struct *);
634634

635635
int sas_set_phy_speed(struct sas_phy *phy,
636636
struct sas_phy_linkrates *rates);
637-
int sas_phy_enable(struct sas_phy *phy, int enabled);
638637
int sas_phy_reset(struct sas_phy *phy, int hard_reset);
639638
int sas_queue_up(struct sas_task *task);
640639
extern int sas_queuecommand(struct Scsi_Host * ,struct scsi_cmnd *);

0 commit comments

Comments
 (0)