[PATCH v3 0/5] Migrate SCSI drivers to use dev_pm_ops

2012-10-12 Thread Aaron Lu
v3:
Only patch 4 is modified:
Remove the special case for system freeze in scsi_bus_suspend_common
as pointed out by Alan Stern;
Updated some comments;
Removed the use of typedef (*pm_callback_t)(struct device *).

v2:
Change the runtime suspend behaviour of sd driver by putting the device
into stopped power state.
Revert 2 patches which are no longer needed as pointed out by Alan Stern.
Find out device callbacks in bus callbacks as suggested by Alan Stern.

Due to these changes, patch number grows from 2 - 5.

v1:
The 2 patches will migrate SCSI drivers to use the pm callbacks defined
in dev_pm_ops as pm_message is deprecated and should not be used by driver.
Bus level callback is changed to use callbacks defined in dev_pm_ops when
needed and sd's pm callback is updated to use what are defined in dev_pm_ops.

Aaron Lu (5):
  sd: put to stopped power state when runtime suspend
  Revert [SCSI] scsi_pm: set device runtime state before parent
suspended
  Revert [SCSI] runtime resume parent for child's system-resume
  pm: use callbacks from dev_pm_ops for scsi devices
  sd: update sd to use the new pm callbacks

 drivers/scsi/scsi_pm.c | 97 +++---
 drivers/scsi/sd.c  | 18 +++---
 2 files changed, 66 insertions(+), 49 deletions(-)

-- 
1.7.12.21.g871e293

--
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 1/5] sd: put to stopped power state when runtime suspend

2012-10-12 Thread Aaron Lu
When device is runtime suspended, put it to stopped power state to save
some power.

This will also make the behaviour consistent with what the scsi_pm.c
thinks about sd as the comment says:
sd treats runtime suspend, system suspend and system hibernate identical.
With this patch, it is now identical.
And sd_shutdown will also do nothing when it finds the device has been
runtime suspended, if we do not spin down the disk in runtime suspend
by putting it into stopped power state, the disk will be shut down
incorrectly.
And the the same problem can be solved for runtime power off after
runtime suspended case by this change.

With the current runtime scheme for disk, it will only be runtime
suspended when no process opens the disk, so this shouldn't happen a
lot, which makes it acceptable to spin down the disk when runtime
suspended. If some day a more aggressive runtime scheme is used, like
the 'request based runtime pm for disk' that Alan Stern and Lin Ming
has been working, we can introduce some policy to control this. But for
now, make it simple and correct by spinning down the disk.

Signed-off-by: Aaron Lu aaron...@intel.com
---
 drivers/scsi/sd.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 12f6fdf..8b6e004 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -2911,7 +2911,8 @@ static int sd_suspend(struct device *dev, pm_message_t 
mesg)
goto done;
}
 
-   if ((mesg.event  PM_EVENT_SLEEP)  sdkp-device-manage_start_stop) {
+   if (((mesg.event  PM_EVENT_SLEEP) || PMSG_IS_AUTO(mesg)) 
+   sdkp-device-manage_start_stop) {
sd_printk(KERN_NOTICE, sdkp, Stopping disk\n);
ret = sd_start_stop_device(sdkp, 0);
}
-- 
1.7.12.21.g871e293

--
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 3/5] Revert [SCSI] runtime resume parent for child's system-resume

2012-10-12 Thread Aaron Lu
This reverts commit 28fd00d42cca178638f51c08efa986a777c24a4b.

With commit 88d26136a256576e444db312179e17af6dd0ea87 (PM: Prevent
runtime suspend during system resume), this patch is no longer needed.

Signed-off-by: Aaron Lu aaron...@intel.com
---
 drivers/scsi/scsi_pm.c | 11 +--
 1 file changed, 1 insertion(+), 10 deletions(-)

diff --git a/drivers/scsi/scsi_pm.c b/drivers/scsi/scsi_pm.c
index d4201de..9923b26 100644
--- a/drivers/scsi/scsi_pm.c
+++ b/drivers/scsi/scsi_pm.c
@@ -76,17 +76,8 @@ static int scsi_bus_resume_common(struct device *dev)
 {
int err = 0;
 
-   if (scsi_is_sdev_device(dev)) {
-   /*
-* Parent device may have runtime suspended as soon as
-* it is woken up during the system resume.
-*
-* Resume it on behalf of child.
-*/
-   pm_runtime_get_sync(dev-parent);
+   if (scsi_is_sdev_device(dev))
err = scsi_dev_type_resume(dev);
-   pm_runtime_put_sync(dev-parent);
-   }
 
if (err == 0) {
pm_runtime_disable(dev);
-- 
1.7.12.21.g871e293

--
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 5/5] sd: update sd to use the new pm callbacks

2012-10-12 Thread Aaron Lu
Update sd driver to use the callbacks defined in dev_pm_ops.

sd_freeze is NULL, the bus level callback has taken care of quiescing
the device so there should be nothing needs to be done here.
Consequently, sd_thaw is not needed here either.

suspend, poweroff and runtime suspend share the same routine sd_suspend,
which will sync flush and then stop the drive, this is the same as before.

resume, restore and runtime resume share the same routine sd_resume,
which will start the drive by putting it into active power state, this
is also the same as before.

Signed-off-by: Aaron Lu aaron...@intel.com
---
 drivers/scsi/sd.c | 19 +--
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 8b6e004..6564305 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -104,7 +104,7 @@ static void sd_unlock_native_capacity(struct gendisk *disk);
 static int  sd_probe(struct device *);
 static int  sd_remove(struct device *);
 static void sd_shutdown(struct device *);
-static int sd_suspend(struct device *, pm_message_t state);
+static int sd_suspend(struct device *);
 static int sd_resume(struct device *);
 static void sd_rescan(struct device *);
 static int sd_done(struct scsi_cmnd *);
@@ -423,15 +423,23 @@ static struct class sd_disk_class = {
.dev_attrs  = sd_disk_attrs,
 };
 
+static const struct dev_pm_ops sd_pm_ops = {
+   .suspend= sd_suspend,
+   .resume = sd_resume,
+   .poweroff   = sd_suspend,
+   .restore= sd_resume,
+   .runtime_suspend= sd_suspend,
+   .runtime_resume = sd_resume,
+};
+
 static struct scsi_driver sd_template = {
.owner  = THIS_MODULE,
.gendrv = {
.name   = sd,
.probe  = sd_probe,
.remove = sd_remove,
-   .suspend= sd_suspend,
-   .resume = sd_resume,
.shutdown   = sd_shutdown,
+   .pm = sd_pm_ops,
},
.rescan = sd_rescan,
.done   = sd_done,
@@ -2896,7 +2904,7 @@ exit:
scsi_disk_put(sdkp);
 }
 
-static int sd_suspend(struct device *dev, pm_message_t mesg)
+static int sd_suspend(struct device *dev)
 {
struct scsi_disk *sdkp = scsi_disk_get_from_dev(dev);
int ret = 0;
@@ -2911,8 +2919,7 @@ static int sd_suspend(struct device *dev, pm_message_t 
mesg)
goto done;
}
 
-   if (((mesg.event  PM_EVENT_SLEEP) || PMSG_IS_AUTO(mesg)) 
-   sdkp-device-manage_start_stop) {
+   if (sdkp-device-manage_start_stop) {
sd_printk(KERN_NOTICE, sdkp, Stopping disk\n);
ret = sd_start_stop_device(sdkp, 0);
}
-- 
1.7.12.21.g871e293

--
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 4/5] pm: use callbacks from dev_pm_ops for scsi devices

2012-10-12 Thread Aaron Lu
Use of pm_message_t is deprecated and device driver is not supposed
to use that. This patch tries to migrate the SCSI bus level pm callbacks
to call device's pm callbacks defined in its driver's dev_pm_ops.

This is achieved by finding out which device pm callback should be used
in bus callback function, and then pass that callback function pointer
as a param to the scsi_bus_{suspend,resume}_common routine, which will
further pass that callback to scsi_dev_type_{suspend,resume} after
proper handling.

The special case for freeze in scsi_bus_suspend_common is not necessary
since there is no high level SCSI driver has implemented freeze, so no
need to runtime resume the device if it is in runtime suspended state
for system freeze, just return like the system suspend/hibernate case.

Since only sd has implemented drv-suspend/drv-resume, and I'll update
sd driver to use the new callbacks in the following patch, there is no
need to fallback to call drv-suspend/drv-resume if dev_pm_ops is NULL.

Signed-off-by: Aaron Lu aaron...@intel.com
---
 drivers/scsi/scsi_pm.c | 85 ++
 1 file changed, 52 insertions(+), 33 deletions(-)

diff --git a/drivers/scsi/scsi_pm.c b/drivers/scsi/scsi_pm.c
index 9923b26..6e70a16 100644
--- a/drivers/scsi/scsi_pm.c
+++ b/drivers/scsi/scsi_pm.c
@@ -16,16 +16,14 @@
 
 #include scsi_priv.h
 
-static int scsi_dev_type_suspend(struct device *dev, pm_message_t msg)
+static int scsi_dev_type_suspend(struct device *dev, int (*cb)(struct device 
*))
 {
-   struct device_driver *drv;
int err;
 
err = scsi_device_quiesce(to_scsi_device(dev));
if (err == 0) {
-   drv = dev-driver;
-   if (drv  drv-suspend) {
-   err = drv-suspend(dev, msg);
+   if (cb) {
+   err = cb(dev);
if (err)
scsi_device_resume(to_scsi_device(dev));
}
@@ -34,14 +32,12 @@ static int scsi_dev_type_suspend(struct device *dev, 
pm_message_t msg)
return err;
 }
 
-static int scsi_dev_type_resume(struct device *dev)
+static int scsi_dev_type_resume(struct device *dev, int (*cb)(struct device *))
 {
-   struct device_driver *drv;
int err = 0;
 
-   drv = dev-driver;
-   if (drv  drv-resume)
-   err = drv-resume(dev);
+   if (cb)
+   err = cb(dev);
scsi_device_resume(to_scsi_device(dev));
dev_dbg(dev, scsi resume: %d\n, err);
return err;
@@ -49,35 +45,33 @@ static int scsi_dev_type_resume(struct device *dev)
 
 #ifdef CONFIG_PM_SLEEP
 
-static int scsi_bus_suspend_common(struct device *dev, pm_message_t msg)
+static int
+scsi_bus_suspend_common(struct device *dev, int (*cb)(struct device *))
 {
int err = 0;
 
if (scsi_is_sdev_device(dev)) {
/*
-* sd is the only high-level SCSI driver to implement runtime
-* PM, and sd treats runtime suspend, system suspend, and
-* system hibernate identically (but not system freeze).
+* All the high-level SCSI drivers that implement runtime
+* PM treat runtime suspend, system suspend, and system
+* hibernate identically.
 */
-   if (pm_runtime_suspended(dev)) {
-   if (msg.event == PM_EVENT_SUSPEND ||
-   msg.event == PM_EVENT_HIBERNATE)
-   return 0;   /* already suspended */
+   if (pm_runtime_suspended(dev))
+   return 0;
 
-   /* wake up device so that FREEZE will succeed */
-   pm_runtime_resume(dev);
-   }
-   err = scsi_dev_type_suspend(dev, msg);
+   err = scsi_dev_type_suspend(dev, cb);
}
+
return err;
 }
 
-static int scsi_bus_resume_common(struct device *dev)
+static int
+scsi_bus_resume_common(struct device *dev, int (*cb)(struct device *))
 {
int err = 0;
 
if (scsi_is_sdev_device(dev))
-   err = scsi_dev_type_resume(dev);
+   err = scsi_dev_type_resume(dev, cb);
 
if (err == 0) {
pm_runtime_disable(dev);
@@ -102,26 +96,49 @@ static int scsi_bus_prepare(struct device *dev)
 
 static int scsi_bus_suspend(struct device *dev)
 {
-   return scsi_bus_suspend_common(dev, PMSG_SUSPEND);
+   const struct dev_pm_ops *pm = dev-driver ? dev-driver-pm : NULL;
+   return scsi_bus_suspend_common(dev, pm ? pm-suspend : NULL);
+}
+
+static int scsi_bus_resume(struct device *dev)
+{
+   const struct dev_pm_ops *pm = dev-driver ? dev-driver-pm : NULL;
+   return scsi_bus_resume_common(dev, pm ? pm-resume : NULL);
 }
 
 static int scsi_bus_freeze(struct device *dev)
 {
-   return scsi_bus_suspend_common(dev, PMSG_FREEZE);
+   const struct dev_pm_ops *pm = dev-driver 

[PATCH 00/10] scsi: avoid linebreaks in syslog output

2012-10-12 Thread Hannes Reinecke
This patchset updates the SCSI midlayer to use dev_printk() instead
of the simple printk(). The main objective here is to avoid line-breaks
in syslog output; with the current state it's nearly impossible to match
the output to the occurring device; under high load even the CDB will
be split off into individual bytes, spread randomly across the lines.
Which makes debugging via scsi_logging_level _really_ hard.
In addition we'll be getting the syslog messages nicely prefixed with
the device, which will make userspace logging daemons happy.

Before:
[  297.300605] sd 2:0:3:2: Send: 
[  297.300607] 0x8802348b0980 
[  297.300610] sd 2:0:3:2: CDB: 
[  297.300615] Test Unit Ready: 00 00 00 00 00 00
[  297.300747] sd 2:0:3:2: Done: 
[  297.300750] 0x8802348b0980 SUCCESS
[  297.300753] sd 2:0:3:2:  
[  297.300755] Result: hostbyte=DID_OK driverbyte=DRIVER_OK
[  297.300758] sd 2:0:3:2: CDB: 
[  297.300764] Test Unit Ready: 00 00 00 00 00 00
[  297.300766] sd 2:0:3:2:  
[  297.300769] Sense Key : Unit Attention [current] 
[  297.300771] Info fld=0x0
[  297.300772] sd 2:0:3:2:  
[  297.300776] Add. Sense: Capacity data has changed

After:
[  636.683556] sd 2:0:3:2: Send: 0x88043145eec0
[  636.727856] sd 2:0:3:2: CDB: Test Unit Ready: 00 00 00 00 00 00
[  636.785330] sd 2:0:3:2: Done: 0x88043145eec0 SUCCESS
[  636.838228] sd 2:0:3:2: Result: hostbyte=DID_OK driverbyte=DRIVER_OK
[  636.899099] sd 2:0:3:2: CDB: Test Unit Ready: 00 00 00 00 00 00
[  636.955905] sd 2:0:3:2: Sense Key : Unit Attention [current] 
[  637.069179] sd 2:0:3:2: Add. Sense: Capacity data has changed


Hannes Reinecke (10):
  sg: Use dev_printk
  sr: Use dev_printk()
  scsi: Avoid linebreaks in syslog output
  scsi: Use sdev_printk() for logging
  scsi: use buffer for print_opcode_name()
  scsi: use single printk call in scsi_print_command()
  scsi: use buffer for scsi_show_result()
  scsi: open-code scsi_decode_sense_buffer()
  scsi: decode descriptor sense
  scsi: use local buffer for decoding sense data

 drivers/scsi/constants.c  |  406 +
 drivers/scsi/scsi.c   |   54 ---
 drivers/scsi/scsi_error.c |  190 ++---
 drivers/scsi/scsi_lib.c   |   13 +-
 drivers/scsi/scsi_scan.c  |   68 
 drivers/scsi/sd.c |   16 +-
 drivers/scsi/sg.c |  187 -
 drivers/scsi/sr.c |   47 +++---
 drivers/scsi/sr.h |4 +
 include/scsi/scsi_dbg.h   |6 +-
 include/scsi/scsi_eh.h|8 +-
 11 files changed, 588 insertions(+), 411 deletions(-)

-- 
1.7.4.2

--
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 01/10] sg: Use dev_printk

2012-10-12 Thread Hannes Reinecke
Every sg device has a reference to the underlying scsi device, so
this patch adds dev_printk() macros to have the messages prefixed
with the correct device.

Before:
[772330.437378] sg_open: dev=2, flags=0x8800
[772330.475425] sg_add_sfp: sfp=0x880429d3e000

After:
[  409.399888] sr 2:0:0:0: [sg2] sg_open: flags=0x8800
[  409.446029] sr 2:0:0:0: [sg2] sg_add_sfp: sfp=0x880425856000

Cc: Kay Sievers k...@vrfy.org
Cc: Doug Gilbert dgilb...@interlog.com
Signed-off-by: Hannes Reinecke h...@suse.de
---
 drivers/scsi/sg.c |  187 +++--
 1 files changed, 109 insertions(+), 78 deletions(-)

diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 9c5c5f2..2e6056f 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -101,6 +101,13 @@ static int scatter_elem_sz_prev = SG_SCATTER_SZ;
 
 #define SG_SECTOR_SZ 512
 
+#define sgdev_printk(prefix, sgdev, fmt, a...) \
+   dev_printk(prefix, (sgdev)-device-sdev_gendev, [%s]  fmt, \
+  (sgdev)-disk-disk_name, ##a)
+
+#define sgfp_printk(prefix, sgfp, fmt, a...)   \
+   sgdev_printk(prefix, (sgfp)-parentdp, fmt, ##a)
+
 static int sg_add(struct device *, struct class_interface *);
 static void sg_remove(struct device *, struct class_interface *);
 
@@ -196,7 +203,7 @@ static ssize_t sg_new_write(Sg_fd *sfp, struct file *file,
 static int sg_common_write(Sg_fd * sfp, Sg_request * srp,
   unsigned char *cmnd, int timeout, int blocking);
 static int sg_read_oxfer(Sg_request * srp, char __user *outp, int 
num_read_xfer);
-static void sg_remove_scat(Sg_scatter_hold * schp);
+static void sg_remove_scat(Sg_scatter_hold * schp, Sg_fd * sfp);
 static void sg_build_reserve(Sg_fd * sfp, int req_size);
 static void sg_link_reserve(Sg_fd * sfp, Sg_request * srp, int size);
 static void sg_unlink_reserve(Sg_fd * sfp, Sg_request * srp);
@@ -268,13 +275,14 @@ sg_open(struct inode *inode, struct file *filp)
int retval;
 
nonseekable_open(inode, filp);
-   SCSI_LOG_TIMEOUT(3, printk(sg_open: dev=%d, flags=0x%x\n, dev, 
flags));
sdp = sg_get_dev(dev);
if (IS_ERR(sdp)) {
retval = PTR_ERR(sdp);
sdp = NULL;
goto sg_put;
}
+   SCSI_LOG_TIMEOUT(3, sgdev_printk(KERN_INFO, sdp,
+sg_open: flags=0x%x\n, flags));
 
/* This driver's module count bumped by fops_get in linux/fs.h */
/* Prevent the device driver from vanishing while we sleep */
@@ -360,7 +368,7 @@ sg_release(struct inode *inode, struct file *filp)
 
if ((!(sfp = (Sg_fd *) filp-private_data)) || (!(sdp = sfp-parentdp)))
return -ENXIO;
-   SCSI_LOG_TIMEOUT(3, printk(sg_release: %s\n, sdp-disk-disk_name));
+   SCSI_LOG_TIMEOUT(3, sgdev_printk(KERN_INFO, sdp, sg_release));
 
set_exclude(sdp, 0);
wake_up_interruptible(sdp-o_excl_wait);
@@ -383,8 +391,8 @@ sg_read(struct file *filp, char __user *buf, size_t count, 
loff_t * ppos)
 
if ((!(sfp = (Sg_fd *) filp-private_data)) || (!(sdp = sfp-parentdp)))
return -ENXIO;
-   SCSI_LOG_TIMEOUT(3, printk(sg_read: %s, count=%d\n,
-  sdp-disk-disk_name, (int) count));
+   SCSI_LOG_TIMEOUT(3, sgdev_printk(KERN_INFO, sdp, sg_read: count=%d,
+(int) count));
 
if (!access_ok(VERIFY_WRITE, buf, count))
return -EFAULT;
@@ -569,8 +577,8 @@ sg_write(struct file *filp, const char __user *buf, size_t 
count, loff_t * ppos)
 
if ((!(sfp = (Sg_fd *) filp-private_data)) || (!(sdp = sfp-parentdp)))
return -ENXIO;
-   SCSI_LOG_TIMEOUT(3, printk(sg_write: %s, count=%d\n,
-  sdp-disk-disk_name, (int) count));
+   SCSI_LOG_TIMEOUT(3, sgdev_printk(KERN_INFO, sdp, sg_write: count=%d,
+(int) count));
if (sdp-detached)
return -ENODEV;
if (!((filp-f_flags  O_NONBLOCK) ||
@@ -591,14 +599,17 @@ sg_write(struct file *filp, const char __user *buf, 
size_t count, loff_t * ppos)
return -EIO;/* The minimum scsi command length is 6 bytes. 
*/
 
if (!(srp = sg_add_request(sfp))) {
-   SCSI_LOG_TIMEOUT(1, printk(sg_write: queue full\n));
+   SCSI_LOG_TIMEOUT(1, sgdev_printk(KERN_INFO, sdp,
+sg_write: queue full));
return -EDOM;
}
buf += SZ_SG_HEADER;
__get_user(opcode, buf);
if (sfp-next_cmd_len  0) {
if (sfp-next_cmd_len  MAX_COMMAND_SIZE) {
-   SCSI_LOG_TIMEOUT(1, printk(sg_write: command length 
too long\n));
+   SCSI_LOG_TIMEOUT(1, sgdev_printk(KERN_INFO, sdp,
+sg_write: command 
+   

[PATCH 03/10] scsi: Avoid linebreaks in syslog output

2012-10-12 Thread Hannes Reinecke
sdev_printk() is adding a linebreak automatically, causing the
syslog output to be garbled:
[  542.494393] sr 2:0:0:0: Send:
[  542.494394] 0x8804291e5dc0
which will make debuggging painful.
So reshuffle sdev_printk invokation to have it printed on
the same line.

Cc: Kay Sievers k...@vrfy.org
Signed-off-by: Hannes Reinecke h...@suse.de
---
 drivers/scsi/scsi.c |   38 ++
 1 files changed, 22 insertions(+), 16 deletions(-)

diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index 2936b44..28b294b 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -551,14 +551,15 @@ void scsi_log_send(struct scsi_cmnd *cmd)
level = SCSI_LOG_LEVEL(SCSI_LOG_MLQUEUE_SHIFT,
   SCSI_LOG_MLQUEUE_BITS);
if (level  1) {
-   scmd_printk(KERN_INFO, cmd, Send: );
if (level  2)
-   printk(0x%p , cmd);
-   printk(\n);
+   scmd_printk(KERN_INFO, cmd, Send: 0x%p, cmd);
+   else
+   scmd_printk(KERN_INFO, cmd, Send:);
scsi_print_command(cmd);
if (level  3) {
-   printk(KERN_INFO buffer = 0x%p, bufflen = %d,
-   queuecommand 0x%p\n,
+   scmd_printk(KERN_INFO, cmd,
+  buffer = 0x%p, bufflen = %d,
+   queuecommand 0x%p,
scsi_sglist(cmd), scsi_bufflen(cmd),
cmd-device-host-hostt-queuecommand);
 
@@ -588,42 +589,47 @@ void scsi_log_completion(struct scsi_cmnd *cmd, int 
disposition)
   SCSI_LOG_MLCOMPLETE_BITS);
if (((level  0)  (cmd-result || disposition != SUCCESS)) ||
(level  1)) {
-   scmd_printk(KERN_INFO, cmd, Done: );
-   if (level  2)
-   printk(0x%p , cmd);
+   const char *disp_str;
+
/*
 * Dump truncated values, so we usually fit within
 * 80 chars.
 */
switch (disposition) {
case SUCCESS:
-   printk(SUCCESS\n);
+   disp_str = SUCCESS;
break;
case NEEDS_RETRY:
-   printk(RETRY\n);
+   disp_str = RETRY;
break;
case ADD_TO_MLQUEUE:
-   printk(MLQUEUE\n);
+   disp_str = MLQUEUE;
break;
case FAILED:
-   printk(FAILED\n);
+   disp_str = FAILED;
break;
case TIMEOUT_ERROR:
-   /* 
+   /*
 * If called via scsi_times_out.
 */
-   printk(TIMEOUT\n);
+   disp_str = TIMEOUT;
break;
default:
-   printk(UNKNOWN\n);
+   disp_str = UNKNOWN;
}
+   if (level  2)
+   scmd_printk(KERN_INFO, cmd, Done: 0x%p %s,
+   cmd, disp_str);
+   else
+   scmd_printk(KERN_INFO, cmd, Done: %s,
+   disp_str);
scsi_print_result(cmd);
scsi_print_command(cmd);
if (status_byte(cmd-result)  CHECK_CONDITION)
scsi_print_sense(, cmd);
if (level  3)
scmd_printk(KERN_INFO, cmd,
-   scsi host busy %d failed %d\n,
+   scsi host busy %d failed %d,
cmd-device-host-host_busy,
cmd-device-host-host_failed);
}
-- 
1.7.4.2

--
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 02/10] sr: Use dev_printk()

2012-10-12 Thread Hannes Reinecke
Convert sr to use dev_printk() to avoid linebreaks in kernel
messages.

Cc: Kay Sievers k...@vrfy.org
Cc: Jens Axboe ax...@kernel.dk
Signed-off-by: Hannes Reinecke h...@suse.de
---
 drivers/scsi/sr.c |   47 ++-
 drivers/scsi/sr.h |4 
 2 files changed, 30 insertions(+), 21 deletions(-)

diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c
index 5fc97d2..26404ca 100644
--- a/drivers/scsi/sr.c
+++ b/drivers/scsi/sr.c
@@ -276,8 +276,8 @@ do_tur:
if (!cd-tur_changed) {
if (cd-get_event_changed) {
if (cd-tur_mismatch++  8) {
-   sdev_printk(KERN_WARNING, cd-device,
-   GET_EVENT and TUR disagree 
continuously, suppress GET_EVENT events\n);
+   sr_printk(KERN_WARNING, cd,
+ GET_EVENT and TUR disagree 
continuously, suppress GET_EVENT events\n);
cd-ignore_get_event = true;
}
} else {
@@ -306,7 +306,7 @@ static int sr_done(struct scsi_cmnd *SCpnt)
struct scsi_cd *cd = scsi_cd(SCpnt-request-rq_disk);
 
 #ifdef DEBUG
-   printk(sr.c done: %x\n, result);
+   sr_printk(KERN_INFO, cd, sr.c done: %x\n, result);
 #endif
 
/*
@@ -389,13 +389,16 @@ static int sr_prep_fn(struct request_queue *q, struct 
request *rq)
 * is used for a killable error condition */
ret = BLKPREP_KILL;
 
-   SCSI_LOG_HLQUEUE(1, printk(Doing sr request, dev = %s, block = %d\n,
-   cd-disk-disk_name, block));
+   SCSI_LOG_HLQUEUE(1,
+   scmd_printk(KERN_INFO, SCpnt,
+   Doing sr request, block = %d\n, block));
 
if (!cd-device || !scsi_device_online(cd-device)) {
-   SCSI_LOG_HLQUEUE(2, printk(Finishing %u sectors\n,
-  blk_rq_sectors(rq)));
-   SCSI_LOG_HLQUEUE(2, printk(Retry with 0x%p\n, SCpnt));
+   SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt,
+   Finishing %u sectors\n,
+ blk_rq_sectors(rq)));
+   SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt,
+   Retry with 0x%p\n, SCpnt));
goto out;
}
 
@@ -416,7 +419,8 @@ static int sr_prep_fn(struct request_queue *q, struct 
request *rq)
if (!in_interrupt())
sr_set_blocklength(cd, 2048);
else
-   printk(sr: can't switch blocksize: in interrupt\n);
+   scmd_printk(KERN_INFO, SCpnt,
+ sr: can't switch blocksize: in interrupt\n);
}
 
if (s_size != 512  s_size != 1024  s_size != 2048) {
@@ -429,7 +433,7 @@ static int sr_prep_fn(struct request_queue *q, struct 
request *rq)
goto out;
SCpnt-cmnd[0] = WRITE_10;
SCpnt-sc_data_direction = DMA_TO_DEVICE;
-   cd-cdi.media_written = 1;
+   cd-cdi.media_written = 1;
} else if (rq_data_dir(rq) == READ) {
SCpnt-cmnd[0] = READ_10;
SCpnt-sc_data_direction = DMA_FROM_DEVICE;
@@ -447,8 +451,8 @@ static int sr_prep_fn(struct request_queue *q, struct 
request *rq)
 
if (size != scsi_bufflen(SCpnt)) {
scmd_printk(KERN_ERR, SCpnt,
-   mismatch count %d, bytes %d\n,
-   size, scsi_bufflen(SCpnt));
+   mismatch count %d, bytes %d\n,
+   size, scsi_bufflen(SCpnt));
if (scsi_bufflen(SCpnt)  size)
SCpnt-sdb.length = size;
}
@@ -466,11 +470,11 @@ static int sr_prep_fn(struct request_queue *q, struct 
request *rq)
this_count = (scsi_bufflen(SCpnt)  9) / (s_size  9);
 
 
-   SCSI_LOG_HLQUEUE(2, printk(%s : %s %d/%u 512 byte blocks.\n,
-   cd-cdi.name,
-   (rq_data_dir(rq) == WRITE) ?
-   writing : reading,
-   this_count, blk_rq_sectors(rq)));
+   SCSI_LOG_HLQUEUE(2, sr_printk(KERN_INFO, cd,
+ %s %d/%u 512 byte blocks.\n,
+ (rq_data_dir(rq) == WRITE) ?
+ writing : reading,
+ this_count, blk_rq_sectors(rq)));
 
SCpnt-cmnd[1] = 0;
block = (unsigned int)blk_rq_pos(rq) / (s_size  9);
@@ -790,8 +794,9 @@ static void get_sectorsize(struct scsi_cd *cd)
case 512:
break;
default:
-   

[PATCH 05/10] scsi: use buffer for print_opcode_name()

2012-10-12 Thread Hannes Reinecke
Instead of printing directly to syslog print_opcode_name() should
be using a private buffer to avoid linebreaks during printout.

Cc: Kay Sievers k...@vrfy.org
Signed-off-by: Hannes Reinecke h...@suse.de
---
 drivers/scsi/constants.c |   98 +++--
 1 files changed, 59 insertions(+), 39 deletions(-)

diff --git a/drivers/scsi/constants.c b/drivers/scsi/constants.c
index 76e4c03..b469798 100644
--- a/drivers/scsi/constants.c
+++ b/drivers/scsi/constants.c
@@ -204,9 +204,10 @@ static const char * get_sa_name(const struct 
value_name_pair * arr,
 }
 
 /* attempt to guess cdb length if cdb_len==0 . No trailing linefeed. */
-static void print_opcode_name(unsigned char * cdbp, int cdb_len)
+static int print_opcode_name(char *buf, int buf_len,
+ unsigned char *cdbp, int cdb_len)
 {
-   int sa, len, cdb0;
+   int sa, len, cdb0, sz = 0;
const char * name;
 
cdb0 = cdbp[0];
@@ -214,101 +215,119 @@ static void print_opcode_name(unsigned char * cdbp, int 
cdb_len)
case VARIABLE_LENGTH_CMD:
len = scsi_varlen_cdb_length(cdbp);
if (len  10) {
-   printk(short variable length command, 
-  len=%d ext_len=%d, len, cdb_len);
-   break;
+   sz = snprintf(buf, buf_len,
+ short variable length command, 
+ len=%d ext_len=%d, len, cdb_len);
+   return sz;
}
sa = (cdbp[8]  8) + cdbp[9];
name = get_sa_name(variable_length_arr, VARIABLE_LENGTH_SZ, sa);
if (name)
-   printk(%s, name);
+   sz = snprintf(buf, buf_len, %s, name);
else
-   printk(cdb[0]=0x%x, sa=0x%x, cdb0, sa);
+   sz = snprintf(buf, buf_len, cdb[0]=0x%x, sa=0x%x,
+ cdb0, sa);
 
if ((cdb_len  0)  (len != cdb_len))
-   printk(, in_cdb_len=%d, ext_len=%d, len, cdb_len);
+   sz = snprintf(buf + sz, buf_len - sz,
+ , in_cdb_len=%d, ext_len=%d,
+ len, cdb_len);
 
break;
case MAINTENANCE_IN:
sa = cdbp[1]  0x1f;
name = get_sa_name(maint_in_arr, MAINT_IN_SZ, sa);
if (name)
-   printk(%s, name);
+   sz = snprintf(buf, buf_len, %s, name);
else
-   printk(cdb[0]=0x%x, sa=0x%x, cdb0, sa);
+   sz = snprintf(buf, buf_len, cdb[0]=0x%x, sa=0x%x,
+ cdb0, sa);
break;
case MAINTENANCE_OUT:
sa = cdbp[1]  0x1f;
name = get_sa_name(maint_out_arr, MAINT_OUT_SZ, sa);
if (name)
-   printk(%s, name);
+   sz = snprintf(buf, buf_len, %s, name);
else
-   printk(cdb[0]=0x%x, sa=0x%x, cdb0, sa);
+   sz = snprintf(buf, buf_len, cdb[0]=0x%x, sa=0x%x,
+ cdb0, sa);
break;
case SERVICE_ACTION_IN_12:
sa = cdbp[1]  0x1f;
name = get_sa_name(serv_in12_arr, SERV_IN12_SZ, sa);
if (name)
-   printk(%s, name);
+   sz = snprintf(buf, buf_len, %s, name);
else
-   printk(cdb[0]=0x%x, sa=0x%x, cdb0, sa);
+   sz = snprintf(buf, buf_len, cdb[0]=0x%x, sa=0x%x,
+ cdb0, sa);
break;
case SERVICE_ACTION_OUT_12:
sa = cdbp[1]  0x1f;
name = get_sa_name(serv_out12_arr, SERV_OUT12_SZ, sa);
if (name)
-   printk(%s, name);
+   sz = snprintf(buf, buf_len, %s, name);
else
-   printk(cdb[0]=0x%x, sa=0x%x, cdb0, sa);
+   sz = snprintf(buf, buf_len, cdb[0]=0x%x, sa=0x%x,
+ cdb0, sa);
break;
case SERVICE_ACTION_IN_16:
sa = cdbp[1]  0x1f;
name = get_sa_name(serv_in16_arr, SERV_IN16_SZ, sa);
if (name)
-   printk(%s, name);
+   sz = snprintf(buf, buf_len, %s, name);
else
-   printk(cdb[0]=0x%x, sa=0x%x, cdb0, sa);
+   sz = snprintf(buf, buf_len, cdb[0]=0x%x, sa=0x%x,
+ cdb0, sa);
break;
case SERVICE_ACTION_OUT_16:
sa = cdbp[1]  0x1f;
name = 

[PATCH 07/10] scsi: use buffer for scsi_show_result()

2012-10-12 Thread Hannes Reinecke
scsi_show_result() should be printing the message into a supplied
buffer to avoid linebreaks during output.

Cc: Kay Sievers k...@vrfy.org
Signed-off-by: Hannes Reinecke h...@suse.de
---
 drivers/scsi/constants.c |   23 +--
 drivers/scsi/sd.c|6 --
 include/scsi/scsi_dbg.h  |2 +-
 3 files changed, 18 insertions(+), 13 deletions(-)

diff --git a/drivers/scsi/constants.c b/drivers/scsi/constants.c
index 65367e8..ded16d9 100644
--- a/drivers/scsi/constants.c
+++ b/drivers/scsi/constants.c
@@ -1502,32 +1502,35 @@ static const char * const driverbyte_table[]={
 DRIVER_INVALID, DRIVER_TIMEOUT, DRIVER_HARD, DRIVER_SENSE};
 #define NUM_DRIVERBYTE_STRS ARRAY_SIZE(driverbyte_table)
 
-void scsi_show_result(int result)
+void scsi_show_result(char *buf, int buf_size, int result)
 {
int hb = host_byte(result);
int db = driver_byte(result);
 
-   printk(Result: hostbyte=%s driverbyte=%s\n,
-  (hb  NUM_HOSTBYTE_STRS ? hostbyte_table[hb] : invalid),
-  (db  NUM_DRIVERBYTE_STRS ? driverbyte_table[db] : invalid));
+   snprintf(buf, buf_size,
+   Result: hostbyte=%s driverbyte=%s\n,
+   (hb  NUM_HOSTBYTE_STRS ? hostbyte_table[hb] : invalid),
+   (db  NUM_DRIVERBYTE_STRS ? driverbyte_table[db] : invalid));
 }
 
 #else
 
-void scsi_show_result(int result)
+void scsi_show_result(char *buf, int buf_size, int result)
 {
-   printk(Result: hostbyte=0x%02x driverbyte=0x%02x\n,
-  host_byte(result), driver_byte(result));
+   snprintf(buf, buf_size,
+Result: hostbyte=0x%02x driverbyte=0x%02x\n,
+host_byte(result), driver_byte(result));
 }
 
 #endif
 EXPORT_SYMBOL(scsi_show_result);
 
-
 void scsi_print_result(struct scsi_cmnd *cmd)
 {
-   scmd_printk(KERN_INFO, cmd,  );
-   scsi_show_result(cmd-result);
+   char result_buf[70];
+
+   scsi_show_result(result_buf, 70, cmd-result);
+   scmd_printk(KERN_INFO, cmd, %s, result_buf);
 }
 EXPORT_SYMBOL(scsi_print_result);
 
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 12f6fdf..f6165e6 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -3025,7 +3025,9 @@ static void sd_print_sense_hdr(struct scsi_disk *sdkp,
 
 static void sd_print_result(struct scsi_disk *sdkp, int result)
 {
-   sd_printk(KERN_INFO, sdkp,  );
-   scsi_show_result(result);
+   char result_buf[70];
+
+   scsi_show_result(result_buf, 70, result);
+   sd_printk(KERN_INFO, sdkp, %s, result_buf);
 }
 
diff --git a/include/scsi/scsi_dbg.h b/include/scsi/scsi_dbg.h
index e89844c..cc6abb4 100644
--- a/include/scsi/scsi_dbg.h
+++ b/include/scsi/scsi_dbg.h
@@ -15,7 +15,7 @@ extern void scsi_print_sense(char *, struct scsi_cmnd *);
 extern void __scsi_print_sense(const char *name,
   const unsigned char *sense_buffer,
   int sense_len);
-extern void scsi_show_result(int);
+extern void scsi_show_result(char *, int, int);
 extern void scsi_print_result(struct scsi_cmnd *);
 extern void scsi_print_status(unsigned char);
 extern const char *scsi_sense_key_string(unsigned char);
-- 
1.7.4.2

--
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 08/10] scsi: open-code scsi_decode_sense_buffer()

2012-10-12 Thread Hannes Reinecke
Pointless, and actually wrong as there is no point in trying
to decode invalid sense data.

Cc: Kay Sievers k...@vrfy.org
Signed-off-by: Hannes Reinecke h...@suse.de
---
 drivers/scsi/constants.c |   43 +--
 1 files changed, 17 insertions(+), 26 deletions(-)

diff --git a/drivers/scsi/constants.c b/drivers/scsi/constants.c
index ded16d9..8bf2616 100644
--- a/drivers/scsi/constants.c
+++ b/drivers/scsi/constants.c
@@ -1373,29 +1373,6 @@ scsi_cmd_print_sense_hdr(struct scsi_cmnd *scmd, const 
char *desc,
 EXPORT_SYMBOL(scsi_cmd_print_sense_hdr);
 
 static void
-scsi_decode_sense_buffer(const unsigned char *sense_buffer, int sense_len,
-  struct scsi_sense_hdr *sshdr)
-{
-   int k, num, res;
-
-   res = scsi_normalize_sense(sense_buffer, sense_len, sshdr);
-   if (0 == res) {
-   /* this may be SCSI-1 sense data */
-   num = (sense_len  32) ? sense_len : 32;
-   printk(Unrecognized sense data (in hex):);
-   for (k = 0; k  num; ++k) {
-   if (0 == (k % 16)) {
-   printk(\n);
-   printk(KERN_INFO );
-   }
-   printk(%02x , sense_buffer[k]);
-   }
-   printk(\n);
-   return;
-   }
-}
-
-static void
 scsi_decode_sense_extras(const unsigned char *sense_buffer, int sense_len,
 struct scsi_sense_hdr *sshdr)
 {
@@ -1462,8 +1439,15 @@ void __scsi_print_sense(const char *name, const unsigned 
char *sense_buffer,
 {
struct scsi_sense_hdr sshdr;
 
+   if (!scsi_normalize_sense(sense_buffer, sense_len, sshdr)) {
+   /* this may be SCSI-1 sense data */
+   int num = (sense_len  32) ? sense_len : 32;
+   pr_info(%s: Unrecognized sense data (in hex):, name);
+   print_hex_dump(KERN_INFO, , DUMP_PREFIX_OFFSET,
+  16, 1, sense_buffer, num, false);
+   return;
+   }
printk(KERN_INFO %s: , name);
-   scsi_decode_sense_buffer(sense_buffer, sense_len, sshdr);
scsi_show_sense_hdr(sshdr);
scsi_decode_sense_extras(sense_buffer, sense_len, sshdr);
printk(KERN_INFO %s: , name);
@@ -1476,9 +1460,16 @@ void scsi_print_sense(char *name, struct scsi_cmnd *cmd)
 {
struct scsi_sense_hdr sshdr;
 
+   if (!scsi_normalize_sense(cmd-sense_buffer, SCSI_SENSE_BUFFERSIZE,
+ sshdr)) {
+   scmd_printk(KERN_INFO, cmd,
+   Unrecognized sense data (in hex):);
+   print_hex_dump(KERN_INFO, , DUMP_PREFIX_OFFSET,
+  16, 1, cmd-sense_buffer, SCSI_SENSE_BUFFERSIZE,
+  false);
+   return;
+   }
scmd_printk(KERN_INFO, cmd,  );
-   scsi_decode_sense_buffer(cmd-sense_buffer, SCSI_SENSE_BUFFERSIZE,
-sshdr);
scsi_show_sense_hdr(sshdr);
scsi_decode_sense_extras(cmd-sense_buffer, SCSI_SENSE_BUFFERSIZE,
 sshdr);
-- 
1.7.4.2

--
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 09/10] scsi: decode descriptor sense

2012-10-12 Thread Hannes Reinecke
Decode descriptor sense buffer to provide the same information as
we are already getting from fixed format sense.

Cc: Kay Sievers k...@vrfy.org
Signed-off-by: Hannes Reinecke h...@suse.de
---
 drivers/scsi/constants.c  |   79 +++--
 drivers/scsi/scsi_error.c |   43 +++-
 include/scsi/scsi_eh.h|8 +++-
 3 files changed, 73 insertions(+), 57 deletions(-)

diff --git a/drivers/scsi/constants.c b/drivers/scsi/constants.c
index 8bf2616..df69ba3 100644
--- a/drivers/scsi/constants.c
+++ b/drivers/scsi/constants.c
@@ -1376,61 +1376,34 @@ static void
 scsi_decode_sense_extras(const unsigned char *sense_buffer, int sense_len,
 struct scsi_sense_hdr *sshdr)
 {
-   int k, num, res;
-
-   if (sshdr-response_code  0x72)
-   {
-   /* only decode extras for fixed format now */
-   char buff[80];
-   int blen, fixed_valid;
-   unsigned int info;
-
-   fixed_valid = sense_buffer[0]  0x80;
-   info = ((sense_buffer[3]  24) | (sense_buffer[4]  16) |
-   (sense_buffer[5]  8) | sense_buffer[6]);
-   res = 0;
-   memset(buff, 0, sizeof(buff));
-   blen = sizeof(buff) - 1;
-   if (fixed_valid)
-   res += snprintf(buff + res, blen - res,
-   Info fld=0x%x, info);
-   if (sense_buffer[2]  0x80) {
-   /* current command has read a filemark */
-   if (res  0)
-   res += snprintf(buff + res, blen - res, , );
-   res += snprintf(buff + res, blen - res, FMK);
-   }
-   if (sense_buffer[2]  0x40) {
-   /* end-of-medium condition exists */
-   if (res  0)
-   res += snprintf(buff + res, blen - res, , );
-   res += snprintf(buff + res, blen - res, EOM);
-   }
-   if (sense_buffer[2]  0x20) {
-   /* incorrect block length requested */
-   if (res  0)
-   res += snprintf(buff + res, blen - res, , );
-   res += snprintf(buff + res, blen - res, ILI);
-   }
-   if (res  0)
-   printk(%s\n, buff);
-   } else if (sshdr-additional_length  0) {
-   /* descriptor format with sense descriptors */
-   num = 8 + sshdr-additional_length;
-   num = (sense_len  num) ? sense_len : num;
-   printk(Descriptor sense data with sense descriptors 
-  (in hex):);
-   for (k = 0; k  num; ++k) {
-   if (0 == (k % 16)) {
-   printk(\n);
-   printk(KERN_INFO );
-   }
-   printk(%02x , sense_buffer[k]);
-   }
+   int res = 0;
+   char buff[80];
+   int blen = sense_len;
 
-   printk(\n);
-   }
+   if (sshdr-info)
+   res += snprintf(buff + res, blen - res,
+   Info fld=0x%llx, sshdr-info);
 
+   if (sshdr-flags  SCSI_SENSE_FLAG_FMK) {
+   /* current command has read a filemark */
+   if (res  0)
+   res += snprintf(buff + res, blen - res, , );
+   res += snprintf(buff + res, blen - res, FMK);
+   }
+   if (sshdr-flags  SCSI_SENSE_FLAG_EOM) {
+   /* end-of-medium condition exists */
+   if (res  0)
+   res += snprintf(buff + res, blen - res, , );
+   res += snprintf(buff + res, blen - res, EOM);
+   }
+   if (sshdr-flags  SCSI_SENSE_FLAG_ILI) {
+   /* incorrect block length requested */
+   if (res  0)
+   res += snprintf(buff + res, blen - res, , );
+   res += snprintf(buff + res, blen - res, ILI);
+   }
+   if (res  0)
+   pr_info(%s\n, buff);
 }
 
 /* Normalize and print sense buffer with name prefix */
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index f8d51c5..e8ff276 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -2086,7 +2086,7 @@ EXPORT_SYMBOL(scsi_reset_provider);
  * 1 if valid sense data information found, else 0;
  */
 int scsi_normalize_sense(const u8 *sense_buffer, int sb_len,
- struct scsi_sense_hdr *sshdr)
+struct scsi_sense_hdr *sshdr)
 {
if (!sense_buffer || !sb_len)
return 0;
@@ -2099,6 +2099,9 @@ int scsi_normalize_sense(const u8 *sense_buffer, int 
sb_len,
return 0;
 
if (sshdr-response_code = 0x72) {
+   int i;
+   const char 

[PATCH 06/10] scsi: use single printk call in scsi_print_command()

2012-10-12 Thread Hannes Reinecke
scsi_print_command is using several calls to printk(), causing
the output to be garbled. Modify it to use a single call to
printk().

Cc: Kay Sievers k...@vrfy.org
Signed-off-by: Hannes Reinecke h...@suse.de
---
 drivers/scsi/constants.c |   71 +++--
 1 files changed, 61 insertions(+), 10 deletions(-)

diff --git a/drivers/scsi/constants.c b/drivers/scsi/constants.c
index b469798..65367e8 100644
--- a/drivers/scsi/constants.c
+++ b/drivers/scsi/constants.c
@@ -349,34 +349,85 @@ static int print_opcode_name(char *buf, int buf_len,
 
 void __scsi_print_command(unsigned char *cdb)
 {
-   int k, len;
+   int k, len, rem, linelen;
char cdb_str[64];
+   char line[16 * 3 + 1];
 
print_opcode_name(cdb_str, 64, cdb, 0);
-   pr_info(%s, cdb_str);
len = scsi_command_size(cdb);
/* print out all bytes in cdb */
-   for (k = 0; k  len; ++k) 
-   printk( %02x, cdb[k]);
-   printk(\n);
+   switch (len) {
+   case 6:
+   pr_info(%s %6ph\n, cdb_str, cdb);
+   break;
+   case 10:
+   pr_info(%s %10ph\n, cdb_str, cdb);
+   break;
+   case 12:
+   pr_info(%s %12ph\n, cdb_str, cdb);
+   break;
+   case 16:
+   pr_info(%s %16ph\n, cdb_str, cdb);
+   break;
+   default:
+   pr_info(%s\n, cdb_str);
+   rem = len;
+   for (k = 0; k  len; k += 16) {
+   linelen = min(rem, 16);
+   rem -= 16;
+
+   hex_dump_to_buffer(cdb + k, linelen, 16, 1,
+  line, sizeof(line), false);
+   pr_info(%s\n, line);
+   }
+   break;
+   }
 }
 EXPORT_SYMBOL(__scsi_print_command);
 
 void scsi_print_command(struct scsi_cmnd *cmd)
 {
-   int k;
+   int k, rem, linelen;
char cdb_str[64];
+   char line[16 * 3 + 1];
 
if (cmd-cmnd == NULL)
return;
 
print_opcode_name(cdb_str, 64, cmd-cmnd, cmd-cmd_len);
-   scmd_printk(KERN_INFO, cmd, CDB: %s:, cdb_str);
 
/* print out all bytes in cdb */
-   for (k = 0; k  cmd-cmd_len; ++k)
-   printk( %02x, cmd-cmnd[k]);
-   printk(\n);
+   switch (cmd-cmd_len) {
+   case 6:
+   scmd_printk(KERN_INFO, cmd, CDB: %s: %6ph\n,
+   cdb_str, cmd-cmnd);
+   break;
+   case 10:
+   scmd_printk(KERN_INFO, cmd, CDB: %s: %10ph\n,
+   cdb_str, cmd-cmnd);
+   break;
+   case 12:
+   scmd_printk(KERN_INFO, cmd, CDB: %s: %12ph\n,
+   cdb_str, cmd-cmnd);
+   break;
+   case 16:
+   scmd_printk(KERN_INFO, cmd, CDB: %s: %16ph\n,
+   cdb_str, cmd-cmnd);
+   break;
+   default:
+   scmd_printk(KERN_INFO, cmd, CDB: %s\n, cdb_str);
+   rem = cmd-cmd_len;
+   for (k = 0; k  cmd-cmd_len; k += 16) {
+   linelen = min(rem, 16);
+   rem -= 16;
+
+   hex_dump_to_buffer(cmd-cmnd + k, linelen, 16, 1,
+  line, sizeof(line), false);
+   scmd_printk(KERN_INFO, cmd, %d: %s\n,
+   k, line);
+   }
+   break;
+   }
 }
 EXPORT_SYMBOL(scsi_print_command);
 
-- 
1.7.4.2

--
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 10/10] scsi: use local buffer for decoding sense data

2012-10-12 Thread Hannes Reinecke
Instead of printing directly to console we should be using
a local buffer for formatting sense data.
This will avoid garbled output.

Cc: Kay Sievers k...@vrfy.org
Signed-off-by: Hannes Reinecke h...@suse.de
---
 drivers/scsi/constants.c |  102 +
 drivers/scsi/sd.c|   10 +++--
 include/scsi/scsi_dbg.h  |4 +-
 3 files changed, 65 insertions(+), 51 deletions(-)

diff --git a/drivers/scsi/constants.c b/drivers/scsi/constants.c
index df69ba3..9115233 100644
--- a/drivers/scsi/constants.c
+++ b/drivers/scsi/constants.c
@@ -1299,49 +1299,52 @@ scsi_extd_sense_format(unsigned char asc, unsigned char 
ascq) {
 EXPORT_SYMBOL(scsi_extd_sense_format);
 
 void
-scsi_show_extd_sense(unsigned char asc, unsigned char ascq)
+scsi_show_extd_sense(char *buf, int buf_len,
+unsigned char asc, unsigned char ascq)
 {
-const char *extd_sense_fmt = scsi_extd_sense_format(asc, ascq);
+   const char *extd_sense_fmt = scsi_extd_sense_format(asc, ascq);
+   int sz = 0;
 
if (extd_sense_fmt) {
if (strstr(extd_sense_fmt, %x)) {
-   printk(Add. Sense: );
-   printk(extd_sense_fmt, ascq);
+   sz = snprintf(buf, buf_len, Add. Sense: );
+   sz += snprintf(buf + sz, buf_len - sz,
+  extd_sense_fmt, ascq);
} else
-   printk(Add. Sense: %s, extd_sense_fmt);
+   sz = snprintf(buf, buf_len, Add. Sense: %s,
+ extd_sense_fmt);
} else {
if (asc = 0x80)
-   printk(vendor ASC=0x%x ASCQ=0x%x, asc,
-  ascq);
-   if (ascq = 0x80)
-   printk(ASC=0x%x vendor ASCQ=0x%x, asc,
-  ascq);
+   snprintf(buf, buf_len, vendor ASC=0x%x ASCQ=0x%x,
+asc, ascq);
+   else if (ascq = 0x80)
+   snprintf(buf, buf_len, ASC=0x%x vendor ASCQ=0x%x,
+asc, ascq);
else
-   printk(ASC=0x%x ASCQ=0x%x, asc, ascq);
+   snprintf(buf, buf_len, ASC=0x%x ASCQ=0x%x, asc, ascq);
}
-
-   printk(\n);
 }
 EXPORT_SYMBOL(scsi_show_extd_sense);
 
 void
-scsi_show_sense_hdr(struct scsi_sense_hdr *sshdr)
+scsi_show_sense_hdr(char *buf, int buf_len, struct scsi_sense_hdr *sshdr)
 {
const char *sense_txt;
+   int sz;
 
sense_txt = scsi_sense_key_string(sshdr-sense_key);
if (sense_txt)
-   printk(Sense Key : %s , sense_txt);
+   sz = snprintf(buf, buf_len, Sense Key : %s , sense_txt);
else
-   printk(Sense Key : 0x%x , sshdr-sense_key);
+   sz = snprintf(buf, buf_len, Sense Key : 0x%x ,
+ sshdr-sense_key);
 
-   printk(%s, scsi_sense_is_deferred(sshdr) ? [deferred]  :
-  [current] );
+   sz += snprintf(buf + sz, buf_len - sz, %s,
+  scsi_sense_is_deferred(sshdr) ?
+  [deferred]  : [current] );
 
if (sshdr-response_code = 0x72)
-   printk([descriptor]);
-
-   printk(\n);
+   sz += snprintf(buf + sz, buf_len - sz, [descriptor]);
 }
 EXPORT_SYMBOL(scsi_show_sense_hdr);
 
@@ -1351,10 +1354,12 @@ EXPORT_SYMBOL(scsi_show_sense_hdr);
 void
 scsi_print_sense_hdr(const char *name, struct scsi_sense_hdr *sshdr)
 {
-   printk(KERN_INFO %s: , name);
-   scsi_show_sense_hdr(sshdr);
-   printk(KERN_INFO %s: , name);
-   scsi_show_extd_sense(sshdr-asc, sshdr-ascq);
+   char sense_buf[128];
+
+   scsi_show_sense_hdr(sense_buf, 128, sshdr);
+   pr_info(%s: %s, name, sense_buf);
+   scsi_show_extd_sense(sense_buf, 128, sshdr-asc, sshdr-ascq);
+   pr_info(%s: %s, name, sense_buf);
 }
 EXPORT_SYMBOL(scsi_print_sense_hdr);
 
@@ -1365,20 +1370,21 @@ void
 scsi_cmd_print_sense_hdr(struct scsi_cmnd *scmd, const char *desc,
  struct scsi_sense_hdr *sshdr)
 {
-   scmd_printk(KERN_INFO, scmd, %s: , desc);
-   scsi_show_sense_hdr(sshdr);
-   scmd_printk(KERN_INFO, scmd, %s: , desc);
-   scsi_show_extd_sense(sshdr-asc, sshdr-ascq);
+   char sense_buf[128];
+
+   scsi_show_sense_hdr(sense_buf, 128, sshdr);
+   scmd_printk(KERN_INFO, scmd, %s: %s, desc, sense_buf);
+   scsi_show_extd_sense(sense_buf, 128, sshdr-asc, sshdr-ascq);
+   scmd_printk(KERN_INFO, scmd, %s: %s, desc, sense_buf);
 }
 EXPORT_SYMBOL(scsi_cmd_print_sense_hdr);
 
-static void
-scsi_decode_sense_extras(const unsigned char *sense_buffer, int sense_len,
+static int
+scsi_decode_sense_extras(char *buff, int buff_len,
 struct scsi_sense_hdr *sshdr)
 {
int res = 0;
-   char buff[80];
-   int blen = 

[PATCH 2/5] arcmsr: Support Hibernation

2012-10-12 Thread NickCheng
From: Nick Cheng nick.ch...@areca.com.tw

Support hibernation for whole series of RAID controllers
Signed-off-by: Nick Cheng nick.ch...@areca.com.tw
---
diff -uprN a//drivers/scsi/arcmsr/arcmsr.h b//drivers/scsi/arcmsr/arcmsr.h
--- a//drivers/scsi/arcmsr/arcmsr.h 2012-10-12 16:28:42.175958900 +0800
+++ b//drivers/scsi/arcmsr/arcmsr.h 2012-10-12 16:29:10.215958628 +0800
@@ -63,7 +63,8 @@ struct device_attribute;
 #define ARCMSR_DEFAULT_SG_ENTRIES  38
 #define ARCMSR_MAX_HBB_POSTQUEUE   264
 #define ARCMSR_MAX_XFER_LEN0x26000
-#define ARCMSR_CDB_SG_PAGE_LENGTH  256 
+#define ARCMSR_CDB_SG_PAGE_LENGTH  256
+#define ARCMST_NUM_MSIX_VECTORS4
 #ifndef PCI_DEVICE_ID_ARECA_1880
#define PCI_DEVICE_ID_ARECA_18800x1880
  #endif
@@ -511,6 +512,7 @@ struct AdapterControlBlock
struct pci_dev *pdev;
struct Scsi_Host *host;
unsigned long vir2phy_offset;
+   struct msix_entry entries[ARCMST_NUM_MSIX_VECTORS];
/* Offset is used in making arc cdb physical to virtual calculations */
uint32_t outbound_int_enable;
uint32_t cdb_phyaddr_hi32;
@@ -547,6 +549,8 @@ struct AdapterControlBlock
/* iop init */
#define ACB_F_ABORT 0x0200
#define ACB_F_FIRMWARE_TRAP 0x0400
+   #define ACB_F_MSI_ENABLED   0x1000
+   #define ACB_F_MSIX_ENABLED  0x2000
struct CommandControlBlock *pccb_pool[ARCMSR_MAX_FREECCB_NUM];
/* used for memory free */
struct list_head ccb_free_list;
diff -uprN a//drivers/scsi/arcmsr/arcmsr_hba.c 
b//drivers/scsi/arcmsr/arcmsr_hba.c
--- a//drivers/scsi/arcmsr/arcmsr_hba.c 2012-10-12 16:28:42.175958900 +0800
+++ b//drivers/scsi/arcmsr/arcmsr_hba.c 2012-10-12 16:29:10.239958629 +0800
@@ -89,11 +89,18 @@ static int arcmsr_bios_param(struct scsi
 static int arcmsr_queue_command(struct Scsi_Host *h, struct scsi_cmnd *cmd);
 static int arcmsr_probe(struct pci_dev *pdev,
const struct pci_device_id *id);
+#ifdef CONFIG_PM
+   static int arcmsr_suspend(struct pci_dev *pdev,
+   pm_message_t state);
+   static int arcmsr_resume(struct pci_dev *pdev);
+#endif
 static void arcmsr_remove(struct pci_dev *pdev);
 static void arcmsr_shutdown(struct pci_dev *pdev);
 static void arcmsr_iop_init(struct AdapterControlBlock *acb);
 static void arcmsr_free_ccb_pool(struct AdapterControlBlock *acb);
 static u32 arcmsr_disable_outbound_ints(struct AdapterControlBlock *acb);
+static void arcmsr_enable_outbound_ints(struct AdapterControlBlock *acb,
+   u32 orig_mask);
 static void arcmsr_stop_adapter_bgrb(struct AdapterControlBlock *acb);
 static void arcmsr_hbaA_flush_cache(struct AdapterControlBlock *acb);
 static void arcmsr_hbaB_flush_cache(struct AdapterControlBlock *acb);
@@ -166,6 +173,10 @@ static struct pci_driver arcmsr_pci_driv
.id_table   = arcmsr_device_id_table,
.probe  = arcmsr_probe,
.remove = arcmsr_remove,
+   #ifdef CONFIG_PM
+   .suspend= arcmsr_suspend,
+   .resume = arcmsr_resume,
+   #endif
.shutdown   = arcmsr_shutdown,
 };
 /*
@@ -662,6 +673,134 @@ arcmsr_message_isr_bh_fn(struct work_str
}
 }
 
+#ifdef CONFIG_PM
+   static int
+   arcmsr_suspend(struct pci_dev *pdev, pm_message_t state)
+   {
+   int i;
+   uint32_t intmask_org;
+   struct Scsi_Host *host = pci_get_drvdata(pdev);
+   struct AdapterControlBlock *acb =
+   (struct AdapterControlBlock *)host-hostdata;
+
+   intmask_org = arcmsr_disable_outbound_ints(acb);
+   if (acb-acb_flags  ACB_F_MSI_ENABLED) {
+   free_irq(pdev-irq, acb);
+   pci_disable_msi(pdev);
+   } else if (acb-acb_flags  ACB_F_MSIX_ENABLED) {
+   for (i = 0; i  ARCMST_NUM_MSIX_VECTORS; i++) {
+   free_irq(acb-entries[i].vector, acb);
+   }
+   pci_disable_msix(pdev);
+   } else {
+   free_irq(pdev-irq, acb);
+   }
+   del_timer_sync(acb-eternal_timer);
+   flush_scheduled_work();
+   arcmsr_stop_adapter_bgrb(acb);
+   arcmsr_flush_adapter_cache(acb);
+   arcmsr_enable_outbound_ints(acb, intmask_org);
+   pci_set_drvdata(pdev, host);
+   pci_save_state(pdev);
+   pci_disable_device(pdev);
+   pci_set_power_state(pdev, pci_choose_state(pdev, state));
+   return 0;
+   }
+   
+   static int
+   arcmsr_resume(struct pci_dev *pdev)
+   {
+   int error, i, 

[PATCH 3/5] arcmsr: Support MSI and MSI-X

2012-10-12 Thread NickCheng
From: Nick Cheng nick.ch...@areca.com.tw

Support MSI or MSI-X for whole series of RAID controllers. Meanwhile correct 
the register access as iowrite32/ioread32 
Signed-off-by: Nick Cheng nick.ch...@areca.com.tw
---
diff -uprN a//drivers/scsi/arcmsr/arcmsr_hba.c 
b//drivers/scsi/arcmsr/arcmsr_hba.c
--- a//drivers/scsi/arcmsr/arcmsr_hba.c 2012-10-12 16:34:58.219955247 +0800
+++ b//drivers/scsi/arcmsr/arcmsr_hba.c 2012-10-12 16:35:16.267955072 +0800
@@ -805,8 +805,9 @@ static int arcmsr_probe(struct pci_dev *
 {
struct Scsi_Host *host;
struct AdapterControlBlock *acb;
-   uint8_t bus,dev_fun;
-   int error;
+   uint8_t bus, dev_fun;
+   struct msix_entry entries[ARCMST_NUM_MSIX_VECTORS];
+   int error, i, j;
error = pci_enable_device(pdev);
if (error) {
return -ENODEV;
@@ -871,10 +872,46 @@ static int arcmsr_probe(struct pci_dev *
if (error) {
goto RAID_controller_stop;
}
-   error = request_irq(pdev-irq, arcmsr_do_interrupt,
-   IRQF_SHARED, arcmsr, acb);
-   if (error) {
-   goto scsi_host_remove;
+   if (pci_find_capability(pdev, PCI_CAP_ID_MSIX)) {
+   if (!pci_enable_msix(pdev, entries, ARCMST_NUM_MSIX_VECTORS)) {
+   for (i = 0; i  ARCMST_NUM_MSIX_VECTORS; i++) {
+   entries[i].entry = i;
+   if (request_irq(entries[i].vector,
+   arcmsr_do_interrupt, 0, arcmsr,
+   acb)) {
+   for (j = 0 ; j  i ; j++)
+   free_irq(entries[i].vector,
+   acb);
+   goto scsi_host_remove;
+   }
+   acb-entries[i] = entries[i];
+   }
+   acb-acb_flags |= ACB_F_MSIX_ENABLED;
+   } else {
+   if (request_irq(pdev-irq, arcmsr_do_interrupt,
+   IRQF_SHARED, arcmsr, acb)) {
+   printk(arcmsr%d: request_irq =%d failed!\n,
+   acb-host-host_no, pdev-irq);
+   goto scsi_host_remove;
+   }
+   }
+   } else if (pci_find_capability(pdev, PCI_CAP_ID_MSI)) {
+   if (!pci_enable_msi(pdev)) {
+   acb-acb_flags |= ACB_F_MSI_ENABLED;
+   }
+   if (request_irq(pdev-irq, arcmsr_do_interrupt,
+   IRQF_SHARED, arcmsr, acb)) {
+   printk(arcmsr%d: request_irq =%d failed!\n,
+   acb-host-host_no, pdev-irq);
+   goto scsi_host_remove;
+   }
+   } else {
+   if (request_irq(pdev-irq, arcmsr_do_interrupt,
+   IRQF_SHARED, arcmsr, acb)) {
+   printk(arcmsr%d: request_irq =%d failed!\n,
+   acb-host-host_no, pdev-irq);
+   goto scsi_host_remove;
+   }
}
host-irq = pdev-irq;
scsi_scan_host(host);
@@ -895,6 +932,11 @@ static int arcmsr_probe(struct pci_dev *
return 0;
 out_free_sysfs:
 scsi_host_remove:
+   if (acb-acb_flags  ACB_F_MSI_ENABLED) {
+   pci_disable_msi(pdev);
+   } else if (acb-acb_flags  ACB_F_MSIX_ENABLED) {
+   pci_disable_msix(pdev);
+   }
scsi_remove_host(host);
 RAID_controller_stop:
arcmsr_stop_adapter_bgrb(acb);

--
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 01/10] sg: Use dev_printk

2012-10-12 Thread Douglas Gilbert

On 12-10-12 04:33 AM, Hannes Reinecke wrote:

Every sg device has a reference to the underlying scsi device, so
this patch adds dev_printk() macros to have the messages prefixed
with the correct device.

Before:
[772330.437378] sg_open: dev=2, flags=0x8800
[772330.475425] sg_add_sfp: sfp=0x880429d3e000

After:
[  409.399888] sr 2:0:0:0: [sg2] sg_open: flags=0x8800
[  409.446029] sr 2:0:0:0: [sg2] sg_add_sfp: sfp=0x880425856000

Cc: Kay Sievers k...@vrfy.org
Cc: Doug Gilbert dgilb...@interlog.com
Signed-off-by: Hannes Reinecke h...@suse.de


Acked-by: Douglas Gilbert dgilb...@interlog.com

--
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3 0/5] Migrate SCSI drivers to use dev_pm_ops

2012-10-12 Thread Alan Stern
On Fri, 12 Oct 2012, Aaron Lu wrote:

 v3:
 Only patch 4 is modified:
 Remove the special case for system freeze in scsi_bus_suspend_common
 as pointed out by Alan Stern;
 Updated some comments;
 Removed the use of typedef (*pm_callback_t)(struct device *).
 
 v2:
 Change the runtime suspend behaviour of sd driver by putting the device
 into stopped power state.
 Revert 2 patches which are no longer needed as pointed out by Alan Stern.
 Find out device callbacks in bus callbacks as suggested by Alan Stern.
 
 Due to these changes, patch number grows from 2 - 5.
 
 v1:
 The 2 patches will migrate SCSI drivers to use the pm callbacks defined
 in dev_pm_ops as pm_message is deprecated and should not be used by driver.
 Bus level callback is changed to use callbacks defined in dev_pm_ops when
 needed and sd's pm callback is updated to use what are defined in dev_pm_ops.
 
 Aaron Lu (5):
   sd: put to stopped power state when runtime suspend
   Revert [SCSI] scsi_pm: set device runtime state before parent
 suspended
   Revert [SCSI] runtime resume parent for child's system-resume
   pm: use callbacks from dev_pm_ops for scsi devices
   sd: update sd to use the new pm callbacks
 
  drivers/scsi/scsi_pm.c | 97 
 +++---
  drivers/scsi/sd.c  | 18 +++---
  2 files changed, 66 insertions(+), 49 deletions(-)

Remember to run all the patches through checkpatch.pl before submitting
them.  Aside from that, for the whole series:

Acked-by: Alan Stern st...@rowland.harvard.edu

--
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html