* [PATCH 4/4 v4] scsi:stex.c Add S3/S4 support
@ 2014-12-16 6:14 Charles Chiou
2014-12-16 9:34 ` Oliver Neukum
0 siblings, 1 reply; 3+ messages in thread
From: Charles Chiou @ 2014-12-16 6:14 UTC (permalink / raw)
To: Charles Chiou, Christoph Hellwig, JBottomley, Oliver Neukum
Cc: ed.lin, grace.chang, linus.chen, victor.p, linux-scsi,
linux-kernel
From f9d84df080c16097218092630db9b5df31d487b5 Mon Sep 17 00:00:00 2001
From: Charles Chiou <charles.chiou@tw.promise.com>
Date: Fri, 7 Nov 2014 10:15:18 +0800
Subject: [PATCH 4/4] scsi:stex.c Add S3/S4 support
Add S3/S4 support, add .suspend and .resume function in pci_driver.
Pegasus need 30~40 seconds to boot up. We don't want to OS wait
in .resume function. Create a thread to handle device boot up.
Signed-off-by: charles.chiou@tw.promise.com
---
drivers/scsi/stex.c | 65
++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 64 insertions(+), 1 deletion(-)
diff --git a/drivers/scsi/stex.c b/drivers/scsi/stex.c
index a536cfb..264dcd8 100644
--- a/drivers/scsi/stex.c
+++ b/drivers/scsi/stex.c
@@ -301,6 +301,11 @@ struct st_ccb {
u8 reserved[2];
};
+struct hba_handshake_workstruct {
+ struct st_hba *hba;
+ struct work_struct handshake_work;
+};
+
struct st_hba {
void __iomem *mmio_base; /* iomapped PCI memory space */
void *dma_mem;
@@ -328,6 +333,7 @@ struct st_hba {
char work_q_name[20];
struct workqueue_struct *work_q;
struct work_struct reset_work;
+ struct hba_handshake_workstruct *resumework;
wait_queue_head_t reset_waitq;
unsigned int mu_status;
unsigned int cardtype;
@@ -369,6 +375,8 @@ static const char console_inq_page[] =
0x0C,0x20,0x20,0x20,0x20,0x20,0x20,0x20
};
+
+
MODULE_AUTHOR("Ed Lin");
MODULE_DESCRIPTION("Promise Technology SuperTrak EX Controllers");
MODULE_LICENSE("GPL");
@@ -630,7 +638,7 @@ stex_queuecommand_lck(struct scsi_cmnd *cmd, void
(*done)(struct scsi_cmnd *))
done(cmd);
return 0;
}
- if (unlikely(hba->mu_status == MU_STATE_RESETTING))
+ if (unlikely(hba->mu_status != MU_STATE_STARTED))
return SCSI_MLQUEUE_HOST_BUSY;
switch (cmd->cmnd[0]) {
@@ -1397,6 +1405,19 @@ static void stex_reset_work(struct work_struct *work)
stex_do_reset(hba);
}
+
+static void resume_handshake(struct work_struct *work)
+{
+ struct st_hba *hba;
+ struct hba_handshake_workstruct *hswork;
+
+ hswork = container_of(work, struct hba_handshake_workstruct,
+ handshake_work);
+ hba = hswork->hba;
+ stex_handshake(hba);
+}
+
+
static int stex_biosparam(struct scsi_device *sdev,
struct block_device *bdev, sector_t capacity, int geom[])
{
@@ -1620,6 +1641,12 @@ static int stex_probe(struct pci_dev *pdev, const
struct pci_device_id *id)
goto out_iounmap;
}
+ hba->resumework = kzalloc(sizeof(struct hba_handshake_workstruct),
+ GFP_KERNEL);
+ hba->resumework->hba = hba;
+ INIT_WORK(&hba->resumework->handshake_work, resume_handshake);
+
+
hba->cardtype = (unsigned int) id->driver_data;
ci = &stex_card_info[hba->cardtype];
switch (id->subdevice) {
@@ -1875,6 +1902,40 @@ static void stex_shutdown(struct pci_dev *pdev)
}
}
+static int stex_choice_sleep_MIC(pm_message_t state)
+{
+ switch (state.event) {
+ case PM_EVENT_SUSPEND:
+ return ST_S3;
+ case PM_EVENT_FREEZE:
+ case PM_EVENT_HIBERNATE:
+ return ST_S4;
+ default:
+ return ST_S4;
+ }
+}
+
+static int stex_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+ struct st_hba *hba = pci_get_drvdata(pdev);
+
+ if (hba->cardtype == st_yel && hba->supports_pm == 1)
+ stex_hba_stop(hba, stex_choice_sleep_MIC(state));
+ else
+ stex_hba_stop(hba, ST_IGNORED);
+ return 0;
+}
+
+
+static int stex_resume(struct pci_dev *pdev)
+{
+ struct st_hba *hba = pci_get_drvdata(pdev);
+ int sts;
+
+ hba->mu_status = MU_STATE_STARTING;
+ sts = schedule_work(&hba->resumework->handshake_work);
+ return 0;
+}
MODULE_DEVICE_TABLE(pci, stex_pci_tbl);
static struct pci_driver stex_pci_driver = {
@@ -1883,6 +1944,8 @@ static struct pci_driver stex_pci_driver = {
.probe = stex_probe,
.remove = stex_remove,
.shutdown = stex_shutdown,
+ .suspend = stex_suspend,
+ .resume = stex_resume,
};
static struct notifier_block stex_reboot_notifier = {
--
1.9.1
^ permalink raw reply related [flat|nested] 3+ messages in thread* Re: [PATCH 4/4 v4] scsi:stex.c Add S3/S4 support
2014-12-16 6:14 [PATCH 4/4 v4] scsi:stex.c Add S3/S4 support Charles Chiou
@ 2014-12-16 9:34 ` Oliver Neukum
2014-12-18 3:09 ` Charles Chiou
0 siblings, 1 reply; 3+ messages in thread
From: Oliver Neukum @ 2014-12-16 9:34 UTC (permalink / raw)
To: Charles Chiou
Cc: Christoph Hellwig, JBottomley, ed.lin, grace.chang, linus.chen,
victor.p, linux-scsi, linux-kernel
On Tue, 2014-12-16 at 14:14 +0800, Charles Chiou wrote:
> From f9d84df080c16097218092630db9b5df31d487b5 Mon Sep 17 00:00:00 2001
> From: Charles Chiou <charles.chiou@tw.promise.com>
> Date: Fri, 7 Nov 2014 10:15:18 +0800
> Subject: [PATCH 4/4] scsi:stex.c Add S3/S4 support
>
> Add S3/S4 support, add .suspend and .resume function in pci_driver.
>
> Pegasus need 30~40 seconds to boot up. We don't want to OS wait
> in .resume function. Create a thread to handle device boot up.
I am sorry to be obnoxious, but this patch raises another
question. What happens if the the system is suspended again
while the work scheduled in resume is still running?
Furthermore, what happens in the case of a PCI hotunplug while
the work is still scheduled?
Regards
Oliver
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH 4/4 v4] scsi:stex.c Add S3/S4 support
2014-12-16 9:34 ` Oliver Neukum
@ 2014-12-18 3:09 ` Charles Chiou
0 siblings, 0 replies; 3+ messages in thread
From: Charles Chiou @ 2014-12-18 3:09 UTC (permalink / raw)
To: Oliver Neukum
Cc: Christoph Hellwig, JBottomley, ed.lin, grace.chang, linus.chen,
victor.p, linux-scsi, linux-kernel
On 12/16/2014 05:34 PM, Oliver Neukum wrote:
> On Tue, 2014-12-16 at 14:14 +0800, Charles Chiou wrote:
>> From f9d84df080c16097218092630db9b5df31d487b5 Mon Sep 17 00:00:00 2001
>> From: Charles Chiou <charles.chiou@tw.promise.com>
>> Date: Fri, 7 Nov 2014 10:15:18 +0800
>> Subject: [PATCH 4/4] scsi:stex.c Add S3/S4 support
>>
>> Add S3/S4 support, add .suspend and .resume function in pci_driver.
>>
>> Pegasus need 30~40 seconds to boot up. We don't want to OS wait
>> in .resume function. Create a thread to handle device boot up.
>
> I am sorry to be obnoxious, but this patch raises another
> question. What happens if the the system is suspended again
> while the work scheduled in resume is still running?
>
> Furthermore, what happens in the case of a PCI hotunplug while
> the work is still scheduled?
>
> Regards
> Oliver
>
>
Hi Oliver,
1. When OS is going to suspend again, .suspend function is active,
and driver prepare a command send to device, while firmware is
not ready. Firmware might loss this command and host can't go
to sleep. I'll fix this issue by add while loop to wait device
ready (polling hba->mu_status) and return -EBUSY if timeout.
I'll fix this issue in the next version. Thanks for your help.
2. When hotplug, .remove function is active. Return all commands to OS
with DID_NO_CONNECT status. And OS can remove the driver. After
experiment, it works well.
BRS
Charles
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2014-12-18 3:09 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-12-16 6:14 [PATCH 4/4 v4] scsi:stex.c Add S3/S4 support Charles Chiou
2014-12-16 9:34 ` Oliver Neukum
2014-12-18 3:09 ` Charles Chiou
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox