Go to:
Gentoo Home
Documentation
Forums
Lists
Bugs
Planet
Store
Wiki
Get Gentoo!
Gentoo's Bugzilla – Attachment 118829 Details for
Bug 174373
SCSI/libata disk shutdown issues
Home
|
New
–
[Ex]
|
Browse
|
Search
|
Privacy Policy
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
All patches that make start/stop management work
libata_start_stop_management.patch (text/plain), 90.68 KB, created by
Ricardo Salveti
on 2007-05-11 05:39:28 UTC
(
hide
)
Description:
All patches that make start/stop management work
Filename:
MIME Type:
Creator:
Ricardo Salveti
Created:
2007-05-11 05:39:28 UTC
Size:
90.68 KB
patch
obsolete
>From: Martin K. Petersen <martin.petersen@oracle.com> >Date: Wed, 28 Feb 2007 03:39:44 +0000 (-0500) >Subject: [SCSI] constants.c: cleanup, verbose result printing >X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=684b7fe976554d12e6266d7280c87a0f3feff02e > >[SCSI] constants.c: cleanup, verbose result printing > >Clean up constants.c and make result printing more user friendly: > > - Refactor the command and sense functions so that the actual > formatting can be called from the various helper functions with the > correct prefix. > > - Replace scsi_print_hostbyte() and scsi_print_driverbyte() with > scsi_print_result() which is verbose when CONFIG_SCSI_CONSTANTS is > on. > >Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> >Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com> >--- > >diff --git a/drivers/scsi/constants.c b/drivers/scsi/constants.c >index 61f6024..6114875 100644 >--- a/drivers/scsi/constants.c >+++ b/drivers/scsi/constants.c >@@ -202,31 +202,29 @@ 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, >- int start_of_line) >+static void print_opcode_name(unsigned char * cdbp, int cdb_len) > { > int sa, len, cdb0; > const char * name; >- const char * leadin = start_of_line ? KERN_INFO : ""; > > cdb0 = cdbp[0]; > switch(cdb0) { > case VARIABLE_LENGTH_CMD: > len = cdbp[7] + 8; > if (len < 10) { >- printk("%sshort variable length command, " >- "len=%d ext_len=%d", leadin, len, cdb_len); >+ printk("short variable length command, " >+ "len=%d ext_len=%d", len, cdb_len); > break; > } > sa = (cdbp[8] << 8) + cdbp[9]; > name = get_sa_name(maint_in_arr, MAINT_IN_SZ, sa); > if (name) { >- printk("%s%s", leadin, name); >+ printk("%s", name); > if ((cdb_len > 0) && (len != cdb_len)) > printk(", in_cdb_len=%d, ext_len=%d", > len, cdb_len); > } else { >- printk("%scdb[0]=0x%x, sa=0x%x", leadin, cdb0, sa); >+ printk("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); >@@ -236,83 +234,80 @@ static void print_opcode_name(unsigned char * cdbp, int cdb_len, > sa = cdbp[1] & 0x1f; > name = get_sa_name(maint_in_arr, MAINT_IN_SZ, sa); > if (name) >- printk("%s%s", leadin, name); >+ printk("%s", name); > else >- printk("%scdb[0]=0x%x, sa=0x%x", leadin, cdb0, sa); >+ printk("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%s", leadin, name); >+ printk("%s", name); > else >- printk("%scdb[0]=0x%x, sa=0x%x", leadin, cdb0, sa); >+ printk("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%s", leadin, name); >+ printk("%s", name); > else >- printk("%scdb[0]=0x%x, sa=0x%x", leadin, cdb0, sa); >+ printk("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%s", leadin, name); >+ printk("%s", name); > else >- printk("%scdb[0]=0x%x, sa=0x%x", leadin, cdb0, sa); >+ printk("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%s", leadin, name); >+ printk("%s", name); > else >- printk("%scdb[0]=0x%x, sa=0x%x", leadin, cdb0, sa); >+ printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa); > break; > case SERVICE_ACTION_OUT_16: > sa = cdbp[1] & 0x1f; > name = get_sa_name(serv_out16_arr, SERV_OUT16_SZ, sa); > if (name) >- printk("%s%s", leadin, name); >+ printk("%s", name); > else >- printk("%scdb[0]=0x%x, sa=0x%x", leadin, cdb0, sa); >+ printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa); > break; > default: > if (cdb0 < 0xc0) { > name = cdb_byte0_names[cdb0]; > if (name) >- printk("%s%s", leadin, name); >+ printk("%s", name); > else >- printk("%scdb[0]=0x%x (reserved)", >- leadin, cdb0); >+ printk("cdb[0]=0x%x (reserved)", cdb0); > } else >- printk("%scdb[0]=0x%x (vendor)", leadin, cdb0); >+ printk("cdb[0]=0x%x (vendor)", cdb0); > break; > } > } > > #else /* ifndef CONFIG_SCSI_CONSTANTS */ > >-static void print_opcode_name(unsigned char * cdbp, int cdb_len, >- int start_of_line) >+static void print_opcode_name(unsigned char * cdbp, int cdb_len) > { > int sa, len, cdb0; >- const char * leadin = start_of_line ? KERN_INFO : ""; > > cdb0 = cdbp[0]; > switch(cdb0) { > case VARIABLE_LENGTH_CMD: > len = cdbp[7] + 8; > if (len < 10) { >- printk("%sshort opcode=0x%x command, len=%d " >- "ext_len=%d", leadin, cdb0, len, cdb_len); >+ printk("short opcode=0x%x command, len=%d " >+ "ext_len=%d", cdb0, len, cdb_len); > break; > } > sa = (cdbp[8] << 8) + cdbp[9]; >- printk("%scdb[0]=0x%x, sa=0x%x", leadin, cdb0, sa); >+ printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa); > if (len != cdb_len) > printk(", in_cdb_len=%d, ext_len=%d", len, cdb_len); > break; >@@ -323,49 +318,48 @@ static void print_opcode_name(unsigned char * cdbp, int cdb_len, > case SERVICE_ACTION_IN_16: > case SERVICE_ACTION_OUT_16: > sa = cdbp[1] & 0x1f; >- printk("%scdb[0]=0x%x, sa=0x%x", leadin, cdb0, sa); >+ printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa); > break; > default: > if (cdb0 < 0xc0) >- printk("%scdb[0]=0x%x", leadin, cdb0); >+ printk("cdb[0]=0x%x", cdb0); > else >- printk("%scdb[0]=0x%x (vendor)", leadin, cdb0); >+ printk("cdb[0]=0x%x (vendor)", cdb0); > break; > } > } > #endif > >-void __scsi_print_command(unsigned char *command) >+void __scsi_print_command(unsigned char *cdb) > { > int k, len; > >- print_opcode_name(command, 0, 1); >- if (VARIABLE_LENGTH_CMD == command[0]) >- len = command[7] + 8; >+ print_opcode_name(cdb, 0); >+ if (VARIABLE_LENGTH_CMD == cdb[0]) >+ len = cdb[7] + 8; > else >- len = COMMAND_SIZE(command[0]); >+ len = COMMAND_SIZE(cdb[0]); > /* print out all bytes in cdb */ > for (k = 0; k < len; ++k) >- printk(" %02x", command[k]); >+ printk(" %02x", cdb[k]); > printk("\n"); > } > EXPORT_SYMBOL(__scsi_print_command); > >-/* This function (perhaps with the addition of peripheral device type) >- * is more approriate than __scsi_print_command(). Perhaps that static >- * can be dropped later if it replaces the __scsi_print_command version. >- */ >-static void scsi_print_cdb(unsigned char *cdb, int cdb_len, int start_of_line) >+void scsi_print_command(struct scsi_cmnd *cmd) > { > int k; > >- print_opcode_name(cdb, cdb_len, start_of_line); >+ scmd_printk(KERN_INFO, cmd, "CDB: "); >+ print_opcode_name(cmd->cmnd, cmd->cmd_len); >+ > /* print out all bytes in cdb */ > printk(":"); >- for (k = 0; k < cdb_len; ++k) >- printk(" %02x", cdb[k]); >+ for (k = 0; k < cmd->cmd_len; ++k) >+ printk(" %02x", cmd->cmnd[k]); > printk("\n"); > } >+EXPORT_SYMBOL(scsi_print_command); > > /** > * >@@ -1176,67 +1170,77 @@ scsi_extd_sense_format(unsigned char asc, unsigned char ascq) { > } > EXPORT_SYMBOL(scsi_extd_sense_format); > >-/* Print extended sense information; no leadin, no linefeed */ >-static void >+void > scsi_show_extd_sense(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); > > if (extd_sense_fmt) { > if (strstr(extd_sense_fmt, "%x")) { >- printk("Additional sense: "); >+ printk("Add. Sense: "); > printk(extd_sense_fmt, ascq); > } else >- printk("Additional sense: %s", extd_sense_fmt); >+ printk("Add. Sense: %s", extd_sense_fmt); > } else { > if (asc >= 0x80) >- printk("<<vendor>> ASC=0x%x ASCQ=0x%x", asc, ascq); >+ printk("<<vendor>> ASC=0x%x ASCQ=0x%x", asc, >+ ascq); > if (ascq >= 0x80) >- printk("ASC=0x%x <<vendor>> ASCQ=0x%x", asc, ascq); >+ printk("ASC=0x%x <<vendor>> ASCQ=0x%x", asc, >+ ascq); > else > printk("ASC=0x%x ASCQ=0x%x", asc, ascq); > } >+ >+ printk("\n"); > } >+EXPORT_SYMBOL(scsi_show_extd_sense); > > void >-scsi_print_sense_hdr(const char *name, struct scsi_sense_hdr *sshdr) >+scsi_show_sense_hdr(struct scsi_sense_hdr *sshdr) > { > const char *sense_txt; >- /* An example of deferred is when an earlier write to disk cache >- * succeeded, but now the disk discovers that it cannot write the >- * data to the magnetic media. >- */ >- const char *error = scsi_sense_is_deferred(sshdr) ? >- "<<DEFERRED>>" : "Current"; >- printk(KERN_INFO "%s: %s", name, error); >- if (sshdr->response_code >= 0x72) >- printk(" [descriptor]"); > > sense_txt = scsi_sense_key_string(sshdr->sense_key); > if (sense_txt) >- printk(": sense key: %s\n", sense_txt); >+ printk("Sense Key : %s ", sense_txt); > else >- printk(": sense key=0x%x\n", sshdr->sense_key); >- printk(KERN_INFO " "); >- scsi_show_extd_sense(sshdr->asc, sshdr->ascq); >+ printk("Sense Key : 0x%x ", sshdr->sense_key); >+ >+ printk("%s", scsi_sense_is_deferred(sshdr) ? "[deferred] " : >+ "[current] "); >+ >+ if (sshdr->response_code >= 0x72) >+ printk("[descriptor]"); >+ > printk("\n"); > } >+EXPORT_SYMBOL(scsi_show_sense_hdr); >+ >+/* >+ * Print normalized SCSI sense header with a prefix. >+ */ >+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); >+} > EXPORT_SYMBOL(scsi_print_sense_hdr); > >-/* Print sense information */ > void >-__scsi_print_sense(const char *name, const unsigned char *sense_buffer, >- int sense_len) >+scsi_decode_sense_buffer(const unsigned char *sense_buffer, int sense_len, >+ struct scsi_sense_hdr *sshdr) > { > int k, num, res; >- unsigned int info; >- struct scsi_sense_hdr ssh; > >- res = scsi_normalize_sense(sense_buffer, sense_len, &ssh); >+ 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(KERN_INFO "Unrecognized sense data (in hex):"); >+ printk("Unrecognized sense data (in hex):"); > for (k = 0; k < num; ++k) { > if (0 == (k % 16)) { > printk("\n"); >@@ -1247,11 +1251,20 @@ __scsi_print_sense(const char *name, const unsigned char *sense_buffer, > printk("\n"); > return; > } >- scsi_print_sense_hdr(name, &ssh); >- if (ssh.response_code < 0x72) { >+} >+ >+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) | >@@ -1281,13 +1294,13 @@ __scsi_print_sense(const char *name, const unsigned char *sense_buffer, > res += snprintf(buff + res, blen - res, "ILI"); > } > if (res > 0) >- printk(KERN_INFO "%s\n", buff); >- } else if (ssh.additional_length > 0) { >+ printk("%s\n", buff); >+ } else if (sshdr->additional_length > 0) { > /* descriptor format with sense descriptors */ >- num = 8 + ssh.additional_length; >+ num = 8 + sshdr->additional_length; > num = (sense_len < num) ? sense_len : num; >- printk(KERN_INFO "Descriptor sense data with sense " >- "descriptors (in hex):"); >+ printk("Descriptor sense data with sense descriptors " >+ "(in hex):"); > for (k = 0; k < num; ++k) { > if (0 == (k % 16)) { > printk("\n"); >@@ -1295,29 +1308,42 @@ __scsi_print_sense(const char *name, const unsigned char *sense_buffer, > } > printk("%02x ", sense_buffer[k]); > } >+ > printk("\n"); > } >+ > } >-EXPORT_SYMBOL(__scsi_print_sense); > >-void scsi_print_sense(const char *devclass, struct scsi_cmnd *cmd) >+/* Normalize and print sense buffer with name prefix */ >+void __scsi_print_sense(const char *name, const unsigned char *sense_buffer, >+ int sense_len) > { >- const char *name = devclass; >- >- if (cmd->request->rq_disk) >- name = cmd->request->rq_disk->disk_name; >- __scsi_print_sense(name, cmd->sense_buffer, SCSI_SENSE_BUFFERSIZE); >+ struct scsi_sense_hdr sshdr; >+ >+ 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); >+ scsi_show_extd_sense(sshdr.asc, sshdr.ascq); > } >-EXPORT_SYMBOL(scsi_print_sense); >+EXPORT_SYMBOL(__scsi_print_sense); > >-void scsi_print_command(struct scsi_cmnd *cmd) >+/* Normalize and print sense buffer in SCSI command */ >+void scsi_print_sense(char *name, struct scsi_cmnd *cmd) > { >- /* Assume appended output (i.e. not at start of line) */ >- sdev_printk("", cmd->device, "\n"); >- printk(KERN_INFO " command: "); >- scsi_print_cdb(cmd->cmnd, cmd->cmd_len, 0); >+ struct scsi_sense_hdr sshdr; >+ >+ 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); >+ scmd_printk(KERN_INFO, cmd, ""); >+ scsi_show_extd_sense(sshdr.asc, sshdr.ascq); > } >-EXPORT_SYMBOL(scsi_print_command); >+EXPORT_SYMBOL(scsi_print_sense); > > #ifdef CONFIG_SCSI_CONSTANTS > >@@ -1327,25 +1353,6 @@ static const char * const hostbyte_table[]={ > "DID_PASSTHROUGH", "DID_SOFT_ERROR", "DID_IMM_RETRY"}; > #define NUM_HOSTBYTE_STRS ARRAY_SIZE(hostbyte_table) > >-void scsi_print_hostbyte(int scsiresult) >-{ >- int hb = host_byte(scsiresult); >- >- printk("Hostbyte=0x%02x", hb); >- if (hb < NUM_HOSTBYTE_STRS) >- printk("(%s) ", hostbyte_table[hb]); >- else >- printk("is invalid "); >-} >-#else >-void scsi_print_hostbyte(int scsiresult) >-{ >- printk("Hostbyte=0x%02x ", host_byte(scsiresult)); >-} >-#endif >- >-#ifdef CONFIG_SCSI_CONSTANTS >- > static const char * const driverbyte_table[]={ > "DRIVER_OK", "DRIVER_BUSY", "DRIVER_SOFT", "DRIVER_MEDIA", "DRIVER_ERROR", > "DRIVER_INVALID", "DRIVER_TIMEOUT", "DRIVER_HARD", "DRIVER_SENSE"}; >@@ -1356,19 +1363,35 @@ static const char * const driversuggest_table[]={"SUGGEST_OK", > "SUGGEST_5", "SUGGEST_6", "SUGGEST_7", "SUGGEST_SENSE"}; > #define NUM_SUGGEST_STRS ARRAY_SIZE(driversuggest_table) > >-void scsi_print_driverbyte(int scsiresult) >+void scsi_show_result(int result) > { >- int dr = (driver_byte(scsiresult) & DRIVER_MASK); >- int su = ((driver_byte(scsiresult) & SUGGEST_MASK) >> 4); >+ int hb = host_byte(result); >+ int db = (driver_byte(result) & DRIVER_MASK); >+ int su = ((driver_byte(result) & SUGGEST_MASK) >> 4); > >- printk("Driverbyte=0x%02x ", driver_byte(scsiresult)); >- printk("(%s,%s) ", >- (dr < NUM_DRIVERBYTE_STRS ? driverbyte_table[dr] : "invalid"), >+ printk("Result: hostbyte=%s driverbyte=%s,%s\n", >+ (hb < NUM_HOSTBYTE_STRS ? hostbyte_table[hb] : "invalid"), >+ (db < NUM_DRIVERBYTE_STRS ? driverbyte_table[db] : "invalid"), > (su < NUM_SUGGEST_STRS ? driversuggest_table[su] : "invalid")); > } >+ > #else >-void scsi_print_driverbyte(int scsiresult) >+ >+void scsi_show_result(int result) > { >- printk("Driverbyte=0x%02x ", driver_byte(scsiresult)); >+ printk("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); >+} >+EXPORT_SYMBOL(scsi_print_result); >+ >+ >diff --git a/include/scsi/scsi_dbg.h b/include/scsi/scsi_dbg.h >index 3bbbfbe..5a43a4c 100644 >--- a/include/scsi/scsi_dbg.h >+++ b/include/scsi/scsi_dbg.h >@@ -5,14 +5,16 @@ struct scsi_cmnd; > struct scsi_sense_hdr; > > extern void scsi_print_command(struct scsi_cmnd *); >-extern void scsi_print_sense_hdr(const char *, struct scsi_sense_hdr *); > extern void __scsi_print_command(unsigned char *); >-extern void scsi_print_sense(const char *, struct scsi_cmnd *); >+extern void scsi_show_extd_sense(unsigned char, unsigned char); >+extern void scsi_show_sense_hdr(struct scsi_sense_hdr *); >+extern void scsi_print_sense_hdr(const char *, struct scsi_sense_hdr *); >+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_print_driverbyte(int); >-extern void scsi_print_hostbyte(int); >+extern void scsi_show_result(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); > extern const char *scsi_extd_sense_format(unsigned char, unsigned char); >From: Martin K. Petersen <martin.petersen@oracle.com> >Date: Wed, 28 Feb 2007 03:40:55 +0000 (-0500) >Subject: [SCSI] sd: make printing use a common prefix >X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=e73aec8247032ee730b5f38edf48922c4f72522e;hp=a4d04a4cd9881e89fdc62107b6b57053438f2b30 > >[SCSI] sd: make printing use a common prefix > >Make SCSI disk printing more consistent: > > - Define sd_printk(), sd_print_sense_hdr() and sd_print_result() > > - Move relevant header bits into sd.h > > - Remove all the legacy disk_name passing and use scsi_disk pointers > where possible > > - Switch printk() lines to the new sd_ functions so that output is > consistent > >Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> >Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com> >--- > >diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c >index 5a8f55f..b5562b8 100644 >--- a/drivers/scsi/sd.c >+++ b/drivers/scsi/sd.c >@@ -58,16 +58,10 @@ > #include <scsi/scsi_host.h> > #include <scsi/scsi_ioctl.h> > #include <scsi/scsicam.h> >+#include <scsi/sd.h> > > #include "scsi_logging.h" > >-/* >- * More than enough for everybody ;) The huge number of majors >- * is a leftover from 16bit dev_t days, we don't really need that >- * much numberspace. >- */ >-#define SD_MAJORS 16 >- > MODULE_AUTHOR("Eric Youngdale"); > MODULE_DESCRIPTION("SCSI disk (sd) driver"); > MODULE_LICENSE("GPL"); >@@ -89,45 +83,6 @@ MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK13_MAJOR); > MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK14_MAJOR); > MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK15_MAJOR); > >-/* >- * This is limited by the naming scheme enforced in sd_probe, >- * add another character to it if you really need more disks. >- */ >-#define SD_MAX_DISKS (((26 * 26) + 26 + 1) * 26) >- >-/* >- * Time out in seconds for disks and Magneto-opticals (which are slower). >- */ >-#define SD_TIMEOUT (30 * HZ) >-#define SD_MOD_TIMEOUT (75 * HZ) >- >-/* >- * Number of allowed retries >- */ >-#define SD_MAX_RETRIES 5 >-#define SD_PASSTHROUGH_RETRIES 1 >- >-/* >- * Size of the initial data buffer for mode and read capacity data >- */ >-#define SD_BUF_SIZE 512 >- >-struct scsi_disk { >- struct scsi_driver *driver; /* always &sd_template */ >- struct scsi_device *device; >- struct class_device cdev; >- struct gendisk *disk; >- unsigned int openers; /* protected by BKL for now, yuck */ >- sector_t capacity; /* size in 512-byte sectors */ >- u32 index; >- u8 media_present; >- u8 write_prot; >- unsigned WCE : 1; /* state of disk WCE bit */ >- unsigned RCD : 1; /* state of disk RCD bit, unused */ >- unsigned DPOFUA : 1; /* state of disk DPOFUA bit */ >-}; >-#define to_scsi_disk(obj) container_of(obj,struct scsi_disk,cdev) >- > static DEFINE_IDR(sd_index_idr); > static DEFINE_SPINLOCK(sd_index_lock); > >@@ -136,20 +91,6 @@ static DEFINE_SPINLOCK(sd_index_lock); > * object after last put) */ > static DEFINE_MUTEX(sd_ref_mutex); > >-static int sd_revalidate_disk(struct gendisk *disk); >-static void sd_rw_intr(struct scsi_cmnd * SCpnt); >- >-static int sd_probe(struct device *); >-static int sd_remove(struct device *); >-static void sd_shutdown(struct device *dev); >-static void sd_rescan(struct device *); >-static int sd_init_command(struct scsi_cmnd *); >-static int sd_issue_flush(struct device *, sector_t *); >-static void sd_prepare_flush(request_queue_t *, struct request *); >-static void sd_read_capacity(struct scsi_disk *sdkp, char *diskname, >- unsigned char *buffer); >-static void scsi_disk_release(struct class_device *cdev); >- > static const char *sd_cache_types[] = { > "write through", "none", "write back", > "write back, no read (daft)" >@@ -199,7 +140,7 @@ static ssize_t sd_store_cache_type(struct class_device *cdev, const char *buf, > if (scsi_mode_select(sdp, 1, sp, 8, buffer_data, len, SD_TIMEOUT, > SD_MAX_RETRIES, &data, &sshdr)) { > if (scsi_sense_valid(&sshdr)) >- scsi_print_sense_hdr(sdkp->disk->disk_name, &sshdr); >+ sd_print_sense_hdr(sdkp, &sshdr); > return -EINVAL; > } > sd_revalidate_disk(sdkp->disk); >@@ -407,7 +348,8 @@ static int sd_init_command(struct scsi_cmnd * SCpnt) > */ > if (sdp->sector_size == 1024) { > if ((block & 1) || (rq->nr_sectors & 1)) { >- printk(KERN_ERR "sd: Bad block number requested"); >+ scmd_printk(KERN_ERR, SCpnt, >+ "Bad block number requested\n"); > return 0; > } else { > block = block >> 1; >@@ -416,7 +358,8 @@ static int sd_init_command(struct scsi_cmnd * SCpnt) > } > if (sdp->sector_size == 2048) { > if ((block & 3) || (rq->nr_sectors & 3)) { >- printk(KERN_ERR "sd: Bad block number requested"); >+ scmd_printk(KERN_ERR, SCpnt, >+ "Bad block number requested\n"); > return 0; > } else { > block = block >> 2; >@@ -425,7 +368,8 @@ static int sd_init_command(struct scsi_cmnd * SCpnt) > } > if (sdp->sector_size == 4096) { > if ((block & 7) || (rq->nr_sectors & 7)) { >- printk(KERN_ERR "sd: Bad block number requested"); >+ scmd_printk(KERN_ERR, SCpnt, >+ "Bad block number requested\n"); > return 0; > } else { > block = block >> 3; >@@ -442,7 +386,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt) > SCpnt->cmnd[0] = READ_6; > SCpnt->sc_data_direction = DMA_FROM_DEVICE; > } else { >- printk(KERN_ERR "sd: Unknown command %x\n", rq->cmd_flags); >+ scmd_printk(KERN_ERR, SCpnt, "Unknown command %x\n", rq->cmd_flags); > return 0; > } > >@@ -490,7 +434,8 @@ static int sd_init_command(struct scsi_cmnd * SCpnt) > * during operation and thus turned off > * use_10_for_rw. > */ >- printk(KERN_ERR "sd: FUA write on READ/WRITE(6) drive\n"); >+ scmd_printk(KERN_ERR, SCpnt, >+ "FUA write on READ/WRITE(6) drive\n"); > return 0; > } > >@@ -786,9 +731,10 @@ not_present: > return 1; > } > >-static int sd_sync_cache(struct scsi_device *sdp) >+static int sd_sync_cache(struct scsi_disk *sdkp) > { > int retries, res; >+ struct scsi_device *sdp = sdkp->device; > struct scsi_sense_hdr sshdr; > > if (!scsi_device_online(sdp)) >@@ -809,12 +755,10 @@ static int sd_sync_cache(struct scsi_device *sdp) > break; > } > >- if (res) { printk(KERN_WARNING "FAILED\n status = %x, message = %02x, " >- "host = %d, driver = %02x\n ", >- status_byte(res), msg_byte(res), >- host_byte(res), driver_byte(res)); >- if (driver_byte(res) & DRIVER_SENSE) >- scsi_print_sense_hdr("sd", &sshdr); >+ if (res) { >+ sd_print_result(sdkp, res); >+ if (driver_byte(res) & DRIVER_SENSE) >+ sd_print_sense_hdr(sdkp, &sshdr); > } > > return res; >@@ -823,14 +767,13 @@ static int sd_sync_cache(struct scsi_device *sdp) > static int sd_issue_flush(struct device *dev, sector_t *error_sector) > { > int ret = 0; >- struct scsi_device *sdp = to_scsi_device(dev); > struct scsi_disk *sdkp = scsi_disk_get_from_dev(dev); > > if (!sdkp) > return -ENODEV; > > if (sdkp->WCE) >- ret = sd_sync_cache(sdp); >+ ret = sd_sync_cache(sdkp); > scsi_disk_put(sdkp); > return ret; > } >@@ -1025,7 +968,7 @@ static int media_not_present(struct scsi_disk *sdkp, > * spinup disk - called only in sd_revalidate_disk() > */ > static void >-sd_spinup_disk(struct scsi_disk *sdkp, char *diskname) >+sd_spinup_disk(struct scsi_disk *sdkp) > { > unsigned char cmd[10]; > unsigned long spintime_expire = 0; >@@ -1069,9 +1012,10 @@ sd_spinup_disk(struct scsi_disk *sdkp, char *diskname) > if ((driver_byte(the_result) & DRIVER_SENSE) == 0) { > /* no sense, TUR either succeeded or failed > * with a status error */ >- if(!spintime && !scsi_status_is_good(the_result)) >- printk(KERN_NOTICE "%s: Unit Not Ready, " >- "error = 0x%x\n", diskname, the_result); >+ if(!spintime && !scsi_status_is_good(the_result)) { >+ sd_printk(KERN_NOTICE, sdkp, "Unit Not Ready\n"); >+ sd_print_result(sdkp, the_result); >+ } > break; > } > >@@ -1096,8 +1040,7 @@ sd_spinup_disk(struct scsi_disk *sdkp, char *diskname) > */ > } else if (sense_valid && sshdr.sense_key == NOT_READY) { > if (!spintime) { >- printk(KERN_NOTICE "%s: Spinning up disk...", >- diskname); >+ sd_printk(KERN_NOTICE, sdkp, "Spinning up disk..."); > cmd[0] = START_STOP; > cmd[1] = 1; /* Return immediately */ > memset((void *) &cmd[2], 0, 8); >@@ -1130,9 +1073,8 @@ sd_spinup_disk(struct scsi_disk *sdkp, char *diskname) > /* we don't understand the sense code, so it's > * probably pointless to loop */ > if(!spintime) { >- printk(KERN_NOTICE "%s: Unit Not Ready, " >- "sense:\n", diskname); >- scsi_print_sense_hdr("", &sshdr); >+ sd_printk(KERN_NOTICE, sdkp, "Unit Not Ready\n"); >+ sd_print_sense_hdr(sdkp, &sshdr); > } > break; > } >@@ -1151,8 +1093,7 @@ sd_spinup_disk(struct scsi_disk *sdkp, char *diskname) > * read disk capacity > */ > static void >-sd_read_capacity(struct scsi_disk *sdkp, char *diskname, >- unsigned char *buffer) >+sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer) > { > unsigned char cmd[16]; > int the_result, retries; >@@ -1191,18 +1132,12 @@ repeat: > } while (the_result && retries); > > if (the_result && !longrc) { >- printk(KERN_NOTICE "%s : READ CAPACITY failed.\n" >- "%s : status=%x, message=%02x, host=%d, driver=%02x \n", >- diskname, diskname, >- status_byte(the_result), >- msg_byte(the_result), >- host_byte(the_result), >- driver_byte(the_result)); >- >+ sd_printk(KERN_NOTICE, sdkp, "READ CAPACITY failed\n"); >+ sd_print_result(sdkp, the_result); > if (driver_byte(the_result) & DRIVER_SENSE) >- scsi_print_sense_hdr("sd", &sshdr); >+ sd_print_sense_hdr(sdkp, &sshdr); > else >- printk("%s : sense not available. \n", diskname); >+ sd_printk(KERN_NOTICE, sdkp, "Sense not available.\n"); > > /* Set dirty bit for removable devices if not ready - > * sometimes drives will not report this properly. */ >@@ -1218,16 +1153,10 @@ repeat: > return; > } else if (the_result && longrc) { > /* READ CAPACITY(16) has been failed */ >- printk(KERN_NOTICE "%s : READ CAPACITY(16) failed.\n" >- "%s : status=%x, message=%02x, host=%d, driver=%02x \n", >- diskname, diskname, >- status_byte(the_result), >- msg_byte(the_result), >- host_byte(the_result), >- driver_byte(the_result)); >- printk(KERN_NOTICE "%s : use 0xffffffff as device size\n", >- diskname); >- >+ sd_printk(KERN_NOTICE, sdkp, "READ CAPACITY(16) failed\n"); >+ sd_print_result(sdkp, the_result); >+ sd_printk(KERN_NOTICE, sdkp, "Use 0xffffffff as device size\n"); >+ > sdkp->capacity = 1 + (sector_t) 0xffffffff; > goto got_data; > } >@@ -1238,14 +1167,14 @@ repeat: > if (buffer[0] == 0xff && buffer[1] == 0xff && > buffer[2] == 0xff && buffer[3] == 0xff) { > if(sizeof(sdkp->capacity) > 4) { >- printk(KERN_NOTICE "%s : very big device. try to use" >- " READ CAPACITY(16).\n", diskname); >+ sd_printk(KERN_NOTICE, sdkp, "Very big device. " >+ "Trying to use READ CAPACITY(16).\n"); > longrc = 1; > goto repeat; > } >- printk(KERN_ERR "%s: too big for this kernel. Use a " >- "kernel compiled with support for large block " >- "devices.\n", diskname); >+ sd_printk(KERN_ERR, sdkp, "Too big for this kernel. Use " >+ "a kernel compiled with support for large " >+ "block devices.\n"); > sdkp->capacity = 0; > goto got_data; > } >@@ -1284,8 +1213,8 @@ repeat: > got_data: > if (sector_size == 0) { > sector_size = 512; >- printk(KERN_NOTICE "%s : sector size 0 reported, " >- "assuming 512.\n", diskname); >+ sd_printk(KERN_NOTICE, sdkp, "Sector size 0 reported, " >+ "assuming 512.\n"); > } > > if (sector_size != 512 && >@@ -1293,8 +1222,8 @@ got_data: > sector_size != 2048 && > sector_size != 4096 && > sector_size != 256) { >- printk(KERN_NOTICE "%s : unsupported sector size " >- "%d.\n", diskname, sector_size); >+ sd_printk(KERN_NOTICE, sdkp, "Unsupported sector size %d.\n", >+ sector_size); > /* > * The user might want to re-format the drive with > * a supported sectorsize. Once this happens, it >@@ -1327,10 +1256,10 @@ got_data: > mb -= sz - 974; > sector_div(mb, 1950); > >- printk(KERN_NOTICE "SCSI device %s: " >- "%llu %d-byte hdwr sectors (%llu MB)\n", >- diskname, (unsigned long long)sdkp->capacity, >- hard_sector, (unsigned long long)mb); >+ sd_printk(KERN_NOTICE, sdkp, >+ "%llu %d-byte hardware sectors (%llu MB)\n", >+ (unsigned long long)sdkp->capacity, >+ hard_sector, (unsigned long long)mb); > } > > /* Rescale capacity to 512-byte units */ >@@ -1362,8 +1291,7 @@ sd_do_mode_sense(struct scsi_device *sdp, int dbd, int modepage, > * called with buffer of length SD_BUF_SIZE > */ > static void >-sd_read_write_protect_flag(struct scsi_disk *sdkp, char *diskname, >- unsigned char *buffer) >+sd_read_write_protect_flag(struct scsi_disk *sdkp, unsigned char *buffer) > { > int res; > struct scsi_device *sdp = sdkp->device; >@@ -1371,7 +1299,7 @@ sd_read_write_protect_flag(struct scsi_disk *sdkp, char *diskname, > > set_disk_ro(sdkp->disk, 0); > if (sdp->skip_ms_page_3f) { >- printk(KERN_NOTICE "%s: assuming Write Enabled\n", diskname); >+ sd_printk(KERN_NOTICE, sdkp, "Assuming Write Enabled\n"); > return; > } > >@@ -1403,15 +1331,16 @@ sd_read_write_protect_flag(struct scsi_disk *sdkp, char *diskname, > } > > if (!scsi_status_is_good(res)) { >- printk(KERN_WARNING >- "%s: test WP failed, assume Write Enabled\n", diskname); >+ sd_printk(KERN_WARNING, sdkp, >+ "Test WP failed, assume Write Enabled\n"); > } else { > sdkp->write_prot = ((data.device_specific & 0x80) != 0); > set_disk_ro(sdkp->disk, sdkp->write_prot); >- printk(KERN_NOTICE "%s: Write Protect is %s\n", diskname, >- sdkp->write_prot ? "on" : "off"); >- printk(KERN_DEBUG "%s: Mode Sense: %02x %02x %02x %02x\n", >- diskname, buffer[0], buffer[1], buffer[2], buffer[3]); >+ sd_printk(KERN_NOTICE, sdkp, "Write Protect is %s\n", >+ sdkp->write_prot ? "on" : "off"); >+ sd_printk(KERN_DEBUG, sdkp, >+ "Mode Sense: %02x %02x %02x %02x\n", >+ buffer[0], buffer[1], buffer[2], buffer[3]); > } > } > >@@ -1420,8 +1349,7 @@ sd_read_write_protect_flag(struct scsi_disk *sdkp, char *diskname, > * called with buffer of length SD_BUF_SIZE > */ > static void >-sd_read_cache_type(struct scsi_disk *sdkp, char *diskname, >- unsigned char *buffer) >+sd_read_cache_type(struct scsi_disk *sdkp, unsigned char *buffer) > { > int len = 0, res; > struct scsi_device *sdp = sdkp->device; >@@ -1450,8 +1378,7 @@ sd_read_cache_type(struct scsi_disk *sdkp, char *diskname, > > if (!data.header_length) { > modepage = 6; >- printk(KERN_ERR "%s: missing header in MODE_SENSE response\n", >- diskname); >+ sd_printk(KERN_ERR, sdkp, "Missing header in MODE_SENSE response\n"); > } > > /* that went OK, now ask for the proper length */ >@@ -1478,13 +1405,12 @@ sd_read_cache_type(struct scsi_disk *sdkp, char *diskname, > int offset = data.header_length + data.block_descriptor_length; > > if (offset >= SD_BUF_SIZE - 2) { >- printk(KERN_ERR "%s: malformed MODE SENSE response", >- diskname); >+ sd_printk(KERN_ERR, sdkp, "Malformed MODE SENSE response\n"); > goto defaults; > } > > if ((buffer[offset] & 0x3f) != modepage) { >- printk(KERN_ERR "%s: got wrong page\n", diskname); >+ sd_printk(KERN_ERR, sdkp, "Got wrong page\n"); > goto defaults; > } > >@@ -1498,14 +1424,13 @@ sd_read_cache_type(struct scsi_disk *sdkp, char *diskname, > > sdkp->DPOFUA = (data.device_specific & 0x10) != 0; > if (sdkp->DPOFUA && !sdkp->device->use_10_for_rw) { >- printk(KERN_NOTICE "SCSI device %s: uses " >- "READ/WRITE(6), disabling FUA\n", diskname); >+ sd_printk(KERN_NOTICE, sdkp, >+ "Uses READ/WRITE(6), disabling FUA\n"); > sdkp->DPOFUA = 0; > } > >- printk(KERN_NOTICE "SCSI device %s: " >- "write cache: %s, read cache: %s, %s\n", >- diskname, >+ sd_printk(KERN_NOTICE, sdkp, >+ "Write cache: %s, read cache: %s, %s\n", > sdkp->WCE ? "enabled" : "disabled", > sdkp->RCD ? "disabled" : "enabled", > sdkp->DPOFUA ? "supports DPO and FUA" >@@ -1518,15 +1443,13 @@ bad_sense: > if (scsi_sense_valid(&sshdr) && > sshdr.sense_key == ILLEGAL_REQUEST && > sshdr.asc == 0x24 && sshdr.ascq == 0x0) >- printk(KERN_NOTICE "%s: cache data unavailable\n", >- diskname); /* Invalid field in CDB */ >+ /* Invalid field in CDB */ >+ sd_printk(KERN_NOTICE, sdkp, "Cache data unavailable\n"); > else >- printk(KERN_ERR "%s: asking for cache data failed\n", >- diskname); >+ sd_printk(KERN_ERR, sdkp, "Asking for cache data failed\n"); > > defaults: >- printk(KERN_ERR "%s: assuming drive cache: write through\n", >- diskname); >+ sd_printk(KERN_ERR, sdkp, "Assuming drive cache: write through\n"); > sdkp->WCE = 0; > sdkp->RCD = 0; > sdkp->DPOFUA = 0; >@@ -1555,8 +1478,8 @@ static int sd_revalidate_disk(struct gendisk *disk) > > buffer = kmalloc(SD_BUF_SIZE, GFP_KERNEL | __GFP_DMA); > if (!buffer) { >- printk(KERN_WARNING "(sd_revalidate_disk:) Memory allocation " >- "failure.\n"); >+ sd_printk(KERN_WARNING, sdkp, "sd_revalidate_disk: Memory " >+ "allocation failure.\n"); > goto out; > } > >@@ -1568,16 +1491,16 @@ static int sd_revalidate_disk(struct gendisk *disk) > sdkp->WCE = 0; > sdkp->RCD = 0; > >- sd_spinup_disk(sdkp, disk->disk_name); >+ sd_spinup_disk(sdkp); > > /* > * Without media there is no reason to ask; moreover, some devices > * react badly if we do. > */ > if (sdkp->media_present) { >- sd_read_capacity(sdkp, disk->disk_name, buffer); >- sd_read_write_protect_flag(sdkp, disk->disk_name, buffer); >- sd_read_cache_type(sdkp, disk->disk_name, buffer); >+ sd_read_capacity(sdkp, buffer); >+ sd_read_write_protect_flag(sdkp, buffer); >+ sd_read_cache_type(sdkp, buffer); > } > > /* >@@ -1709,8 +1632,8 @@ static int sd_probe(struct device *dev) > dev_set_drvdata(dev, sdkp); > add_disk(gd); > >- sdev_printk(KERN_NOTICE, sdp, "Attached scsi %sdisk %s\n", >- sdp->removable ? "removable " : "", gd->disk_name); >+ sd_printk(KERN_NOTICE, sdkp, "Attached SCSI %sdisk\n", >+ sdp->removable ? "removable " : ""); > > return 0; > >@@ -1781,16 +1704,14 @@ static void scsi_disk_release(struct class_device *cdev) > */ > static void sd_shutdown(struct device *dev) > { >- struct scsi_device *sdp = to_scsi_device(dev); > struct scsi_disk *sdkp = scsi_disk_get_from_dev(dev); > > if (!sdkp) > return; /* this can happen */ > > if (sdkp->WCE) { >- printk(KERN_NOTICE "Synchronizing SCSI cache for disk %s: \n", >- sdkp->disk->disk_name); >- sd_sync_cache(sdp); >+ sd_printk(KERN_NOTICE, sdkp, "Synchronizing SCSI cache\n"); >+ sd_sync_cache(sdkp); > } > scsi_disk_put(sdkp); > } >@@ -1852,3 +1773,19 @@ static void __exit exit_sd(void) > > module_init(init_sd); > module_exit(exit_sd); >+ >+static void sd_print_sense_hdr(struct scsi_disk *sdkp, >+ struct scsi_sense_hdr *sshdr) >+{ >+ sd_printk(KERN_INFO, sdkp, ""); >+ scsi_show_sense_hdr(sshdr); >+ sd_printk(KERN_INFO, sdkp, ""); >+ scsi_show_extd_sense(sshdr->asc, sshdr->ascq); >+} >+ >+static void sd_print_result(struct scsi_disk *sdkp, int result) >+{ >+ sd_printk(KERN_INFO, sdkp, ""); >+ scsi_show_result(result); >+} >+ >diff --git a/include/scsi/sd.h b/include/scsi/sd.h >new file mode 100644 >index 0000000..82e6a84 >--- /dev/null >+++ b/include/scsi/sd.h >@@ -0,0 +1,70 @@ >+#ifndef _SCSI_DISK_H >+#define _SCSI_DISK_H >+ >+/* >+ * More than enough for everybody ;) The huge number of majors >+ * is a leftover from 16bit dev_t days, we don't really need that >+ * much numberspace. >+ */ >+#define SD_MAJORS 16 >+ >+/* >+ * This is limited by the naming scheme enforced in sd_probe, >+ * add another character to it if you really need more disks. >+ */ >+#define SD_MAX_DISKS (((26 * 26) + 26 + 1) * 26) >+ >+/* >+ * Time out in seconds for disks and Magneto-opticals (which are slower). >+ */ >+#define SD_TIMEOUT (30 * HZ) >+#define SD_MOD_TIMEOUT (75 * HZ) >+ >+/* >+ * Number of allowed retries >+ */ >+#define SD_MAX_RETRIES 5 >+#define SD_PASSTHROUGH_RETRIES 1 >+ >+/* >+ * Size of the initial data buffer for mode and read capacity data >+ */ >+#define SD_BUF_SIZE 512 >+ >+struct scsi_disk { >+ struct scsi_driver *driver; /* always &sd_template */ >+ struct scsi_device *device; >+ struct class_device cdev; >+ struct gendisk *disk; >+ unsigned int openers; /* protected by BKL for now, yuck */ >+ sector_t capacity; /* size in 512-byte sectors */ >+ u32 index; >+ u8 media_present; >+ u8 write_prot; >+ unsigned WCE : 1; /* state of disk WCE bit */ >+ unsigned RCD : 1; /* state of disk RCD bit, unused */ >+ unsigned DPOFUA : 1; /* state of disk DPOFUA bit */ >+}; >+#define to_scsi_disk(obj) container_of(obj,struct scsi_disk,cdev) >+ >+static int sd_revalidate_disk(struct gendisk *disk); >+static void sd_rw_intr(struct scsi_cmnd * SCpnt); >+static int sd_probe(struct device *); >+static int sd_remove(struct device *); >+static void sd_shutdown(struct device *dev); >+static void sd_rescan(struct device *); >+static int sd_init_command(struct scsi_cmnd *); >+static int sd_issue_flush(struct device *, sector_t *); >+static void sd_prepare_flush(request_queue_t *, struct request *); >+static void sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer); >+static void scsi_disk_release(struct class_device *cdev); >+static void sd_print_sense_hdr(struct scsi_disk *, struct scsi_sense_hdr *); >+static void sd_print_result(struct scsi_disk *, int); >+ >+#define sd_printk(prefix, sdsk, fmt, a...) \ >+ (sdsk)->disk ? \ >+ sdev_printk(prefix, (sdsk)->device, "[%s] " fmt, \ >+ (sdsk)->disk->disk_name, ##a) : \ >+ sdev_printk(prefix, (sdsk)->device, fmt, ##a) >+ >+#endif /* _SCSI_DISK_H */ >From: Tejun Heo <htejun@gmail.com> >Date: Tue, 20 Mar 2007 15:07:18 +0000 (+0900) >Subject: [SCSI] sd: fix return value of sd_sync_cache() >X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=3721050afc6cb6ddf6de0f782e2054ebcc225e9b;hp=ad8c31bb69d60c0c6bc6431bccdf67e5a96c0d31 > >[SCSI] sd: fix return value of sd_sync_cache() > >sd_sync_cache() should return -errno on error, fix it. > >Signed-off-by: Tejun Heo <htejun@gmail.com> >Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com> >--- > >diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c >index 12e18bb..3dda77c 100644 >--- a/drivers/scsi/sd.c >+++ b/drivers/scsi/sd.c >@@ -766,7 +766,9 @@ static int sd_sync_cache(struct scsi_disk *sdkp) > sd_print_sense_hdr(sdkp, &sshdr); > } > >- return res; >+ if (res) >+ return -EIO; >+ return 0; > } > > static int sd_issue_flush(struct device *dev, sector_t *error_sector) >From: Tejun Heo <htejun@gmail.com> >Date: Tue, 20 Mar 2007 15:13:59 +0000 (+0900) >Subject: [SCSI] sd: implement START/STOP management >X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=c3c94c5a2fb43a654e777f509d5032b0db8ed09f;hp=3721050afc6cb6ddf6de0f782e2054ebcc225e9b > >[SCSI] sd: implement START/STOP management > >Implement SBC START/STOP management. sdev->mange_start_stop is added. >When it's set to one, sd STOPs the device on suspend and shutdown and >STARTs it on resume. sdev->manage_start_stop defaults is in sdev >instead of scsi_disk cdev to allow ->slave_config() override the >default configuration but is exported under scsi_disk sysfs node as >sdev->allow_restart is. > >When manage_start_stop is zero (the default value), this patch doesn't >introduce any behavior change. > >Signed-off-by: Tejun Heo <htejun@gmail.com> > >Rejections fixed and >Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com> >--- > >diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c >index c275dca..96db51c 100644 >--- a/drivers/scsi/scsi_sysfs.c >+++ b/drivers/scsi/scsi_sysfs.c >@@ -278,6 +278,7 @@ static int scsi_bus_match(struct device *dev, struct device_driver *gendrv) > > static int scsi_bus_suspend(struct device * dev, pm_message_t state) > { >+ struct device_driver *drv = dev->driver; > struct scsi_device *sdev = to_scsi_device(dev); > struct scsi_host_template *sht = sdev->host->hostt; > int err; >@@ -286,23 +287,45 @@ static int scsi_bus_suspend(struct device * dev, pm_message_t state) > if (err) > return err; > >- if (sht->suspend) >+ /* call HLD suspend first */ >+ if (drv && drv->suspend) { >+ err = drv->suspend(dev, state); >+ if (err) >+ return err; >+ } >+ >+ /* then, call host suspend */ >+ if (sht->suspend) { > err = sht->suspend(sdev, state); >+ if (err) { >+ if (drv && drv->resume) >+ drv->resume(dev); >+ return err; >+ } >+ } > >- return err; >+ return 0; > } > > static int scsi_bus_resume(struct device * dev) > { >+ struct device_driver *drv = dev->driver; > struct scsi_device *sdev = to_scsi_device(dev); > struct scsi_host_template *sht = sdev->host->hostt; >- int err = 0; >+ int err = 0, err2 = 0; > >+ /* call host resume first */ > if (sht->resume) > err = sht->resume(sdev); > >+ /* then, call HLD resume */ >+ if (drv && drv->resume) >+ err2 = drv->resume(dev); >+ > scsi_device_resume(sdev); >- return err; >+ >+ /* favor LLD failure */ >+ return err ? err : err2;; > } > > struct bus_type scsi_bus_type = { >diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c >index 3dda77c..49a94ae 100644 >--- a/drivers/scsi/sd.c >+++ b/drivers/scsi/sd.c >@@ -147,6 +147,20 @@ static ssize_t sd_store_cache_type(struct class_device *cdev, const char *buf, > return count; > } > >+static ssize_t sd_store_manage_start_stop(struct class_device *cdev, >+ const char *buf, size_t count) >+{ >+ struct scsi_disk *sdkp = to_scsi_disk(cdev); >+ struct scsi_device *sdp = sdkp->device; >+ >+ if (!capable(CAP_SYS_ADMIN)) >+ return -EACCES; >+ >+ sdp->manage_start_stop = simple_strtoul(buf, NULL, 10); >+ >+ return count; >+} >+ > static ssize_t sd_store_allow_restart(struct class_device *cdev, const char *buf, > size_t count) > { >@@ -179,6 +193,14 @@ static ssize_t sd_show_fua(struct class_device *cdev, char *buf) > return snprintf(buf, 20, "%u\n", sdkp->DPOFUA); > } > >+static ssize_t sd_show_manage_start_stop(struct class_device *cdev, char *buf) >+{ >+ struct scsi_disk *sdkp = to_scsi_disk(cdev); >+ struct scsi_device *sdp = sdkp->device; >+ >+ return snprintf(buf, 20, "%u\n", sdp->manage_start_stop); >+} >+ > static ssize_t sd_show_allow_restart(struct class_device *cdev, char *buf) > { > struct scsi_disk *sdkp = to_scsi_disk(cdev); >@@ -192,6 +214,8 @@ static struct class_device_attribute sd_disk_attrs[] = { > __ATTR(FUA, S_IRUGO, sd_show_fua, NULL), > __ATTR(allow_restart, S_IRUGO|S_IWUSR, sd_show_allow_restart, > sd_store_allow_restart), >+ __ATTR(manage_start_stop, S_IRUGO|S_IWUSR, sd_show_manage_start_stop, >+ sd_store_manage_start_stop), > __ATTR_NULL, > }; > >@@ -208,6 +232,8 @@ static struct scsi_driver sd_template = { > .name = "sd", > .probe = sd_probe, > .remove = sd_remove, >+ .suspend = sd_suspend, >+ .resume = sd_resume, > .shutdown = sd_shutdown, > }, > .rescan = sd_rescan, >@@ -1707,6 +1733,32 @@ static void scsi_disk_release(struct class_device *cdev) > kfree(sdkp); > } > >+static int sd_start_stop_device(struct scsi_device *sdp, int start) >+{ >+ unsigned char cmd[6] = { START_STOP }; /* START_VALID */ >+ struct scsi_sense_hdr sshdr; >+ int res; >+ >+ if (start) >+ cmd[4] |= 1; /* START */ >+ >+ if (!scsi_device_online(sdp)) >+ return -ENODEV; >+ >+ res = scsi_execute_req(sdp, cmd, DMA_NONE, NULL, 0, &sshdr, >+ SD_TIMEOUT, SD_MAX_RETRIES); >+ if (res) { >+ printk(KERN_WARNING "FAILED\n status = %x, message = %02x, " >+ "host = %d, driver = %02x\n ", >+ status_byte(res), msg_byte(res), >+ host_byte(res), driver_byte(res)); >+ if (driver_byte(res) & DRIVER_SENSE) >+ scsi_print_sense_hdr("sd", &sshdr); >+ } >+ >+ return res; >+} >+ > /* > * Send a SYNCHRONIZE CACHE instruction down to the device through > * the normal SCSI command structure. Wait for the command to >@@ -1714,6 +1766,7 @@ static void scsi_disk_release(struct class_device *cdev) > */ > static void sd_shutdown(struct device *dev) > { >+ struct scsi_device *sdp = to_scsi_device(dev); > struct scsi_disk *sdkp = scsi_disk_get_from_dev(dev); > > if (!sdkp) >@@ -1723,9 +1776,57 @@ static void sd_shutdown(struct device *dev) > sd_printk(KERN_NOTICE, sdkp, "Synchronizing SCSI cache\n"); > sd_sync_cache(sdkp); > } >+ >+ if (system_state != SYSTEM_RESTART && sdp->manage_start_stop) { >+ printk(KERN_NOTICE "Stopping disk %s: \n", >+ sdkp->disk->disk_name); >+ sd_start_stop_device(sdp, 0); >+ } >+ > scsi_disk_put(sdkp); > } > >+static int sd_suspend(struct device *dev, pm_message_t mesg) >+{ >+ struct scsi_device *sdp = to_scsi_device(dev); >+ struct scsi_disk *sdkp = scsi_disk_get_from_dev(dev); >+ int ret; >+ >+ if (!sdkp) >+ return 0; /* this can happen */ >+ >+ if (sdkp->WCE) { >+ printk(KERN_NOTICE "Synchronizing SCSI cache for disk %s: \n", >+ sdkp->disk->disk_name); >+ ret = sd_sync_cache(sdkp); >+ if (ret) >+ return ret; >+ } >+ >+ if (mesg.event == PM_EVENT_SUSPEND && sdp->manage_start_stop) { >+ printk(KERN_NOTICE "Stopping disk %s: \n", >+ sdkp->disk->disk_name); >+ ret = sd_start_stop_device(sdp, 0); >+ if (ret) >+ return ret; >+ } >+ >+ return 0; >+} >+ >+static int sd_resume(struct device *dev) >+{ >+ struct scsi_device *sdp = to_scsi_device(dev); >+ struct scsi_disk *sdkp = scsi_disk_get_from_dev(dev); >+ >+ if (!sdp->manage_start_stop) >+ return 0; >+ >+ printk(KERN_NOTICE "Starting disk %s: \n", sdkp->disk->disk_name); >+ >+ return sd_start_stop_device(sdp, 1); >+} >+ > /** > * init_sd - entry point for this driver (both when built in or when > * a module). >diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h >index c86e6ce..b05cd3b 100644 >--- a/include/scsi/scsi_device.h >+++ b/include/scsi/scsi_device.h >@@ -120,6 +120,7 @@ struct scsi_device { > unsigned use_192_bytes_for_3f:1; /* ask for 192 bytes from page 0x3f */ > unsigned no_start_on_add:1; /* do not issue start on add */ > unsigned allow_restart:1; /* issue START_UNIT in error handler */ >+ unsigned manage_start_stop:1; /* Let HLD (sd) manage start/stop */ > unsigned no_uld_attach:1; /* disable connecting to upper level drivers */ > unsigned select_no_atn:1; > unsigned fix_capacity:1; /* READ_CAPACITY is too high by 1 */ >diff --git a/include/scsi/sd.h b/include/scsi/sd.h >index 82e6a84..5261488 100644 >--- a/include/scsi/sd.h >+++ b/include/scsi/sd.h >@@ -52,6 +52,8 @@ static void sd_rw_intr(struct scsi_cmnd * SCpnt); > static int sd_probe(struct device *); > static int sd_remove(struct device *); > static void sd_shutdown(struct device *dev); >+static int sd_suspend(struct device *dev, pm_message_t state); >+static int sd_resume(struct device *dev); > static void sd_rescan(struct device *); > static int sd_init_command(struct scsi_cmnd *); > static int sd_issue_flush(struct device *, sector_t *); >Reimplement suspend/resume support using sdev->manage_start_stop. > >* Device suspend/resume is now SCSI layer's responsibility and the > code is simplified a lot. > >* DPM is dropped. This also simplifies code a lot. Suspend/resume > status is port-wide now. > >* ata_scsi_device_suspend/resume() and ata_dev_ready() removed. > >* Resume now has to wait for disk to spin up before proceeding. I > couldn't find easy way out as libata is in EH waiting for the > disk to be ready and sd is waiting for EH to complete to issue > START_STOP. > >* sdev->manage_start_stop is set to 1 in ata_scsi_slave_config(). > This fixes spindown on shutdown and suspend-to-disk. > >Signed-off-by: Tejun Heo <htejun@gmail.com> >--- > drivers/ata/ahci.c | 4 - > drivers/ata/ata_generic.c | 6 +- > drivers/ata/ata_piix.c | 4 - > drivers/ata/libata-core.c | 39 +------ > drivers/ata/libata-eh.c | 237 +-------------------------------------- > drivers/ata/libata-scsi.c | 129 +--------------------- > drivers/ata/pata_ali.c | 4 - > drivers/ata/pata_amd.c | 4 - > drivers/ata/pata_atiixp.c | 4 - > drivers/ata/pata_cmd64x.c | 4 - > drivers/ata/pata_cs5520.c | 4 - > drivers/ata/pata_cs5530.c | 4 - > drivers/ata/pata_cs5535.c | 4 - > drivers/ata/pata_cypress.c | 4 - > drivers/ata/pata_efar.c | 4 - > drivers/ata/pata_hpt366.c | 4 - > drivers/ata/pata_hpt3x3.c | 4 - > drivers/ata/pata_it8213.c | 4 - > drivers/ata/pata_it821x.c | 4 - > drivers/ata/pata_ixp4xx_cf.c | 2 +- > drivers/ata/pata_jmicron.c | 4 - > drivers/ata/pata_marvell.c | 4 - > drivers/ata/pata_mpc52xx.c | 4 - > drivers/ata/pata_mpiix.c | 4 - > drivers/ata/pata_netcell.c | 4 - > drivers/ata/pata_ns87410.c | 4 - > drivers/ata/pata_oldpiix.c | 4 - > drivers/ata/pata_opti.c | 4 - > drivers/ata/pata_optidma.c | 4 - > drivers/ata/pata_pdc202xx_old.c | 4 - > drivers/ata/pata_radisys.c | 4 - > drivers/ata/pata_rz1000.c | 6 +- > drivers/ata/pata_sc1200.c | 4 - > drivers/ata/pata_scc.c | 4 - > drivers/ata/pata_serverworks.c | 4 - > drivers/ata/pata_sil680.c | 4 - > drivers/ata/pata_sis.c | 4 - > drivers/ata/pata_triflex.c | 4 - > drivers/ata/pata_via.c | 4 - > drivers/ata/sata_inic162x.c | 4 - > drivers/ata/sata_nv.c | 8 -- > drivers/ata/sata_sil.c | 4 - > drivers/ata/sata_sil24.c | 4 - > include/linux/libata.h | 14 +-- > 44 files changed, 14 insertions(+), 571 deletions(-) > >diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c >index 34c5534..d730291 100644 >--- a/drivers/ata/ahci.c >+++ b/drivers/ata/ahci.c >@@ -250,10 +250,6 @@ static struct scsi_host_template ahci_sh > .slave_configure = ata_scsi_slave_config, > .slave_destroy = ata_scsi_slave_destroy, > .bios_param = ata_std_bios_param, >-#ifdef CONFIG_PM >- .suspend = ata_scsi_device_suspend, >- .resume = ata_scsi_device_resume, >-#endif > }; > > static const struct ata_port_operations ahci_ops = { >diff --git a/drivers/ata/ata_generic.c b/drivers/ata/ata_generic.c >index 92a491d..0f19e32 100644 >--- a/drivers/ata/ata_generic.c >+++ b/drivers/ata/ata_generic.c >@@ -54,7 +54,7 @@ static int generic_set_mode(struct ata_p > > for (i = 0; i < ATA_MAX_DEVICES; i++) { > struct ata_device *dev = &ap->device[i]; >- if (ata_dev_ready(dev)) { >+ if (ata_dev_enabled(dev)) { > /* We don't really care */ > dev->pio_mode = XFER_PIO_0; > dev->dma_mode = XFER_MW_DMA_0; >@@ -90,10 +90,6 @@ static struct scsi_host_template generic > .slave_configure = ata_scsi_slave_config, > .slave_destroy = ata_scsi_slave_destroy, > .bios_param = ata_std_bios_param, >-#ifdef CONFIG_PM >- .resume = ata_scsi_device_resume, >- .suspend = ata_scsi_device_suspend, >-#endif > }; > > static struct ata_port_operations generic_port_ops = { >diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c >index 55d306a..8421742 100644 >--- a/drivers/ata/ata_piix.c >+++ b/drivers/ata/ata_piix.c >@@ -275,10 +275,6 @@ static struct scsi_host_template piix_sh > .slave_configure = ata_scsi_slave_config, > .slave_destroy = ata_scsi_slave_destroy, > .bios_param = ata_std_bios_param, >-#ifdef CONFIG_PM >- .resume = ata_scsi_device_resume, >- .suspend = ata_scsi_device_suspend, >-#endif > }; > > static const struct ata_port_operations piix_pata_ops = { >diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c >index ca67484..ce5e080 100644 >--- a/drivers/ata/libata-core.c >+++ b/drivers/ata/libata-core.c >@@ -2858,7 +2858,7 @@ int ata_do_set_mode(struct ata_port *ap, > dev = &ap->device[i]; > > /* don't update suspended devices' xfer mode */ >- if (!ata_dev_ready(dev)) >+ if (!ata_dev_enabled(dev)) > continue; > > rc = ata_dev_set_mode(dev); >@@ -5793,37 +5793,11 @@ static int ata_host_request_pm(struct at > */ > int ata_host_suspend(struct ata_host *host, pm_message_t mesg) > { >- int i, j, rc; >+ int rc; > > rc = ata_host_request_pm(host, mesg, 0, ATA_EHI_QUIET, 1); >- if (rc) >- goto fail; >- >- /* EH is quiescent now. Fail if we have any ready device. >- * This happens if hotplug occurs between completion of device >- * suspension and here. >- */ >- for (i = 0; i < host->n_ports; i++) { >- struct ata_port *ap = host->ports[i]; >- >- for (j = 0; j < ATA_MAX_DEVICES; j++) { >- struct ata_device *dev = &ap->device[j]; >- >- if (ata_dev_ready(dev)) { >- ata_port_printk(ap, KERN_WARNING, >- "suspend failed, device %d " >- "still active\n", dev->devno); >- rc = -EBUSY; >- goto fail; >- } >- } >- } >- >- host->dev->power.power_state = mesg; >- return 0; >- >- fail: >- ata_host_resume(host); >+ if (rc == 0) >+ host->dev->power.power_state = mesg; > return rc; > } > >@@ -6836,11 +6810,6 @@ EXPORT_SYMBOL_GPL(ata_pci_default_filter > EXPORT_SYMBOL_GPL(ata_pci_clear_simplex); > #endif /* CONFIG_PCI */ > >-#ifdef CONFIG_PM >-EXPORT_SYMBOL_GPL(ata_scsi_device_suspend); >-EXPORT_SYMBOL_GPL(ata_scsi_device_resume); >-#endif /* CONFIG_PM */ >- > EXPORT_SYMBOL_GPL(ata_eng_timeout); > EXPORT_SYMBOL_GPL(ata_port_schedule_eh); > EXPORT_SYMBOL_GPL(ata_port_abort); >diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c >index 2bff9ad..2aad5fe 100644 >--- a/drivers/ata/libata-eh.c >+++ b/drivers/ata/libata-eh.c >@@ -55,29 +55,12 @@ static void ata_eh_finish(struct ata_por > #ifdef CONFIG_PM > static void ata_eh_handle_port_suspend(struct ata_port *ap); > static void ata_eh_handle_port_resume(struct ata_port *ap); >-static int ata_eh_suspend(struct ata_port *ap, >- struct ata_device **r_failed_dev); >-static void ata_eh_prep_resume(struct ata_port *ap); >-static int ata_eh_resume(struct ata_port *ap, struct ata_device **r_failed_dev); > #else /* CONFIG_PM */ > static void ata_eh_handle_port_suspend(struct ata_port *ap) > { } > > static void ata_eh_handle_port_resume(struct ata_port *ap) > { } >- >-static int ata_eh_suspend(struct ata_port *ap, struct ata_device **r_failed_dev) >-{ >- return 0; >-} >- >-static void ata_eh_prep_resume(struct ata_port *ap) >-{ } >- >-static int ata_eh_resume(struct ata_port *ap, struct ata_device **r_failed_dev) >-{ >- return 0; >-} > #endif /* CONFIG_PM */ > > static void ata_ering_record(struct ata_ering *ering, int is_io, >@@ -1767,7 +1750,7 @@ static int ata_eh_revalidate_and_attach( > if (ehc->i.flags & ATA_EHI_DID_RESET) > readid_flags |= ATA_READID_POSTRESET; > >- if (action & ATA_EH_REVALIDATE && ata_dev_ready(dev)) { >+ if ((action & ATA_EH_REVALIDATE) && ata_dev_enabled(dev)) { > if (ata_port_offline(ap)) { > rc = -EIO; > goto err; >@@ -1848,166 +1831,6 @@ static int ata_eh_revalidate_and_attach( > return rc; > } > >-#ifdef CONFIG_PM >-/** >- * ata_eh_suspend - handle suspend EH action >- * @ap: target host port >- * @r_failed_dev: result parameter to indicate failing device >- * >- * Handle suspend EH action. Disk devices are spinned down and >- * other types of devices are just marked suspended. Once >- * suspended, no EH action to the device is allowed until it is >- * resumed. >- * >- * LOCKING: >- * Kernel thread context (may sleep). >- * >- * RETURNS: >- * 0 on success, -errno otherwise >- */ >-static int ata_eh_suspend(struct ata_port *ap, struct ata_device **r_failed_dev) >-{ >- struct ata_device *dev; >- int i, rc = 0; >- >- DPRINTK("ENTER\n"); >- >- for (i = 0; i < ATA_MAX_DEVICES; i++) { >- unsigned long flags; >- unsigned int action, err_mask; >- >- dev = &ap->device[i]; >- action = ata_eh_dev_action(dev); >- >- if (!ata_dev_enabled(dev) || !(action & ATA_EH_SUSPEND)) >- continue; >- >- WARN_ON(dev->flags & ATA_DFLAG_SUSPENDED); >- >- ata_eh_about_to_do(ap, dev, ATA_EH_SUSPEND); >- >- if (dev->class == ATA_DEV_ATA && !(action & ATA_EH_PM_FREEZE)) { >- /* flush cache */ >- rc = ata_flush_cache(dev); >- if (rc) >- break; >- >- /* spin down */ >- err_mask = ata_do_simple_cmd(dev, ATA_CMD_STANDBYNOW1); >- if (err_mask) { >- ata_dev_printk(dev, KERN_ERR, "failed to " >- "spin down (err_mask=0x%x)\n", >- err_mask); >- rc = -EIO; >- break; >- } >- } >- >- spin_lock_irqsave(ap->lock, flags); >- dev->flags |= ATA_DFLAG_SUSPENDED; >- spin_unlock_irqrestore(ap->lock, flags); >- >- ata_eh_done(ap, dev, ATA_EH_SUSPEND); >- } >- >- if (rc) >- *r_failed_dev = dev; >- >- DPRINTK("EXIT\n"); >- return rc; >-} >- >-/** >- * ata_eh_prep_resume - prep for resume EH action >- * @ap: target host port >- * >- * Clear SUSPENDED in preparation for scheduled resume actions. >- * This allows other parts of EH to access the devices being >- * resumed. >- * >- * LOCKING: >- * Kernel thread context (may sleep). >- */ >-static void ata_eh_prep_resume(struct ata_port *ap) >-{ >- struct ata_device *dev; >- unsigned long flags; >- int i; >- >- DPRINTK("ENTER\n"); >- >- for (i = 0; i < ATA_MAX_DEVICES; i++) { >- unsigned int action; >- >- dev = &ap->device[i]; >- action = ata_eh_dev_action(dev); >- >- if (!ata_dev_enabled(dev) || !(action & ATA_EH_RESUME)) >- continue; >- >- spin_lock_irqsave(ap->lock, flags); >- dev->flags &= ~ATA_DFLAG_SUSPENDED; >- spin_unlock_irqrestore(ap->lock, flags); >- } >- >- DPRINTK("EXIT\n"); >-} >- >-/** >- * ata_eh_resume - handle resume EH action >- * @ap: target host port >- * @r_failed_dev: result parameter to indicate failing device >- * >- * Handle resume EH action. Target devices are already reset and >- * revalidated. Spinning up is the only operation left. >- * >- * LOCKING: >- * Kernel thread context (may sleep). >- * >- * RETURNS: >- * 0 on success, -errno otherwise >- */ >-static int ata_eh_resume(struct ata_port *ap, struct ata_device **r_failed_dev) >-{ >- struct ata_device *dev; >- int i, rc = 0; >- >- DPRINTK("ENTER\n"); >- >- for (i = 0; i < ATA_MAX_DEVICES; i++) { >- unsigned int action, err_mask; >- >- dev = &ap->device[i]; >- action = ata_eh_dev_action(dev); >- >- if (!ata_dev_enabled(dev) || !(action & ATA_EH_RESUME)) >- continue; >- >- ata_eh_about_to_do(ap, dev, ATA_EH_RESUME); >- >- if (dev->class == ATA_DEV_ATA && !(action & ATA_EH_PM_FREEZE)) { >- err_mask = ata_do_simple_cmd(dev, >- ATA_CMD_IDLEIMMEDIATE); >- if (err_mask) { >- ata_dev_printk(dev, KERN_ERR, "failed to " >- "spin up (err_mask=0x%x)\n", >- err_mask); >- rc = -EIO; >- break; >- } >- } >- >- ata_eh_done(ap, dev, ATA_EH_RESUME); >- } >- >- if (rc) >- *r_failed_dev = dev; >- >- DPRINTK("EXIT\n"); >- return 0; >-} >-#endif /* CONFIG_PM */ >- > static int ata_port_nr_enabled(struct ata_port *ap) > { > int i, cnt = 0; >@@ -2033,17 +1856,6 @@ static int ata_eh_skip_recovery(struct a > struct ata_eh_context *ehc = &ap->eh_context; > int i; > >- /* skip if all possible devices are suspended */ >- for (i = 0; i < ata_port_max_devices(ap); i++) { >- struct ata_device *dev = &ap->device[i]; >- >- if (!(dev->flags & ATA_DFLAG_SUSPENDED)) >- break; >- } >- >- if (i == ata_port_max_devices(ap)) >- return 1; >- > /* thaw frozen port, resume link and recover failed devices */ > if ((ap->pflags & ATA_PFLAG_FROZEN) || > (ehc->i.flags & ATA_EHI_RESUME_LINK) || ata_port_nr_enabled(ap)) >@@ -2123,9 +1935,6 @@ static int ata_eh_recover(struct ata_por > if (ap->pflags & ATA_PFLAG_UNLOADING) > goto out; > >- /* prep for resume */ >- ata_eh_prep_resume(ap); >- > /* skip EH if possible. */ > if (ata_eh_skip_recovery(ap)) > ehc->i.action = 0; >@@ -2153,11 +1962,6 @@ static int ata_eh_recover(struct ata_por > if (rc) > goto dev_fail; > >- /* resume devices */ >- rc = ata_eh_resume(ap, &dev); >- if (rc) >- goto dev_fail; >- > /* configure transfer mode if necessary */ > if (ehc->i.flags & ATA_EHI_SETMODE) { > rc = ata_set_mode(ap, &dev); >@@ -2166,11 +1970,6 @@ static int ata_eh_recover(struct ata_por > ehc->i.flags &= ~ATA_EHI_SETMODE; > } > >- /* suspend devices */ >- rc = ata_eh_suspend(ap, &dev); >- if (rc) >- goto dev_fail; >- > goto out; > > dev_fail: >@@ -2366,22 +2165,13 @@ static void ata_eh_handle_port_suspend(s > * > * Resume @ap. > * >- * This function also waits upto one second until all devices >- * hanging off this port requests resume EH action. This is to >- * prevent invoking EH and thus reset multiple times on resume. >- * >- * On DPM resume, where some of devices might not be resumed >- * together, this may delay port resume upto one second, but such >- * DPM resumes are rare and 1 sec delay isn't too bad. >- * > * LOCKING: > * Kernel thread context (may sleep). > */ > static void ata_eh_handle_port_resume(struct ata_port *ap) > { >- unsigned long timeout; > unsigned long flags; >- int i, rc = 0; >+ int rc = 0; > > /* are we resuming? */ > spin_lock_irqsave(ap->lock, flags); >@@ -2392,31 +2182,12 @@ static void ata_eh_handle_port_resume(st > } > spin_unlock_irqrestore(ap->lock, flags); > >- /* spurious? */ >- if (!(ap->pflags & ATA_PFLAG_SUSPENDED)) >- goto done; >+ WARN_ON(!(ap->pflags & ATA_PFLAG_SUSPENDED)); > > if (ap->ops->port_resume) > rc = ap->ops->port_resume(ap); > >- /* give devices time to request EH */ >- timeout = jiffies + HZ; /* 1s max */ >- while (1) { >- for (i = 0; i < ATA_MAX_DEVICES; i++) { >- struct ata_device *dev = &ap->device[i]; >- unsigned int action = ata_eh_dev_action(dev); >- >- if ((dev->flags & ATA_DFLAG_SUSPENDED) && >- !(action & ATA_EH_RESUME)) >- break; >- } >- >- if (i == ATA_MAX_DEVICES || time_after(jiffies, timeout)) >- break; >- msleep(10); >- } >- >- done: >+ /* report result */ > spin_lock_irqsave(ap->lock, flags); > ap->pflags &= ~(ATA_PFLAG_PM_PENDING | ATA_PFLAG_SUSPENDED); > if (ap->pm_result) { >diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c >index 9afba2b..8f80019 100644 >--- a/drivers/ata/libata-scsi.c >+++ b/drivers/ata/libata-scsi.c >@@ -510,133 +510,6 @@ static void ata_dump_status(unsigned id, > } > } > >-#ifdef CONFIG_PM >-/** >- * ata_scsi_device_suspend - suspend ATA device associated with sdev >- * @sdev: the SCSI device to suspend >- * @mesg: target power management message >- * >- * Request suspend EH action on the ATA device associated with >- * @sdev and wait for the operation to complete. >- * >- * LOCKING: >- * Kernel thread context (may sleep). >- * >- * RETURNS: >- * 0 on success, -errno otherwise. >- */ >-int ata_scsi_device_suspend(struct scsi_device *sdev, pm_message_t mesg) >-{ >- struct ata_port *ap = ata_shost_to_port(sdev->host); >- struct ata_device *dev = ata_scsi_find_dev(ap, sdev); >- unsigned long flags; >- unsigned int action; >- int rc = 0; >- >- if (!dev) >- goto out; >- >- spin_lock_irqsave(ap->lock, flags); >- >- /* wait for the previous resume to complete */ >- while (dev->flags & ATA_DFLAG_SUSPENDED) { >- spin_unlock_irqrestore(ap->lock, flags); >- ata_port_wait_eh(ap); >- spin_lock_irqsave(ap->lock, flags); >- } >- >- /* if @sdev is already detached, nothing to do */ >- if (sdev->sdev_state == SDEV_OFFLINE || >- sdev->sdev_state == SDEV_CANCEL || sdev->sdev_state == SDEV_DEL) >- goto out_unlock; >- >- /* request suspend */ >- action = ATA_EH_SUSPEND; >- if (mesg.event != PM_EVENT_SUSPEND) >- action |= ATA_EH_PM_FREEZE; >- ap->eh_info.dev_action[dev->devno] |= action; >- ap->eh_info.flags |= ATA_EHI_QUIET; >- ata_port_schedule_eh(ap); >- >- spin_unlock_irqrestore(ap->lock, flags); >- >- /* wait for EH to do the job */ >- ata_port_wait_eh(ap); >- >- spin_lock_irqsave(ap->lock, flags); >- >- /* If @sdev is still attached but the associated ATA device >- * isn't suspended, the operation failed. >- */ >- if (sdev->sdev_state != SDEV_OFFLINE && >- sdev->sdev_state != SDEV_CANCEL && sdev->sdev_state != SDEV_DEL && >- !(dev->flags & ATA_DFLAG_SUSPENDED)) >- rc = -EIO; >- >- out_unlock: >- spin_unlock_irqrestore(ap->lock, flags); >- out: >- if (rc == 0) >- sdev->sdev_gendev.power.power_state = mesg; >- return rc; >-} >- >-/** >- * ata_scsi_device_resume - resume ATA device associated with sdev >- * @sdev: the SCSI device to resume >- * >- * Request resume EH action on the ATA device associated with >- * @sdev and return immediately. This enables parallel >- * wakeup/spinup of devices. >- * >- * LOCKING: >- * Kernel thread context (may sleep). >- * >- * RETURNS: >- * 0. >- */ >-int ata_scsi_device_resume(struct scsi_device *sdev) >-{ >- struct ata_port *ap = ata_shost_to_port(sdev->host); >- struct ata_device *dev = ata_scsi_find_dev(ap, sdev); >- struct ata_eh_info *ehi = &ap->eh_info; >- unsigned long flags; >- unsigned int action; >- >- if (!dev) >- goto out; >- >- spin_lock_irqsave(ap->lock, flags); >- >- /* if @sdev is already detached, nothing to do */ >- if (sdev->sdev_state == SDEV_OFFLINE || >- sdev->sdev_state == SDEV_CANCEL || sdev->sdev_state == SDEV_DEL) >- goto out_unlock; >- >- /* request resume */ >- action = ATA_EH_RESUME; >- if (sdev->sdev_gendev.power.power_state.event == PM_EVENT_SUSPEND) >- __ata_ehi_hotplugged(ehi); >- else >- action |= ATA_EH_PM_FREEZE | ATA_EH_SOFTRESET; >- ehi->dev_action[dev->devno] |= action; >- >- /* We don't want autopsy and verbose EH messages. Disable >- * those if we're the only device on this link. >- */ >- if (ata_port_max_devices(ap) == 1) >- ehi->flags |= ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET; >- >- ata_port_schedule_eh(ap); >- >- out_unlock: >- spin_unlock_irqrestore(ap->lock, flags); >- out: >- sdev->sdev_gendev.power.power_state = PMSG_ON; >- return 0; >-} >-#endif /* CONFIG_PM */ >- > /** > * ata_to_sense_error - convert ATA error to SCSI error > * @id: ATA device number >@@ -929,6 +802,8 @@ int ata_scsi_slave_config(struct scsi_de > > blk_queue_max_phys_segments(sdev->request_queue, LIBATA_MAX_PRD); > >+ sdev->manage_start_stop = 1; >+ > if (dev) > ata_scsi_dev_config(sdev, dev); > >diff --git a/drivers/ata/pata_ali.c b/drivers/ata/pata_ali.c >index d40edeb..48c7531 100644 >--- a/drivers/ata/pata_ali.c >+++ b/drivers/ata/pata_ali.c >@@ -291,10 +291,6 @@ static struct scsi_host_template ali_sht > .slave_configure = ata_scsi_slave_config, > .slave_destroy = ata_scsi_slave_destroy, > .bios_param = ata_std_bios_param, >-#ifdef CONFIG_PM >- .resume = ata_scsi_device_resume, >- .suspend = ata_scsi_device_suspend, >-#endif > }; > > /* >diff --git a/drivers/ata/pata_amd.c b/drivers/ata/pata_amd.c >index 536ee89..23903c8 100644 >--- a/drivers/ata/pata_amd.c >+++ b/drivers/ata/pata_amd.c >@@ -323,10 +323,6 @@ static struct scsi_host_template amd_sht > .slave_configure = ata_scsi_slave_config, > .slave_destroy = ata_scsi_slave_destroy, > .bios_param = ata_std_bios_param, >-#ifdef CONFIG_PM >- .resume = ata_scsi_device_resume, >- .suspend = ata_scsi_device_suspend, >-#endif > }; > > static struct ata_port_operations amd33_port_ops = { >diff --git a/drivers/ata/pata_atiixp.c b/drivers/ata/pata_atiixp.c >index 39c871a..b4048f0 100644 >--- a/drivers/ata/pata_atiixp.c >+++ b/drivers/ata/pata_atiixp.c >@@ -229,10 +229,6 @@ static struct scsi_host_template atiixp_ > .slave_configure = ata_scsi_slave_config, > .slave_destroy = ata_scsi_slave_destroy, > .bios_param = ata_std_bios_param, >-#ifdef CONFIG_PM >- .resume = ata_scsi_device_resume, >- .suspend = ata_scsi_device_suspend, >-#endif > }; > > static struct ata_port_operations atiixp_port_ops = { >diff --git a/drivers/ata/pata_cmd64x.c b/drivers/ata/pata_cmd64x.c >index 3989cc5..3e02c6a 100644 >--- a/drivers/ata/pata_cmd64x.c >+++ b/drivers/ata/pata_cmd64x.c >@@ -266,10 +266,6 @@ static struct scsi_host_template cmd64x_ > .slave_configure = ata_scsi_slave_config, > .slave_destroy = ata_scsi_slave_destroy, > .bios_param = ata_std_bios_param, >-#ifdef CONFIG_PM >- .resume = ata_scsi_device_resume, >- .suspend = ata_scsi_device_suspend, >-#endif > }; > > static struct ata_port_operations cmd64x_port_ops = { >diff --git a/drivers/ata/pata_cs5520.c b/drivers/ata/pata_cs5520.c >index 79bef0d..83bcc5b 100644 >--- a/drivers/ata/pata_cs5520.c >+++ b/drivers/ata/pata_cs5520.c >@@ -155,10 +155,6 @@ static struct scsi_host_template cs5520_ > .slave_configure = ata_scsi_slave_config, > .slave_destroy = ata_scsi_slave_destroy, > .bios_param = ata_std_bios_param, >-#ifdef CONFIG_PM >- .resume = ata_scsi_device_resume, >- .suspend = ata_scsi_device_suspend, >-#endif > }; > > static struct ata_port_operations cs5520_port_ops = { >diff --git a/drivers/ata/pata_cs5530.c b/drivers/ata/pata_cs5530.c >index 29642d5..637d8b3 100644 >--- a/drivers/ata/pata_cs5530.c >+++ b/drivers/ata/pata_cs5530.c >@@ -176,10 +176,6 @@ static struct scsi_host_template cs5530_ > .slave_configure = ata_scsi_slave_config, > .slave_destroy = ata_scsi_slave_destroy, > .bios_param = ata_std_bios_param, >-#ifdef CONFIG_PM >- .resume = ata_scsi_device_resume, >- .suspend = ata_scsi_device_suspend, >-#endif > }; > > static struct ata_port_operations cs5530_port_ops = { >diff --git a/drivers/ata/pata_cs5535.c b/drivers/ata/pata_cs5535.c >index 08cccc9..54586ac 100644 >--- a/drivers/ata/pata_cs5535.c >+++ b/drivers/ata/pata_cs5535.c >@@ -172,10 +172,6 @@ static struct scsi_host_template cs5535_ > .slave_configure = ata_scsi_slave_config, > .slave_destroy = ata_scsi_slave_destroy, > .bios_param = ata_std_bios_param, >-#ifdef CONFIG_PM >- .resume = ata_scsi_device_resume, >- .suspend = ata_scsi_device_suspend, >-#endif > }; > > static struct ata_port_operations cs5535_port_ops = { >diff --git a/drivers/ata/pata_cypress.c b/drivers/ata/pata_cypress.c >index 6ec049c..30e5c54 100644 >--- a/drivers/ata/pata_cypress.c >+++ b/drivers/ata/pata_cypress.c >@@ -125,10 +125,6 @@ static struct scsi_host_template cy82c69 > .slave_configure = ata_scsi_slave_config, > .slave_destroy = ata_scsi_slave_destroy, > .bios_param = ata_std_bios_param, >-#ifdef CONFIG_PM >- .resume = ata_scsi_device_resume, >- .suspend = ata_scsi_device_suspend, >-#endif > }; > > static struct ata_port_operations cy82c693_port_ops = { >diff --git a/drivers/ata/pata_efar.c b/drivers/ata/pata_efar.c >index a321685..38411f2 100644 >--- a/drivers/ata/pata_efar.c >+++ b/drivers/ata/pata_efar.c >@@ -246,10 +246,6 @@ static struct scsi_host_template efar_sh > .slave_configure = ata_scsi_slave_config, > .slave_destroy = ata_scsi_slave_destroy, > .bios_param = ata_std_bios_param, >-#ifdef CONFIG_PM >- .resume = ata_scsi_device_resume, >- .suspend = ata_scsi_device_suspend, >-#endif > }; > > static const struct ata_port_operations efar_ops = { >diff --git a/drivers/ata/pata_hpt366.c b/drivers/ata/pata_hpt366.c >index 93cfa6d..c412a9a 100644 >--- a/drivers/ata/pata_hpt366.c >+++ b/drivers/ata/pata_hpt366.c >@@ -331,10 +331,6 @@ static struct scsi_host_template hpt36x_ > .slave_configure = ata_scsi_slave_config, > .slave_destroy = ata_scsi_slave_destroy, > .bios_param = ata_std_bios_param, >-#ifdef CONFIG_PM >- .resume = ata_scsi_device_resume, >- .suspend = ata_scsi_device_suspend, >-#endif > }; > > /* >diff --git a/drivers/ata/pata_hpt3x3.c b/drivers/ata/pata_hpt3x3.c >index ac28ec8..84c636b 100644 >--- a/drivers/ata/pata_hpt3x3.c >+++ b/drivers/ata/pata_hpt3x3.c >@@ -100,10 +100,6 @@ static struct scsi_host_template hpt3x3_ > .slave_configure = ata_scsi_slave_config, > .slave_destroy = ata_scsi_slave_destroy, > .bios_param = ata_std_bios_param, >-#ifdef CONFIG_PM >- .resume = ata_scsi_device_resume, >- .suspend = ata_scsi_device_suspend, >-#endif > }; > > static struct ata_port_operations hpt3x3_port_ops = { >diff --git a/drivers/ata/pata_it8213.c b/drivers/ata/pata_it8213.c >index 011306e..e1bd263 100644 >--- a/drivers/ata/pata_it8213.c >+++ b/drivers/ata/pata_it8213.c >@@ -255,10 +255,6 @@ static struct scsi_host_template it8213_ > .dma_boundary = ATA_DMA_BOUNDARY, > .slave_configure = ata_scsi_slave_config, > .bios_param = ata_std_bios_param, >-#ifdef CONFIG_PM >- .resume = ata_scsi_device_resume, >- .suspend = ata_scsi_device_suspend, >-#endif > }; > > static const struct ata_port_operations it8213_ops = { >diff --git a/drivers/ata/pata_it821x.c b/drivers/ata/pata_it821x.c >index f1f8cec..8e565a5 100644 >--- a/drivers/ata/pata_it821x.c >+++ b/drivers/ata/pata_it821x.c >@@ -620,10 +620,6 @@ static struct scsi_host_template it821x_ > .slave_configure = ata_scsi_slave_config, > .slave_destroy = ata_scsi_slave_destroy, > .bios_param = ata_std_bios_param, >-#ifdef CONFIG_PM >- .resume = ata_scsi_device_resume, >- .suspend = ata_scsi_device_suspend, >-#endif > }; > > static struct ata_port_operations it821x_smart_port_ops = { >diff --git a/drivers/ata/pata_ixp4xx_cf.c b/drivers/ata/pata_ixp4xx_cf.c >index 420c343..b994351 100644 >--- a/drivers/ata/pata_ixp4xx_cf.c >+++ b/drivers/ata/pata_ixp4xx_cf.c >@@ -31,7 +31,7 @@ static int ixp4xx_set_mode(struct ata_po > > for (i = 0; i < ATA_MAX_DEVICES; i++) { > struct ata_device *dev = &ap->device[i]; >- if (ata_dev_ready(dev)) { >+ if (ata_dev_enabled(dev)) { > ata_dev_printk(dev, KERN_INFO, "configured for PIO0\n"); > dev->pio_mode = XFER_PIO_0; > dev->xfer_mode = XFER_PIO_0; >diff --git a/drivers/ata/pata_jmicron.c b/drivers/ata/pata_jmicron.c >index 43763c9..e3f6f5d 100644 >--- a/drivers/ata/pata_jmicron.c >+++ b/drivers/ata/pata_jmicron.c >@@ -137,10 +137,6 @@ static struct scsi_host_template jmicron > .slave_destroy = ata_scsi_slave_destroy, > /* Use standard CHS mapping rules */ > .bios_param = ata_std_bios_param, >-#ifdef CONFIG_PM >- .suspend = ata_scsi_device_suspend, >- .resume = ata_scsi_device_resume, >-#endif > }; > > static const struct ata_port_operations jmicron_ops = { >diff --git a/drivers/ata/pata_marvell.c b/drivers/ata/pata_marvell.c >index d9b94a1..4c282ab 100644 >--- a/drivers/ata/pata_marvell.c >+++ b/drivers/ata/pata_marvell.c >@@ -104,10 +104,6 @@ static struct scsi_host_template marvell > .slave_destroy = ata_scsi_slave_destroy, > /* Use standard CHS mapping rules */ > .bios_param = ata_std_bios_param, >-#ifdef CONFIG_PM >- .resume = ata_scsi_device_resume, >- .suspend = ata_scsi_device_suspend, >-#endif > }; > > static const struct ata_port_operations marvell_ops = { >diff --git a/drivers/ata/pata_mpc52xx.c b/drivers/ata/pata_mpc52xx.c >index 9587a89..368fac7 100644 >--- a/drivers/ata/pata_mpc52xx.c >+++ b/drivers/ata/pata_mpc52xx.c >@@ -280,10 +280,6 @@ static struct scsi_host_template mpc52xx > .dma_boundary = ATA_DMA_BOUNDARY, > .slave_configure = ata_scsi_slave_config, > .bios_param = ata_std_bios_param, >-#ifdef CONFIG_PM >- .suspend = ata_scsi_device_suspend, >- .resume = ata_scsi_device_resume, >-#endif > }; > > static struct ata_port_operations mpc52xx_ata_port_ops = { >diff --git a/drivers/ata/pata_mpiix.c b/drivers/ata/pata_mpiix.c >index 987c5fa..2858927 100644 >--- a/drivers/ata/pata_mpiix.c >+++ b/drivers/ata/pata_mpiix.c >@@ -164,10 +164,6 @@ static struct scsi_host_template mpiix_s > .slave_configure = ata_scsi_slave_config, > .slave_destroy = ata_scsi_slave_destroy, > .bios_param = ata_std_bios_param, >-#ifdef CONFIG_PM >- .resume = ata_scsi_device_resume, >- .suspend = ata_scsi_device_suspend, >-#endif > }; > > static struct ata_port_operations mpiix_port_ops = { >diff --git a/drivers/ata/pata_netcell.c b/drivers/ata/pata_netcell.c >index dbba5b7..f15eb34 100644 >--- a/drivers/ata/pata_netcell.c >+++ b/drivers/ata/pata_netcell.c >@@ -37,10 +37,6 @@ static struct scsi_host_template netcell > .slave_destroy = ata_scsi_slave_destroy, > /* Use standard CHS mapping rules */ > .bios_param = ata_std_bios_param, >-#ifdef CONFIG_PM >- .resume = ata_scsi_device_resume, >- .suspend = ata_scsi_device_suspend, >-#endif > }; > > static const struct ata_port_operations netcell_ops = { >diff --git a/drivers/ata/pata_ns87410.c b/drivers/ata/pata_ns87410.c >index 078aeda..2147172 100644 >--- a/drivers/ata/pata_ns87410.c >+++ b/drivers/ata/pata_ns87410.c >@@ -156,10 +156,6 @@ static struct scsi_host_template ns87410 > .slave_configure = ata_scsi_slave_config, > .slave_destroy = ata_scsi_slave_destroy, > .bios_param = ata_std_bios_param, >-#ifdef CONFIG_PM >- .resume = ata_scsi_device_resume, >- .suspend = ata_scsi_device_suspend, >-#endif > }; > > static struct ata_port_operations ns87410_port_ops = { >diff --git a/drivers/ata/pata_oldpiix.c b/drivers/ata/pata_oldpiix.c >index dea4690..9cc1d1e 100644 >--- a/drivers/ata/pata_oldpiix.c >+++ b/drivers/ata/pata_oldpiix.c >@@ -232,10 +232,6 @@ static struct scsi_host_template oldpiix > .slave_configure = ata_scsi_slave_config, > .slave_destroy = ata_scsi_slave_destroy, > .bios_param = ata_std_bios_param, >-#ifdef CONFIG_PM >- .resume = ata_scsi_device_resume, >- .suspend = ata_scsi_device_suspend, >-#endif > }; > > static const struct ata_port_operations oldpiix_pata_ops = { >diff --git a/drivers/ata/pata_opti.c b/drivers/ata/pata_opti.c >index 13b63e2..af00c26 100644 >--- a/drivers/ata/pata_opti.c >+++ b/drivers/ata/pata_opti.c >@@ -177,10 +177,6 @@ static struct scsi_host_template opti_sh > .slave_configure = ata_scsi_slave_config, > .slave_destroy = ata_scsi_slave_destroy, > .bios_param = ata_std_bios_param, >-#ifdef CONFIG_PM >- .resume = ata_scsi_device_resume, >- .suspend = ata_scsi_device_suspend, >-#endif > }; > > static struct ata_port_operations opti_port_ops = { >diff --git a/drivers/ata/pata_optidma.c b/drivers/ata/pata_optidma.c >index b70e04c..d1569a7 100644 >--- a/drivers/ata/pata_optidma.c >+++ b/drivers/ata/pata_optidma.c >@@ -362,10 +362,6 @@ static struct scsi_host_template optidma > .slave_configure = ata_scsi_slave_config, > .slave_destroy = ata_scsi_slave_destroy, > .bios_param = ata_std_bios_param, >-#ifdef CONFIG_PM >- .resume = ata_scsi_device_resume, >- .suspend = ata_scsi_device_suspend, >-#endif > }; > > static struct ata_port_operations optidma_port_ops = { >diff --git a/drivers/ata/pata_pdc202xx_old.c b/drivers/ata/pata_pdc202xx_old.c >index ee636be..3e204c3 100644 >--- a/drivers/ata/pata_pdc202xx_old.c >+++ b/drivers/ata/pata_pdc202xx_old.c >@@ -244,10 +244,6 @@ static struct scsi_host_template pdc202x > .slave_configure = ata_scsi_slave_config, > .slave_destroy = ata_scsi_slave_destroy, > .bios_param = ata_std_bios_param, >-#ifdef CONFIG_PM >- .resume = ata_scsi_device_resume, >- .suspend = ata_scsi_device_suspend, >-#endif > }; > > static struct ata_port_operations pdc2024x_port_ops = { >diff --git a/drivers/ata/pata_radisys.c b/drivers/ata/pata_radisys.c >index 1c54673..bc01b17 100644 >--- a/drivers/ata/pata_radisys.c >+++ b/drivers/ata/pata_radisys.c >@@ -200,10 +200,6 @@ static struct scsi_host_template radisys > .slave_configure = ata_scsi_slave_config, > .slave_destroy = ata_scsi_slave_destroy, > .bios_param = ata_std_bios_param, >-#ifdef CONFIG_PM >- .resume = ata_scsi_device_resume, >- .suspend = ata_scsi_device_suspend, >-#endif > }; > > static const struct ata_port_operations radisys_pata_ops = { >diff --git a/drivers/ata/pata_rz1000.c b/drivers/ata/pata_rz1000.c >index 85c4529..97785b4 100644 >--- a/drivers/ata/pata_rz1000.c >+++ b/drivers/ata/pata_rz1000.c >@@ -40,7 +40,7 @@ static int rz1000_set_mode(struct ata_po > > for (i = 0; i < ATA_MAX_DEVICES; i++) { > struct ata_device *dev = &ap->device[i]; >- if (ata_dev_ready(dev)) { >+ if (ata_dev_enabled(dev)) { > /* We don't really care */ > dev->pio_mode = XFER_PIO_0; > dev->xfer_mode = XFER_PIO_0; >@@ -69,10 +69,6 @@ static struct scsi_host_template rz1000_ > .slave_configure = ata_scsi_slave_config, > .slave_destroy = ata_scsi_slave_destroy, > .bios_param = ata_std_bios_param, >-#ifdef CONFIG_PM >- .resume = ata_scsi_device_resume, >- .suspend = ata_scsi_device_suspend, >-#endif > }; > > static struct ata_port_operations rz1000_port_ops = { >diff --git a/drivers/ata/pata_sc1200.c b/drivers/ata/pata_sc1200.c >index 66e8ff4..2af9f8c 100644 >--- a/drivers/ata/pata_sc1200.c >+++ b/drivers/ata/pata_sc1200.c >@@ -194,10 +194,6 @@ static struct scsi_host_template sc1200_ > .slave_configure = ata_scsi_slave_config, > .slave_destroy = ata_scsi_slave_destroy, > .bios_param = ata_std_bios_param, >-#ifdef CONFIG_PM >- .resume = ata_scsi_device_resume, >- .suspend = ata_scsi_device_suspend, >-#endif > }; > > static struct ata_port_operations sc1200_port_ops = { >diff --git a/drivers/ata/pata_scc.c b/drivers/ata/pata_scc.c >index 5df354d..243130e 100644 >--- a/drivers/ata/pata_scc.c >+++ b/drivers/ata/pata_scc.c >@@ -984,10 +984,6 @@ static struct scsi_host_template scc_sht > .slave_configure = ata_scsi_slave_config, > .slave_destroy = ata_scsi_slave_destroy, > .bios_param = ata_std_bios_param, >-#ifdef CONFIG_PM >- .resume = ata_scsi_device_resume, >- .suspend = ata_scsi_device_suspend, >-#endif > }; > > static const struct ata_port_operations scc_pata_ops = { >diff --git a/drivers/ata/pata_serverworks.c b/drivers/ata/pata_serverworks.c >index 3956ef2..fdd9a63 100644 >--- a/drivers/ata/pata_serverworks.c >+++ b/drivers/ata/pata_serverworks.c >@@ -313,10 +313,6 @@ static struct scsi_host_template serverw > .slave_configure = ata_scsi_slave_config, > .slave_destroy = ata_scsi_slave_destroy, > .bios_param = ata_std_bios_param, >-#ifdef CONFIG_PM >- .resume = ata_scsi_device_resume, >- .suspend = ata_scsi_device_suspend, >-#endif > }; > > static struct ata_port_operations serverworks_osb4_port_ops = { >diff --git a/drivers/ata/pata_sil680.c b/drivers/ata/pata_sil680.c >index 6770820..8978186 100644 >--- a/drivers/ata/pata_sil680.c >+++ b/drivers/ata/pata_sil680.c >@@ -230,10 +230,6 @@ static struct scsi_host_template sil680_ > .slave_configure = ata_scsi_slave_config, > .slave_destroy = ata_scsi_slave_destroy, > .bios_param = ata_std_bios_param, >-#ifdef CONFIG_PM >- .suspend = ata_scsi_device_suspend, >- .resume = ata_scsi_device_resume, >-#endif > }; > > static struct ata_port_operations sil680_port_ops = { >diff --git a/drivers/ata/pata_sis.c b/drivers/ata/pata_sis.c >index a3fbcee..1d7dc0c 100644 >--- a/drivers/ata/pata_sis.c >+++ b/drivers/ata/pata_sis.c >@@ -520,10 +520,6 @@ static struct scsi_host_template sis_sht > .slave_configure = ata_scsi_slave_config, > .slave_destroy = ata_scsi_slave_destroy, > .bios_param = ata_std_bios_param, >-#ifdef CONFIG_PM >- .resume = ata_scsi_device_resume, >- .suspend = ata_scsi_device_suspend, >-#endif > }; > > static const struct ata_port_operations sis_133_ops = { >diff --git a/drivers/ata/pata_triflex.c b/drivers/ata/pata_triflex.c >index e618ffd..33a1663 100644 >--- a/drivers/ata/pata_triflex.c >+++ b/drivers/ata/pata_triflex.c >@@ -192,10 +192,6 @@ static struct scsi_host_template triflex > .slave_configure = ata_scsi_slave_config, > .slave_destroy = ata_scsi_slave_destroy, > .bios_param = ata_std_bios_param, >-#ifdef CONFIG_PM >- .resume = ata_scsi_device_resume, >- .suspend = ata_scsi_device_suspend, >-#endif > }; > > static struct ata_port_operations triflex_port_ops = { >diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c >index 96b7179..969b98f 100644 >--- a/drivers/ata/pata_via.c >+++ b/drivers/ata/pata_via.c >@@ -300,10 +300,6 @@ static struct scsi_host_template via_sht > .slave_configure = ata_scsi_slave_config, > .slave_destroy = ata_scsi_slave_destroy, > .bios_param = ata_std_bios_param, >-#ifdef CONFIG_PM >- .resume = ata_scsi_device_resume, >- .suspend = ata_scsi_device_suspend, >-#endif > }; > > static struct ata_port_operations via_port_ops = { >diff --git a/drivers/ata/sata_inic162x.c b/drivers/ata/sata_inic162x.c >index f099a1d..4c12d92 100644 >--- a/drivers/ata/sata_inic162x.c >+++ b/drivers/ata/sata_inic162x.c >@@ -135,10 +135,6 @@ static struct scsi_host_template inic_sh > .slave_configure = inic_slave_config, > .slave_destroy = ata_scsi_slave_destroy, > .bios_param = ata_std_bios_param, >-#ifdef CONFIG_PM >- .suspend = ata_scsi_device_suspend, >- .resume = ata_scsi_device_resume, >-#endif > }; > > static const int scr_map[] = { >diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c >index 0216974..087f84b 100644 >--- a/drivers/ata/sata_nv.c >+++ b/drivers/ata/sata_nv.c >@@ -323,10 +323,6 @@ static struct scsi_host_template nv_sht > .slave_configure = ata_scsi_slave_config, > .slave_destroy = ata_scsi_slave_destroy, > .bios_param = ata_std_bios_param, >-#ifdef CONFIG_PM >- .suspend = ata_scsi_device_suspend, >- .resume = ata_scsi_device_resume, >-#endif > }; > > static struct scsi_host_template nv_adma_sht = { >@@ -345,10 +341,6 @@ static struct scsi_host_template nv_adma > .slave_configure = nv_adma_slave_config, > .slave_destroy = ata_scsi_slave_destroy, > .bios_param = ata_std_bios_param, >-#ifdef CONFIG_PM >- .suspend = ata_scsi_device_suspend, >- .resume = ata_scsi_device_resume, >-#endif > }; > > static const struct ata_port_operations nv_generic_ops = { >diff --git a/drivers/ata/sata_sil.c b/drivers/ata/sata_sil.c >index 0a1e417..e8483aa 100644 >--- a/drivers/ata/sata_sil.c >+++ b/drivers/ata/sata_sil.c >@@ -182,10 +182,6 @@ static struct scsi_host_template sil_sht > .slave_configure = ata_scsi_slave_config, > .slave_destroy = ata_scsi_slave_destroy, > .bios_param = ata_std_bios_param, >-#ifdef CONFIG_PM >- .suspend = ata_scsi_device_suspend, >- .resume = ata_scsi_device_resume, >-#endif > }; > > static const struct ata_port_operations sil_ops = { >diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c >index e6223ba..b1945e6 100644 >--- a/drivers/ata/sata_sil24.c >+++ b/drivers/ata/sata_sil24.c >@@ -380,10 +380,6 @@ static struct scsi_host_template sil24_s > .slave_configure = ata_scsi_slave_config, > .slave_destroy = ata_scsi_slave_destroy, > .bios_param = ata_std_bios_param, >-#ifdef CONFIG_PM >- .suspend = ata_scsi_device_suspend, >- .resume = ata_scsi_device_resume, >-#endif > }; > > static const struct ata_port_operations sil24_ops = { >diff --git a/include/linux/libata.h b/include/linux/libata.h >index d8cfc72..c6745e6 100644 >--- a/include/linux/libata.h >+++ b/include/linux/libata.h >@@ -140,7 +140,6 @@ enum { > > ATA_DFLAG_PIO = (1 << 8), /* device limited to PIO mode */ > ATA_DFLAG_NCQ_OFF = (1 << 9), /* device limited to non-NCQ mode */ >- ATA_DFLAG_SUSPENDED = (1 << 10), /* device suspended */ > ATA_DFLAG_INIT_MASK = (1 << 16) - 1, > > ATA_DFLAG_DETACH = (1 << 16), >@@ -268,13 +267,9 @@ enum { > ATA_EH_REVALIDATE = (1 << 0), > ATA_EH_SOFTRESET = (1 << 1), > ATA_EH_HARDRESET = (1 << 2), >- ATA_EH_SUSPEND = (1 << 3), >- ATA_EH_RESUME = (1 << 4), >- ATA_EH_PM_FREEZE = (1 << 5), > > ATA_EH_RESET_MASK = ATA_EH_SOFTRESET | ATA_EH_HARDRESET, >- ATA_EH_PERDEV_MASK = ATA_EH_REVALIDATE | ATA_EH_SUSPEND | >- ATA_EH_RESUME | ATA_EH_PM_FREEZE, >+ ATA_EH_PERDEV_MASK = ATA_EH_REVALIDATE, > > /* ata_eh_info->flags */ > ATA_EHI_HOTPLUGGED = (1 << 0), /* could have been hotplugged */ >@@ -742,8 +737,6 @@ extern int sata_scr_write_flush(struct a > extern int ata_port_online(struct ata_port *ap); > extern int ata_port_offline(struct ata_port *ap); > #ifdef CONFIG_PM >-extern int ata_scsi_device_resume(struct scsi_device *); >-extern int ata_scsi_device_suspend(struct scsi_device *, pm_message_t mesg); > extern int ata_host_suspend(struct ata_host *host, pm_message_t mesg); > extern void ata_host_resume(struct ata_host *host); > #endif >@@ -1018,11 +1011,6 @@ static inline unsigned int ata_dev_absen > return ata_class_absent(dev->class); > } > >-static inline unsigned int ata_dev_ready(const struct ata_device *dev) >-{ >- return ata_dev_enabled(dev) && !(dev->flags & ATA_DFLAG_SUSPENDED); >-} >- > /* > * port helpers > */ >Now that libata uses sd->manage_start_stop, libata spins down disk on >shutdown. In an attempt to compensate libata's previous shortcoming, >some distros sync and spin down disks attached via libata in their >shutdown(8). Some disks spin back up just to spin down again on >STANDBYNOW1 if the command is issued when the disk is spun down, so >this double spinning down causes problem. > >This patch implements module parameter libata.spindown_compat which, >when set to one (default value), prevents libata from spinning down >disks on shutdown thus avoiding double spinning down. Note that >libata spins down disks for suspend to mem and disk, so with >libata.spindown_compat set to one, disks should be properly spun down >in all cases without modifying shutdown(8). > >shutdown(8) should be fixed eventually. Some drive do spin up on >SYNCHRONZE_CACHE even when their cache is clean. Those disks >currently spin up briefly when sd tries to shutdown the device and >then the machine powers off immediately, which can't be good for the >head. We can't skip SYNCHRONIZE_CACHE during shudown as it can be >dangerous data integrity-wise. > >So, this spindown_compat parameter is already scheduled for removal by >the end of the next year and here's what shutdown(8) should do. > > * Check whether /sys/modules/libata/parameters/spindown_compat > exists. If it does, write 0 to it. > > * For each libata harddisk { > * Check whether /sys/class/scsi_disk/h:c:i:l/manage_start_stop > exists. Iff it doesn't, synchronize cache and spin the disk > down as before. > } > >The above procedure will make shutdown(8) work properly with kernels >before this change, ones with this workaround and later ones without >it. > >To accelerate shutdown(8) updates, if the compat mode is in use, this >patch prints BIG FAT warning for five seconds during shutdown (the >optimal interval to annoy the user just the right amount discovered by >hours of tireless usability testing). > >Signed-off-by: Tejun Heo <htejun@gmail.com> >--- > Documentation/feature-removal-schedule.txt | 19 +++++++++++++++++++ > drivers/ata/libata-core.c | 6 ++++++ > drivers/ata/libata-scsi.c | 28 +++++++++++++++++++++++++++- > drivers/ata/libata.h | 1 + > 4 files changed, 53 insertions(+), 1 deletions(-) > >diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt >index 5c88ba1..78b3aa6 100644 >--- a/Documentation/feature-removal-schedule.txt >+++ b/Documentation/feature-removal-schedule.txt >@@ -314,3 +314,22 @@ Why: Code was merged, then submitter imm > Who: David S. Miller <davem@davemloft.net> > > --------------------------- >+ >+What: libata.spindown_compat module parameter >+When: Dec 2008 >+Why: halt(8) synchronizes caches for and spins down libata disks >+ because libata didn't use to spin down disk on system halt >+ (only synchronized caches). >+ Spin down on system halt is now implemented and can be tested >+ using sysfs node /sys/class/scsi_disk/h:c:i:l/manage_start_stop. >+ Because issuing spin down command to an already spun down disk >+ makes some disks spin up just to spin down again, the old >+ behavior needs to be maintained till userspace tool is updated >+ to check the sysfs node and not to spin down disks with the >+ node set to one. >+ This module parameter is to give userspace tool the time to >+ get updated and should be removed after userspace is >+ reasonably updated. >+Who: Tejun Heo <htejun@gmail.com> >+ >+--------------------------- >diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c >index ce5e080..4a81549 100644 >--- a/drivers/ata/libata-core.c >+++ b/drivers/ata/libata-core.c >@@ -101,6 +101,12 @@ int libata_noacpi = 1; > module_param_named(noacpi, libata_noacpi, int, 0444); > MODULE_PARM_DESC(noacpi, "Disables the use of ACPI in suspend/resume when set"); > >+int ata_spindown_compat = 1; >+module_param_named(spindown_compat, ata_spindown_compat, int, 0644); >+MODULE_PARM_DESC(spindown_compat, "Enable backward compatible spindown " >+ "behavior. Will be removed. More info can be found in " >+ "Documentation/feature-removal-schedule.txt\n"); >+ > MODULE_AUTHOR("Jeff Garzik"); > MODULE_DESCRIPTION("Library module for ATA devices"); > MODULE_LICENSE("GPL"); >diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c >index 8f80019..dd81fa7 100644 >--- a/drivers/ata/libata-scsi.c >+++ b/drivers/ata/libata-scsi.c >@@ -944,9 +944,35 @@ static unsigned int ata_scsi_start_stop_ > } > > tf->command = ATA_CMD_VERIFY; /* READ VERIFY */ >- } else >+ } else { >+ /* XXX: This is for backward compatibility, will be >+ * removed. Read Documentation/feature-removal-schedule.txt >+ * for more info. >+ */ >+ if (ata_spindown_compat && >+ (system_state == SYSTEM_HALT || >+ system_state == SYSTEM_POWER_OFF)) { >+ static int warned = 0; >+ >+ if (!warned) { >+ spin_unlock_irq(qc->ap->lock); >+ ata_dev_printk(qc->dev, KERN_WARNING, >+ "DISK MIGHT NOT BE SPUN DOWN PROPERLY. " >+ "UPDATE SHUTDOWN UTILITY\n"); >+ ata_dev_printk(qc->dev, KERN_WARNING, >+ "For more info, visit " >+ "http://linux-ata.org/shutdown.html\n"); >+ warned = 1; >+ ssleep(5); >+ spin_lock_irq(qc->ap->lock); >+ } >+ scmd->result = SAM_STAT_GOOD; >+ return 1; >+ } >+ > /* Issue ATA STANDBY IMMEDIATE command */ > tf->command = ATA_CMD_STANDBYNOW1; >+ } > > /* > * Standby and Idle condition timers could be implemented but that >diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h >index 5f4d40c..316bf8a 100644 >--- a/drivers/ata/libata.h >+++ b/drivers/ata/libata.h >@@ -58,6 +58,7 @@ extern int atapi_enabled; > extern int atapi_dmadir; > extern int libata_fua; > extern int libata_noacpi; >+extern int ata_spindown_compat; > extern struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev); > extern int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev, > u64 block, u32 n_block, unsigned int tf_flags,
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 174373
: 118829