SCSI for-linus on 20130713

This is the remaining set of SCSI patches for the merge window.  it's mostly
 driver updates (scsi_debug, qla2xxx, storvsc, mp3sas).  There are also several
 bug fixes in fcoe, libfc, and megaraid_sas.  We also have a couple of core
 changes to try to make device destruction more deterministic.
 
 Signed-off-by: James Bottomley <JBottomley@Parallels.com>
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2.0.19 (GNU/Linux)
 
 iQEcBAABAgAGBQJR4NdLAAoJEDeqqVYsXL0MgLcIAIMpnHPPO0xTB1brAhIA2r4H
 MHcD3/iRu+b+YuzEOuErw+pNzsAUGG9MD1b4m74qZ4z9PaVl4U0lWt61++P/OW91
 ZD9TAF70t+3/R6Wz2eZp8WqmgWkLcEu9wDQxJKGPCcyWB9MphbsxaakM60B1swCy
 5H3VGBWOy8MieLCHzdYgXfB83fnSy/75h/jErDiNwoEUuRci0rb9yOtpNamXPOiB
 2JpW8hegixdup6srt+4Uq3gSWKJhqV1MD3leu6i3cHmoqTGueCX46patqlciSLRo
 lN8fB3RgZjtIj8zattaeaGchEUMAE7yKcbjC+LyGPQe3+DKVutGNrEFT68KKRcQ=
 =7slg
 -----END PGP SIGNATURE-----

Merge tag 'scsi-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi

Pull final round of SCSI updates from James Bottomley:
 "This is the remaining set of SCSI patches for the merge window.  It's
  mostly driver updates (scsi_debug, qla2xxx, storvsc, mp3sas).  There
  are also several bug fixes in fcoe, libfc, and megaraid_sas.  We also
  have a couple of core changes to try to make device destruction more
  deterministic"

* tag 'scsi-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: (46 commits)
  [SCSI] scsi constants: command, sense key + additional sense strings
  fcoe: Reduce number of sparse warnings
  fcoe: Stop fc_rport_priv structure leak
  libfcoe: Fix meaningless log statement
  libfc: Differentiate echange timer cancellation debug statements
  libfc: Remove extra space in fc_exch_timer_cancel definition
  fcoe: fix the link error status block sparse warnings
  fcoe: Fix smatch warning in fcoe_fdmi_info function
  libfc: Reject PLOGI from nodes with incompatible role
  [SCSI] enable destruction of blocked devices which fail LUN scanning
  [SCSI] Fix race between starved list and device removal
  [SCSI] megaraid_sas: fix a bug for 64 bit arches
  [SCSI] scsi_debug: reduce duplication between prot_verify_read and prot_verify_write
  [SCSI] scsi_debug: simplify offset calculation for dif_storep
  [SCSI] scsi_debug: invalidate protection info for unmapped region
  [SCSI] scsi_debug: fix NULL pointer dereference with parameters dif=0 dix=1
  [SCSI] scsi_debug: fix incorrectly nested kmap_atomic()
  [SCSI] scsi_debug: fix invalid address passed to kunmap_atomic()
  [SCSI] mpt3sas: Bump driver version to v02.100.00.00
  [SCSI] mpt3sas: when async scanning is enabled then while scanning, devices are removed but their transport layer entries are not removed
  ...
This commit is contained in:
Linus Torvalds 2013-07-13 17:41:21 -07:00
commit 03ce3ca4b0
46 changed files with 827 additions and 528 deletions

View File

@ -1,10 +1,10 @@
/*
/*
* ASCII values for a number of symbolic constants, printing functions,
* etc.
* Additions for SCSI 2 and Linux 2.2.x by D. Gilbert (990422)
* Additions for SCSI 3+ (SPC-3 T10/1416-D Rev 07 3 May 2002)
* by D. Gilbert and aeb (20020609)
* Update to SPC-4 T10/1713-D Rev 20, 22 May 2009, D. Gilbert 20090624
* Updated to SPC-4 T10/1713-D Rev 36g, D. Gilbert 20130701
*/
#include <linux/blkdev.h>
@ -21,12 +21,13 @@
/* Commands with service actions that change the command name */
#define MAINTENANCE_IN 0xa3
#define MAINTENANCE_OUT 0xa4
#define SERVICE_ACTION_IN_12 0xab
#define SERVICE_ACTION_OUT_12 0xa9
#define SERVICE_ACTION_BIDIRECTIONAL 0x9d
#define SERVICE_ACTION_IN_16 0x9e
#define SERVICE_ACTION_OUT_16 0x9f
#define THIRD_PARTY_COPY_OUT 0x83
#define THIRD_PARTY_COPY_IN 0x84
@ -36,11 +37,11 @@ static const char * cdb_byte0_names[] = {
/* 04-07 */ "Format Unit/Medium", "Read Block Limits", NULL,
"Reassign Blocks",
/* 08-0d */ "Read(6)", NULL, "Write(6)", "Seek(6)", NULL, NULL,
/* 0e-12 */ NULL, "Read Reverse", "Write Filemarks", "Space", "Inquiry",
/* 0e-12 */ NULL, "Read Reverse", "Write Filemarks", "Space", "Inquiry",
/* 13-16 */ "Verify(6)", "Recover Buffered Data", "Mode Select(6)",
"Reserve(6)",
/* 17-1a */ "Release(6)", "Copy", "Erase", "Mode Sense(6)",
/* 1b-1d */ "Start/Stop Unit", "Receive Diagnostic", "Send Diagnostic",
/* 1b-1d */ "Start/Stop Unit", "Receive Diagnostic", "Send Diagnostic",
/* 1e-1f */ "Prevent/Allow Medium Removal", NULL,
/* 20-22 */ NULL, NULL, NULL,
/* 23-28 */ "Read Format Capacities", "Set Window",
@ -48,16 +49,16 @@ static const char * cdb_byte0_names[] = {
/* 29-2d */ "Read Generation", "Write(10)", "Seek(10)", "Erase(10)",
"Read updated block",
/* 2e-31 */ "Write Verify(10)", "Verify(10)", "Search High", "Search Equal",
/* 32-34 */ "Search Low", "Set Limits", "Prefetch/Read Position",
/* 32-34 */ "Search Low", "Set Limits", "Prefetch/Read Position",
/* 35-37 */ "Synchronize Cache(10)", "Lock/Unlock Cache(10)",
"Read Defect Data(10)",
/* 38-3c */ "Medium Scan", "Compare", "Copy Verify", "Write Buffer",
"Read Buffer",
"Read Defect Data(10)",
/* 38-3c */ "Medium Scan", "Compare", "Copy Verify", "Write Buffer",
"Read Buffer",
/* 3d-3f */ "Update Block", "Read Long(10)", "Write Long(10)",
/* 40-41 */ "Change Definition", "Write Same(10)",
/* 42-48 */ "Unmap/Read sub-channel", "Read TOC/PMA/ATIP",
"Read density support", "Play audio(10)", "Get configuration",
"Play audio msf", "Play audio track/index",
"Play audio msf", "Sanitize/Play audio track/index",
/* 49-4f */ "Play track relative(10)", "Get event status notification",
"Pause/resume", "Log Select", "Log Sense", "Stop play/scan",
NULL,
@ -72,17 +73,17 @@ static const char * cdb_byte0_names[] = {
/* 70-77 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/* 78-7f */ NULL, NULL, NULL, NULL, NULL, NULL, "Extended CDB",
"Variable length",
/* 80-84 */ "Xdwrite(16)", "Rebuild(16)", "Regenerate(16)", "Extended copy",
"Receive copy results",
/* 80-84 */ "Xdwrite(16)", "Rebuild(16)", "Regenerate(16)",
"Third party copy out", "Third party copy in",
/* 85-89 */ "ATA command pass through(16)", "Access control in",
"Access control out", "Read(16)", "Memory Export Out(16)",
"Access control out", "Read(16)", "Compare and Write",
/* 8a-8f */ "Write(16)", "ORWrite", "Read attributes", "Write attributes",
"Write and verify(16)", "Verify(16)",
/* 90-94 */ "Pre-fetch(16)", "Synchronize cache(16)",
"Lock/unlock cache(16)", "Write same(16)", NULL,
/* 95-99 */ NULL, NULL, NULL, NULL, NULL,
/* 9a-9f */ NULL, NULL, NULL, NULL, "Service action in(16)",
"Service action out(16)",
/* 9a-9f */ NULL, NULL, NULL, "Service action bidirectional",
"Service action in(16)", "Service action out(16)",
/* a0-a5 */ "Report luns", "ATA command pass through(12)/Blank",
"Security protocol in", "Maintenance in", "Maintenance out",
"Move medium/play audio(12)",
@ -122,6 +123,7 @@ static const struct value_name_pair maint_out_arr[] = {
{0x6, "Set identifying information"},
{0xa, "Set target port groups"},
{0xb, "Change aliases"},
{0xc, "Remove I_T nexus"},
{0xe, "Set priority"},
{0xf, "Set timestamp"},
{0x10, "Management protocol out"},
@ -138,10 +140,16 @@ static const struct value_name_pair serv_out12_arr[] = {
};
#define SERV_OUT12_SZ ARRAY_SIZE(serv_out12_arr)
static const struct value_name_pair serv_bidi_arr[] = {
{-1, "dummy entry"},
};
#define SERV_BIDI_SZ ARRAY_SIZE(serv_bidi_arr)
static const struct value_name_pair serv_in16_arr[] = {
{0x10, "Read capacity(16)"},
{0x11, "Read long(16)"},
{0x12, "Get LBA status"},
{0x13, "Report referrals"},
};
#define SERV_IN16_SZ ARRAY_SIZE(serv_in16_arr)
@ -151,6 +159,51 @@ static const struct value_name_pair serv_out16_arr[] = {
};
#define SERV_OUT16_SZ ARRAY_SIZE(serv_out16_arr)
static const struct value_name_pair pr_in_arr[] = {
{0x0, "Persistent reserve in, read keys"},
{0x1, "Persistent reserve in, read reservation"},
{0x2, "Persistent reserve in, report capabilities"},
{0x3, "Persistent reserve in, read full status"},
};
#define PR_IN_SZ ARRAY_SIZE(pr_in_arr)
static const struct value_name_pair pr_out_arr[] = {
{0x0, "Persistent reserve out, register"},
{0x1, "Persistent reserve out, reserve"},
{0x2, "Persistent reserve out, release"},
{0x3, "Persistent reserve out, clear"},
{0x4, "Persistent reserve out, preempt"},
{0x5, "Persistent reserve out, preempt and abort"},
{0x6, "Persistent reserve out, register and ignore existing key"},
{0x7, "Persistent reserve out, register and move"},
};
#define PR_OUT_SZ ARRAY_SIZE(pr_out_arr)
/* SPC-4 rev 34 renamed the Extended Copy opcode to Third Party Copy Out.
LID1 (List Identifier length: 1 byte) is the Extended Copy found in SPC-2
and SPC-3 */
static const struct value_name_pair tpc_out_arr[] = {
{0x0, "Extended copy(LID1)"},
{0x1, "Extended copy(LID4)"},
{0x10, "Populate token"},
{0x11, "Write using token"},
{0x1c, "Copy operation abort"},
};
#define TPC_OUT_SZ ARRAY_SIZE(tpc_out_arr)
static const struct value_name_pair tpc_in_arr[] = {
{0x0, "Receive copy status(LID1)"},
{0x1, "Receive copy data(LID1)"},
{0x3, "Receive copy operating parameters"},
{0x4, "Receive copy failure details(LID1)"},
{0x5, "Receive copy status(LID4)"},
{0x6, "Receive copy data(LID4)"},
{0x7, "Receive ROD token information"},
{0x8, "Report all ROD tokens"},
};
#define TPC_IN_SZ ARRAY_SIZE(tpc_in_arr)
static const struct value_name_pair variable_length_arr[] = {
{0x1, "Rebuild(32)"},
{0x2, "Regenerate(32)"},
@ -207,6 +260,7 @@ static const char * get_sa_name(const struct value_name_pair * arr,
static void print_opcode_name(unsigned char * cdbp, int cdb_len)
{
int sa, len, cdb0;
int fin_name = 0;
const char * name;
cdb0 = cdbp[0];
@ -219,7 +273,8 @@ static void print_opcode_name(unsigned char * cdbp, int cdb_len)
break;
}
sa = (cdbp[8] << 8) + cdbp[9];
name = get_sa_name(variable_length_arr, VARIABLE_LENGTH_SZ, sa);
name = get_sa_name(variable_length_arr, VARIABLE_LENGTH_SZ,
sa);
if (name)
printk("%s", name);
else
@ -232,50 +287,57 @@ static void print_opcode_name(unsigned char * cdbp, int cdb_len)
case MAINTENANCE_IN:
sa = cdbp[1] & 0x1f;
name = get_sa_name(maint_in_arr, MAINT_IN_SZ, sa);
if (name)
printk("%s", name);
else
printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa);
fin_name = 1;
break;
case MAINTENANCE_OUT:
sa = cdbp[1] & 0x1f;
name = get_sa_name(maint_out_arr, MAINT_OUT_SZ, sa);
if (name)
printk("%s", name);
else
printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa);
fin_name = 1;
break;
case PERSISTENT_RESERVE_IN:
sa = cdbp[1] & 0x1f;
name = get_sa_name(pr_in_arr, PR_IN_SZ, sa);
fin_name = 1;
break;
case PERSISTENT_RESERVE_OUT:
sa = cdbp[1] & 0x1f;
name = get_sa_name(pr_out_arr, PR_OUT_SZ, sa);
fin_name = 1;
break;
case SERVICE_ACTION_IN_12:
sa = cdbp[1] & 0x1f;
name = get_sa_name(serv_in12_arr, SERV_IN12_SZ, sa);
if (name)
printk("%s", name);
else
printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa);
fin_name = 1;
break;
case SERVICE_ACTION_OUT_12:
sa = cdbp[1] & 0x1f;
name = get_sa_name(serv_out12_arr, SERV_OUT12_SZ, sa);
if (name)
printk("%s", name);
else
printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa);
fin_name = 1;
break;
case SERVICE_ACTION_BIDIRECTIONAL:
sa = cdbp[1] & 0x1f;
name = get_sa_name(serv_bidi_arr, SERV_BIDI_SZ, sa);
fin_name = 1;
break;
case SERVICE_ACTION_IN_16:
sa = cdbp[1] & 0x1f;
name = get_sa_name(serv_in16_arr, SERV_IN16_SZ, sa);
if (name)
printk("%s", name);
else
printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa);
fin_name = 1;
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", name);
else
printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa);
fin_name = 1;
break;
case THIRD_PARTY_COPY_IN:
sa = cdbp[1] & 0x1f;
name = get_sa_name(tpc_in_arr, TPC_IN_SZ, sa);
fin_name = 1;
break;
case THIRD_PARTY_COPY_OUT:
sa = cdbp[1] & 0x1f;
name = get_sa_name(tpc_out_arr, TPC_OUT_SZ, sa);
fin_name = 1;
break;
default:
if (cdb0 < 0xc0) {
@ -288,6 +350,12 @@ static void print_opcode_name(unsigned char * cdbp, int cdb_len)
printk("cdb[0]=0x%x (vendor)", cdb0);
break;
}
if (fin_name) {
if (name)
printk("%s", name);
else
printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa);
}
}
#else /* ifndef CONFIG_SCSI_CONSTANTS */
@ -312,10 +380,15 @@ static void print_opcode_name(unsigned char * cdbp, int cdb_len)
break;
case MAINTENANCE_IN:
case MAINTENANCE_OUT:
case PERSISTENT_RESERVE_IN:
case PERSISTENT_RESERVE_OUT:
case SERVICE_ACTION_IN_12:
case SERVICE_ACTION_OUT_12:
case SERVICE_ACTION_BIDIRECTIONAL:
case SERVICE_ACTION_IN_16:
case SERVICE_ACTION_OUT_16:
case THIRD_PARTY_COPY_IN:
case THIRD_PARTY_COPY_OUT:
sa = cdbp[1] & 0x1f;
printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa);
break;
@ -327,7 +400,7 @@ static void print_opcode_name(unsigned char * cdbp, int cdb_len)
break;
}
}
#endif
#endif
void __scsi_print_command(unsigned char *cdb)
{
@ -336,7 +409,7 @@ void __scsi_print_command(unsigned char *cdb)
print_opcode_name(cdb, 0);
len = scsi_command_size(cdb);
/* print out all bytes in cdb */
for (k = 0; k < len; ++k)
for (k = 0; k < len; ++k)
printk(" %02x", cdb[k]);
printk("\n");
}
@ -404,8 +477,9 @@ struct error_info {
/*
* The canonical list of T10 Additional Sense Codes is available at:
* http://www.t10.org/lists/asc-num.txt
* http://www.t10.org/lists/asc-num.txt [most recent: 20130605]
*/
static const struct error_info additional[] =
{
{0x0000, "No additional sense information"},
@ -430,6 +504,8 @@ static const struct error_info additional[] =
{0x001C, "Verify operation in progress"},
{0x001D, "ATA pass through information available"},
{0x001E, "Conflicting SA creation request"},
{0x001F, "Logical unit transitioning to another power condition"},
{0x0020, "Extended copy information available"},
{0x0100, "No index/sector signal"},
@ -460,6 +536,17 @@ static const struct error_info additional[] =
{0x0412, "Logical unit not ready, offline"},
{0x0413, "Logical unit not ready, SA creation in progress"},
{0x0414, "Logical unit not ready, space allocation in progress"},
{0x0415, "Logical unit not ready, robotics disabled"},
{0x0416, "Logical unit not ready, configuration required"},
{0x0417, "Logical unit not ready, calibration required"},
{0x0418, "Logical unit not ready, a door is open"},
{0x0419, "Logical unit not ready, operating in sequential mode"},
{0x041A, "Logical unit not ready, start stop unit command in "
"progress"},
{0x041B, "Logical unit not ready, sanitize in progress"},
{0x041C, "Logical unit not ready, additional power use not yet "
"granted"},
{0x041D, "Logical unit not ready, configuration in progress"},
{0x0500, "Logical unit does not respond to selection"},
@ -490,6 +577,7 @@ static const struct error_info additional[] =
{0x0B06, "Warning - non-volatile cache now volatile"},
{0x0B07, "Warning - degraded power to non-volatile cache"},
{0x0B08, "Warning - power loss expected"},
{0x0B09, "Warning - device statistics notification active"},
{0x0C00, "Write error"},
{0x0C01, "Write error - recovered with auto reallocation"},
@ -505,6 +593,7 @@ static const struct error_info additional[] =
{0x0C0B, "Auxiliary memory write error"},
{0x0C0C, "Write error - unexpected unsolicited data"},
{0x0C0D, "Write error - not enough unsolicited data"},
{0x0C0E, "Multiple write errors"},
{0x0C0F, "Defects in error window"},
{0x0D00, "Error detected by third party temporary initiator"},
@ -523,6 +612,8 @@ static const struct error_info additional[] =
{0x1001, "Logical block guard check failed"},
{0x1002, "Logical block application tag check failed"},
{0x1003, "Logical block reference tag check failed"},
{0x1004, "Logical block protection error on recover buffered data"},
{0x1005, "Logical block protection method error"},
{0x1100, "Unrecovered read error"},
{0x1101, "Read retries exhausted"},
@ -545,6 +636,7 @@ static const struct error_info additional[] =
{0x1112, "Auxiliary memory read error"},
{0x1113, "Read error - failed retransmission request"},
{0x1114, "Read error - lba marked bad by application client"},
{0x1115, "Write after sanitize required"},
{0x1200, "Address mark not found for id field"},
@ -622,6 +714,7 @@ static const struct error_info additional[] =
{0x2009, "Access denied - invalid LU identifier"},
{0x200A, "Access denied - invalid proxy token"},
{0x200B, "Access denied - ACL LUN conflict"},
{0x200C, "Illegal command when not in append-only mode"},
{0x2100, "Logical block address out of range"},
{0x2101, "Invalid element address"},
@ -630,6 +723,19 @@ static const struct error_info additional[] =
{0x2200, "Illegal function (use 20 00, 24 00, or 26 00)"},
{0x2300, "Invalid token operation, cause not reportable"},
{0x2301, "Invalid token operation, unsupported token type"},
{0x2302, "Invalid token operation, remote token usage not supported"},
{0x2303, "Invalid token operation, remote rod token creation not "
"supported"},
{0x2304, "Invalid token operation, token unknown"},
{0x2305, "Invalid token operation, token corrupt"},
{0x2306, "Invalid token operation, token revoked"},
{0x2307, "Invalid token operation, token expired"},
{0x2308, "Invalid token operation, token cancelled"},
{0x2309, "Invalid token operation, token deleted"},
{0x230A, "Invalid token operation, invalid token length"},
{0x2400, "Invalid field in cdb"},
{0x2401, "CDB decryption error"},
{0x2402, "Obsolete"},
@ -705,6 +811,7 @@ static const struct error_info additional[] =
"event"},
{0x2A13, "Data encryption key instance counter has changed"},
{0x2A14, "SA creation capabilities data has changed"},
{0x2A15, "Medium removal prevention preempted"},
{0x2B00, "Copy cannot execute since host cannot disconnect"},
@ -720,6 +827,7 @@ static const struct error_info additional[] =
{0x2C09, "Previous reservation conflict status"},
{0x2C0A, "Partition or collection contains user objects"},
{0x2C0B, "Not reserved"},
{0x2C0C, "Orwrite generation does not match"},
{0x2D00, "Overwrite error on update in place"},
@ -728,6 +836,7 @@ static const struct error_info additional[] =
{0x2F00, "Commands cleared by another initiator"},
{0x2F01, "Commands cleared by power loss notification"},
{0x2F02, "Commands cleared by device server"},
{0x2F03, "Some commands cleared by queuing layer event"},
{0x3000, "Incompatible medium installed"},
{0x3001, "Cannot read medium - unknown format"},
@ -745,10 +854,12 @@ static const struct error_info additional[] =
{0x3010, "Medium not formatted"},
{0x3011, "Incompatible volume type"},
{0x3012, "Incompatible volume qualifier"},
{0x3013, "Cleaning volume expired"},
{0x3100, "Medium format corrupted"},
{0x3101, "Format command failed"},
{0x3102, "Zoned formatting failed due to spare linking"},
{0x3103, "Sanitize command failed"},
{0x3200, "No defect spare location available"},
{0x3201, "Defect list update failure"},
@ -809,6 +920,8 @@ static const struct error_info additional[] =
{0x3B19, "Element enabled"},
{0x3B1A, "Data transfer device removed"},
{0x3B1B, "Data transfer device inserted"},
{0x3B1C, "Too many logical objects on partition to support "
"operation"},
{0x3D00, "Invalid bits in identify message"},
@ -839,6 +952,7 @@ static const struct error_info additional[] =
{0x3F12, "iSCSI IP address added"},
{0x3F13, "iSCSI IP address removed"},
{0x3F14, "iSCSI IP address changed"},
{0x3F15, "Inspect referrals sense descriptors"},
/*
* {0x40NN, "Ram failure"},
* {0x40NN, "Diagnostic failure on component nn"},
@ -848,6 +962,7 @@ static const struct error_info additional[] =
{0x4300, "Message error"},
{0x4400, "Internal target failure"},
{0x4401, "Persistent reservation information lost"},
{0x4471, "ATA device failed set features"},
{0x4500, "Select or reselect failure"},
@ -876,6 +991,21 @@ static const struct error_info additional[] =
{0x4B04, "Nak received"},
{0x4B05, "Data offset error"},
{0x4B06, "Initiator response timeout"},
{0x4B07, "Connection lost"},
{0x4B08, "Data-in buffer overflow - data buffer size"},
{0x4B09, "Data-in buffer overflow - data buffer descriptor area"},
{0x4B0A, "Data-in buffer error"},
{0x4B0B, "Data-out buffer overflow - data buffer size"},
{0x4B0C, "Data-out buffer overflow - data buffer descriptor area"},
{0x4B0D, "Data-out buffer error"},
{0x4B0E, "PCIe fabric error"},
{0x4B0F, "PCIe completion timeout"},
{0x4B10, "PCIe completer abort"},
{0x4B11, "PCIe poisoned tlp received"},
{0x4B12, "PCIe eCRC check failed"},
{0x4B13, "PCIe unsupported request"},
{0x4B14, "PCIe acs violation"},
{0x4B15, "PCIe tlp prefix blocked"},
{0x4C00, "Logical unit failed self-configuration"},
/*
@ -897,6 +1027,10 @@ static const struct error_info additional[] =
{0x5302, "Medium removal prevented"},
{0x5303, "Medium removal prevented by data transfer element"},
{0x5304, "Medium thread or unthread failure"},
{0x5305, "Volume identifier invalid"},
{0x5306, "Volume identifier missing"},
{0x5307, "Duplicate volume identifier"},
{0x5308, "Element status unknown"},
{0x5400, "Scsi to host system interface failure"},
@ -911,6 +1045,9 @@ static const struct error_info additional[] =
{0x5508, "Maximum number of supplemental decryption keys exceeded"},
{0x5509, "Medium auxiliary memory not accessible"},
{0x550A, "Data currently unavailable"},
{0x550B, "Insufficient power for operation"},
{0x550C, "Insufficient resources to create rod"},
{0x550D, "Insufficient resources to create rod token"},
{0x5700, "Unable to recover table-of-contents"},
@ -1069,6 +1206,7 @@ static const struct error_info additional[] =
{0x670B, "ATA device feature not enabled"},
{0x6800, "Logical unit not configured"},
{0x6801, "Subsidiary logical unit not configured"},
{0x6900, "Data loss on logical unit"},
{0x6901, "Multiple logical unit failures"},
@ -1185,10 +1323,13 @@ static const char * const snstext[] = {
"Vendor Specific(9)",
"Copy Aborted", /* A: COPY or COMPARE was aborted */
"Aborted Command", /* B: The target aborted the command */
"Equal", /* C: A SEARCH DATA command found data equal */
"Equal", /* C: A SEARCH DATA command found data equal,
reserved in SPC-4 rev 36 */
"Volume Overflow", /* D: Medium full with still data to be written */
"Miscompare", /* E: Source data and data on the medium
do not agree */
"Completed", /* F: command completed sense data reported,
may occur for successful command */
};
#endif
@ -1306,7 +1447,7 @@ scsi_decode_sense_buffer(const unsigned char *sense_buffer, int sense_len,
struct scsi_sense_hdr *sshdr)
{
int k, num, res;
res = scsi_normalize_sense(sense_buffer, sense_len, sshdr);
if (0 == res) {
/* this may be SCSI-1 sense data */
@ -1459,5 +1600,3 @@ void scsi_print_result(struct scsi_cmnd *cmd)
scsi_show_result(cmd->result);
}
EXPORT_SYMBOL(scsi_print_result);

View File

@ -774,7 +774,6 @@ static void fcoe_fdmi_info(struct fc_lport *lport, struct net_device *netdev)
struct fcoe_port *port;
struct net_device *realdev;
int rc;
struct netdev_fcoe_hbainfo fdmi;
port = lport_priv(lport);
fcoe = port->priv;
@ -788,9 +787,13 @@ static void fcoe_fdmi_info(struct fc_lport *lport, struct net_device *netdev)
return;
if (realdev->netdev_ops->ndo_fcoe_get_hbainfo) {
memset(&fdmi, 0, sizeof(fdmi));
struct netdev_fcoe_hbainfo *fdmi;
fdmi = kzalloc(sizeof(*fdmi), GFP_KERNEL);
if (!fdmi)
return;
rc = realdev->netdev_ops->ndo_fcoe_get_hbainfo(realdev,
&fdmi);
fdmi);
if (rc) {
printk(KERN_INFO "fcoe: Failed to retrieve FDMI "
"information from netdev.\n");
@ -800,38 +803,39 @@ static void fcoe_fdmi_info(struct fc_lport *lport, struct net_device *netdev)
snprintf(fc_host_serial_number(lport->host),
FC_SERIAL_NUMBER_SIZE,
"%s",
fdmi.serial_number);
fdmi->serial_number);
snprintf(fc_host_manufacturer(lport->host),
FC_SERIAL_NUMBER_SIZE,
"%s",
fdmi.manufacturer);
fdmi->manufacturer);
snprintf(fc_host_model(lport->host),
FC_SYMBOLIC_NAME_SIZE,
"%s",
fdmi.model);
fdmi->model);
snprintf(fc_host_model_description(lport->host),
FC_SYMBOLIC_NAME_SIZE,
"%s",
fdmi.model_description);
fdmi->model_description);
snprintf(fc_host_hardware_version(lport->host),
FC_VERSION_STRING_SIZE,
"%s",
fdmi.hardware_version);
fdmi->hardware_version);
snprintf(fc_host_driver_version(lport->host),
FC_VERSION_STRING_SIZE,
"%s",
fdmi.driver_version);
fdmi->driver_version);
snprintf(fc_host_optionrom_version(lport->host),
FC_VERSION_STRING_SIZE,
"%s",
fdmi.optionrom_version);
fdmi->optionrom_version);
snprintf(fc_host_firmware_version(lport->host),
FC_VERSION_STRING_SIZE,
"%s",
fdmi.firmware_version);
fdmi->firmware_version);
/* Enable FDMI lport states */
lport->fdmi_enabled = 1;
kfree(fdmi);
} else {
lport->fdmi_enabled = 0;
printk(KERN_INFO "fcoe: No FDMI support.\n");

View File

@ -2090,7 +2090,11 @@ static struct fc_rport_operations fcoe_ctlr_vn_rport_ops = {
*/
static void fcoe_ctlr_disc_stop_locked(struct fc_lport *lport)
{
struct fc_rport_priv *rdata;
mutex_lock(&lport->disc.disc_mutex);
list_for_each_entry_rcu(rdata, &lport->disc.rports, peers)
lport->tt.rport_logoff(rdata);
lport->disc.disc_callback = NULL;
mutex_unlock(&lport->disc.disc_mutex);
}

View File

@ -507,7 +507,7 @@ static const struct attribute_group *fcoe_fcf_attr_groups[] = {
NULL,
};
struct bus_type fcoe_bus_type;
static struct bus_type fcoe_bus_type;
static int fcoe_bus_match(struct device *dev,
struct device_driver *drv)
@ -541,25 +541,25 @@ static void fcoe_fcf_device_release(struct device *dev)
kfree(fcf);
}
struct device_type fcoe_ctlr_device_type = {
static struct device_type fcoe_ctlr_device_type = {
.name = "fcoe_ctlr",
.groups = fcoe_ctlr_attr_groups,
.release = fcoe_ctlr_device_release,
};
struct device_type fcoe_fcf_device_type = {
static struct device_type fcoe_fcf_device_type = {
.name = "fcoe_fcf",
.groups = fcoe_fcf_attr_groups,
.release = fcoe_fcf_device_release,
};
struct bus_attribute fcoe_bus_attr_group[] = {
static struct bus_attribute fcoe_bus_attr_group[] = {
__ATTR(ctlr_create, S_IWUSR, NULL, fcoe_ctlr_create_store),
__ATTR(ctlr_destroy, S_IWUSR, NULL, fcoe_ctlr_destroy_store),
__ATTR_NULL
};
struct bus_type fcoe_bus_type = {
static struct bus_type fcoe_bus_type = {
.name = "fcoe",
.match = &fcoe_bus_match,
.bus_attrs = fcoe_bus_attr_group,
@ -569,7 +569,7 @@ struct bus_type fcoe_bus_type = {
* fcoe_ctlr_device_flush_work() - Flush a FIP ctlr's workqueue
* @ctlr: Pointer to the FIP ctlr whose workqueue is to be flushed
*/
void fcoe_ctlr_device_flush_work(struct fcoe_ctlr_device *ctlr)
static void fcoe_ctlr_device_flush_work(struct fcoe_ctlr_device *ctlr)
{
if (!fcoe_ctlr_work_q(ctlr)) {
printk(KERN_ERR
@ -590,8 +590,8 @@ void fcoe_ctlr_device_flush_work(struct fcoe_ctlr_device *ctlr)
* Return value:
* 1 on success / 0 already queued / < 0 for error
*/
int fcoe_ctlr_device_queue_work(struct fcoe_ctlr_device *ctlr,
struct work_struct *work)
static int fcoe_ctlr_device_queue_work(struct fcoe_ctlr_device *ctlr,
struct work_struct *work)
{
if (unlikely(!fcoe_ctlr_work_q(ctlr))) {
printk(KERN_ERR
@ -609,7 +609,7 @@ int fcoe_ctlr_device_queue_work(struct fcoe_ctlr_device *ctlr,
* fcoe_ctlr_device_flush_devloss() - Flush a FIP ctlr's devloss workqueue
* @ctlr: Pointer to FIP ctlr whose workqueue is to be flushed
*/
void fcoe_ctlr_device_flush_devloss(struct fcoe_ctlr_device *ctlr)
static void fcoe_ctlr_device_flush_devloss(struct fcoe_ctlr_device *ctlr)
{
if (!fcoe_ctlr_devloss_work_q(ctlr)) {
printk(KERN_ERR
@ -631,9 +631,9 @@ void fcoe_ctlr_device_flush_devloss(struct fcoe_ctlr_device *ctlr)
* Return value:
* 1 on success / 0 already queued / < 0 for error
*/
int fcoe_ctlr_device_queue_devloss_work(struct fcoe_ctlr_device *ctlr,
struct delayed_work *work,
unsigned long delay)
static int fcoe_ctlr_device_queue_devloss_work(struct fcoe_ctlr_device *ctlr,
struct delayed_work *work,
unsigned long delay)
{
if (unlikely(!fcoe_ctlr_devloss_work_q(ctlr))) {
printk(KERN_ERR

View File

@ -180,24 +180,10 @@ void fcoe_ctlr_get_lesb(struct fcoe_ctlr_device *ctlr_dev)
{
struct fcoe_ctlr *fip = fcoe_ctlr_device_priv(ctlr_dev);
struct net_device *netdev = fcoe_get_netdev(fip->lp);
struct fcoe_fc_els_lesb *fcoe_lesb;
struct fc_els_lesb fc_lesb;
struct fc_els_lesb *fc_lesb;
__fcoe_get_lesb(fip->lp, &fc_lesb, netdev);
fcoe_lesb = (struct fcoe_fc_els_lesb *)(&fc_lesb);
ctlr_dev->lesb.lesb_link_fail =
ntohl(fcoe_lesb->lesb_link_fail);
ctlr_dev->lesb.lesb_vlink_fail =
ntohl(fcoe_lesb->lesb_vlink_fail);
ctlr_dev->lesb.lesb_miss_fka =
ntohl(fcoe_lesb->lesb_miss_fka);
ctlr_dev->lesb.lesb_symb_err =
ntohl(fcoe_lesb->lesb_symb_err);
ctlr_dev->lesb.lesb_err_block =
ntohl(fcoe_lesb->lesb_err_block);
ctlr_dev->lesb.lesb_fcs_error =
ntohl(fcoe_lesb->lesb_fcs_error);
fc_lesb = (struct fc_els_lesb *)(&ctlr_dev->lesb);
__fcoe_get_lesb(fip->lp, fc_lesb, netdev);
}
EXPORT_SYMBOL_GPL(fcoe_ctlr_get_lesb);
@ -721,7 +707,6 @@ ssize_t fcoe_ctlr_create_store(struct bus_type *bus,
{
struct net_device *netdev = NULL;
struct fcoe_transport *ft = NULL;
struct fcoe_ctlr_device *ctlr_dev = NULL;
int rc = 0;
int err;
@ -768,9 +753,8 @@ ssize_t fcoe_ctlr_create_store(struct bus_type *bus,
goto out_putdev;
}
LIBFCOE_TRANSPORT_DBG("transport %s %s to create fcoe on %s.\n",
ft->name, (ctlr_dev) ? "succeeded" : "failed",
netdev->name);
LIBFCOE_TRANSPORT_DBG("transport %s succeeded to create fcoe on %s.\n",
ft->name, netdev->name);
out_putdev:
dev_put(netdev);

View File

@ -337,7 +337,7 @@ static void fc_exch_release(struct fc_exch *ep)
* fc_exch_timer_cancel() - cancel exch timer
* @ep: The exchange whose timer to be canceled
*/
static inline void fc_exch_timer_cancel(struct fc_exch *ep)
static inline void fc_exch_timer_cancel(struct fc_exch *ep)
{
if (cancel_delayed_work(&ep->timeout_work)) {
FC_EXCH_DBG(ep, "Exchange timer canceled\n");
@ -1567,7 +1567,7 @@ static void fc_exch_abts_resp(struct fc_exch *ep, struct fc_frame *fp)
fc_exch_rctl_name(fh->fh_r_ctl));
if (cancel_delayed_work_sync(&ep->timeout_work)) {
FC_EXCH_DBG(ep, "Exchange timer canceled\n");
FC_EXCH_DBG(ep, "Exchange timer canceled due to ABTS response\n");
fc_exch_release(ep); /* release from pending timer hold */
}

View File

@ -926,6 +926,20 @@ err:
kref_put(&rdata->kref, rdata->local_port->tt.rport_destroy);
}
static bool
fc_rport_compatible_roles(struct fc_lport *lport, struct fc_rport_priv *rdata)
{
if (rdata->ids.roles == FC_PORT_ROLE_UNKNOWN)
return true;
if ((rdata->ids.roles & FC_PORT_ROLE_FCP_TARGET) &&
(lport->service_params & FCP_SPPF_INIT_FCN))
return true;
if ((rdata->ids.roles & FC_PORT_ROLE_FCP_INITIATOR) &&
(lport->service_params & FCP_SPPF_TARG_FCN))
return true;
return false;
}
/**
* fc_rport_enter_plogi() - Send Port Login (PLOGI) request
* @rdata: The remote port to send a PLOGI to
@ -938,6 +952,12 @@ static void fc_rport_enter_plogi(struct fc_rport_priv *rdata)
struct fc_lport *lport = rdata->local_port;
struct fc_frame *fp;
if (!fc_rport_compatible_roles(lport, rdata)) {
FC_RPORT_DBG(rdata, "PLOGI suppressed for incompatible role\n");
fc_rport_state_enter(rdata, RPORT_ST_PLOGI_WAIT);
return;
}
FC_RPORT_DBG(rdata, "Port entered PLOGI state from %s state\n",
fc_rport_state(rdata));
@ -1646,6 +1666,13 @@ static void fc_rport_recv_plogi_req(struct fc_lport *lport,
rjt_data.explan = ELS_EXPL_NONE;
goto reject;
}
if (!fc_rport_compatible_roles(lport, rdata)) {
FC_RPORT_DBG(rdata, "Received PLOGI for incompatible role\n");
mutex_unlock(&rdata->rp_mutex);
rjt_data.reason = ELS_RJT_LOGIC;
rjt_data.explan = ELS_EXPL_NONE;
goto reject;
}
/*
* Get session payload size from incoming PLOGI.

View File

@ -4958,10 +4958,12 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance,
sense, sense_handle);
}
for (i = 0; i < ioc->sge_count && kbuff_arr[i]; i++) {
dma_free_coherent(&instance->pdev->dev,
kern_sge32[i].length,
kbuff_arr[i], kern_sge32[i].phys_addr);
for (i = 0; i < ioc->sge_count; i++) {
if (kbuff_arr[i])
dma_free_coherent(&instance->pdev->dev,
kern_sge32[i].length,
kbuff_arr[i],
kern_sge32[i].phys_addr);
}
megasas_return_cmd(instance, cmd);

View File

@ -585,7 +585,7 @@ u8 get_arm(struct megasas_instance *instance, u32 ld, u8 span, u64 stripe,
case 1:
/* start with logical arm */
arm = get_arm_from_strip(instance, ld, stripe, map);
if (arm != -1UL)
if (arm != -1U)
arm *= 2;
break;
}
@ -637,7 +637,7 @@ static u8 mr_spanset_get_phy_params(struct megasas_instance *instance, u32 ld,
if (raid->level == 6) {
logArm = get_arm_from_strip(instance, ld, stripRow, map);
if (logArm == -1UL)
if (logArm == -1U)
return FALSE;
rowMod = mega_mod64(row, SPAN_ROW_SIZE(map, ld, span));
armQ = SPAN_ROW_SIZE(map, ld, span) - 1 - rowMod;

View File

@ -2,7 +2,7 @@
# Kernel configuration file for the MPT3SAS
#
# This code is based on drivers/scsi/mpt3sas/Kconfig
# Copyright (C) 2012 LSI Corporation
# Copyright (C) 2012-2013 LSI Corporation
# (mailto:DL-MPTFusionLinux@lsi.com)
# This program is free software; you can redistribute it and/or

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000-2012 LSI Corporation.
* Copyright (c) 2000-2013 LSI Corporation.
*
*
* Name: mpi2.h
@ -8,7 +8,7 @@
* scatter/gather formats.
* Creation Date: June 21, 2006
*
* mpi2.h Version: 02.00.26
* mpi2.h Version: 02.00.29
*
* NOTE: Names (typedefs, defines, etc.) beginning with an MPI25 or Mpi25
* prefix are for use only on MPI v2.5 products, and must not be used
@ -82,6 +82,10 @@
* 03-29-12 02.00.25 Bumped MPI2_HEADER_VERSION_UNIT.
* Added Hard Reset delay timings.
* 07-10-12 02.00.26 Bumped MPI2_HEADER_VERSION_UNIT.
* 07-26-12 02.00.27 Bumped MPI2_HEADER_VERSION_UNIT.
* 11-27-12 02.00.28 Bumped MPI2_HEADER_VERSION_UNIT.
* 12-20-12 02.00.29 Bumped MPI2_HEADER_VERSION_UNIT.
* Added MPI25_SUP_REPLY_POST_HOST_INDEX_OFFSET.
* --------------------------------------------------------------------------
*/
@ -115,7 +119,7 @@
#define MPI2_VERSION_02_05 (0x0205)
/*Unit and Dev versioning for this MPI header set */
#define MPI2_HEADER_VERSION_UNIT (0x1A)
#define MPI2_HEADER_VERSION_UNIT (0x1D)
#define MPI2_HEADER_VERSION_DEV (0x00)
#define MPI2_HEADER_VERSION_UNIT_MASK (0xFF00)
#define MPI2_HEADER_VERSION_UNIT_SHIFT (8)
@ -274,6 +278,8 @@ typedef volatile struct _MPI2_SYSTEM_INTERFACE_REGS {
#define MPI2_REPLY_POST_HOST_INDEX_MASK (0x00FFFFFF)
#define MPI2_RPHI_MSIX_INDEX_MASK (0xFF000000)
#define MPI2_RPHI_MSIX_INDEX_SHIFT (24)
#define MPI25_SUP_REPLY_POST_HOST_INDEX_OFFSET (0x0000030C) /*MPI v2.5 only*/
/*
*Defines for the HCBSize and address

View File

@ -1,12 +1,12 @@
/*
* Copyright (c) 2000-2011 LSI Corporation.
* Copyright (c) 2000-2013 LSI Corporation.
*
*
* Name: mpi2_cnfg.h
* Title: MPI Configuration messages and pages
* Creation Date: November 10, 2006
*
* mpi2_cnfg.h Version: 02.00.22
* mpi2_cnfg.h Version: 02.00.24
*
* NOTE: Names (typedefs, defines, etc.) beginning with an MPI25 or Mpi25
* prefix are for use only on MPI v2.5 products, and must not be used
@ -155,6 +155,11 @@
* Added UEFIVersion field to BIOS Page 1 and defined new
* BiosOptions bits.
* Incorporating additions for MPI v2.5.
* 11-27-12 02.00.23 Added MPI2_MANPAGE7_FLAG_EVENTREPLAY_SLOT_ORDER.
* Added MPI2_BIOSPAGE1_OPTIONS_MASK_OEM_ID.
* 12-20-12 02.00.24 Marked MPI2_SASIOUNIT1_CONTROL_CLEAR_AFFILIATION as
* obsolete for MPI v2.5 and later.
* Added some defines for 12G SAS speeds.
* --------------------------------------------------------------------------
*/
@ -714,6 +719,7 @@ typedef struct _MPI2_CONFIG_PAGE_MAN_7 {
#define MPI2_MANUFACTURING7_PAGEVERSION (0x01)
/*defines for the Flags field */
#define MPI2_MANPAGE7_FLAG_EVENTREPLAY_SLOT_ORDER (0x00000002)
#define MPI2_MANPAGE7_FLAG_USE_SLOT_INFO (0x00000001)
@ -1310,6 +1316,9 @@ typedef struct _MPI2_CONFIG_PAGE_BIOS_1 {
#define MPI2_BIOSPAGE1_PAGEVERSION (0x05)
/*values for BIOS Page 1 BiosOptions field */
#define MPI2_BIOSPAGE1_OPTIONS_MASK_OEM_ID (0x000000F0)
#define MPI2_BIOSPAGE1_OPTIONS_LSI_OEM_ID (0x00000000)
#define MPI2_BIOSPAGE1_OPTIONS_MASK_UEFI_HII_REGISTRATION (0x00000006)
#define MPI2_BIOSPAGE1_OPTIONS_ENABLE_UEFI_HII (0x00000000)
#define MPI2_BIOSPAGE1_OPTIONS_DISABLE_UEFI_HII (0x00000002)
@ -1884,6 +1893,7 @@ typedef struct _MPI2_CONFIG_PAGE_RD_PDISK_1 {
#define MPI2_SAS_PRATE_MAX_RATE_1_5 (0x80)
#define MPI2_SAS_PRATE_MAX_RATE_3_0 (0x90)
#define MPI2_SAS_PRATE_MAX_RATE_6_0 (0xA0)
#define MPI25_SAS_PRATE_MAX_RATE_12_0 (0xB0)
#define MPI2_SAS_PRATE_MIN_RATE_MASK (0x0F)
#define MPI2_SAS_PRATE_MIN_RATE_NOT_PROGRAMMABLE (0x00)
#define MPI2_SAS_PRATE_MIN_RATE_1_5 (0x08)
@ -1897,6 +1907,7 @@ typedef struct _MPI2_CONFIG_PAGE_RD_PDISK_1 {
#define MPI2_SAS_HWRATE_MAX_RATE_1_5 (0x80)
#define MPI2_SAS_HWRATE_MAX_RATE_3_0 (0x90)
#define MPI2_SAS_HWRATE_MAX_RATE_6_0 (0xA0)
#define MPI25_SAS_HWRATE_MAX_RATE_12_0 (0xB0)
#define MPI2_SAS_HWRATE_MIN_RATE_MASK (0x0F)
#define MPI2_SAS_HWRATE_MIN_RATE_1_5 (0x08)
#define MPI2_SAS_HWRATE_MIN_RATE_3_0 (0x09)

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000-2012 LSI Corporation.
* Copyright (c) 2000-2013 LSI Corporation.
*
*
* Name: mpi2_init.h

View File

@ -1,12 +1,12 @@
/*
* Copyright (c) 2000-2012 LSI Corporation.
* Copyright (c) 2000-2013 LSI Corporation.
*
*
* Name: mpi2_ioc.h
* Title: MPI IOC, Port, Event, FW Download, and FW Upload messages
* Creation Date: October 11, 2006
*
* mpi2_ioc.h Version: 02.00.21
* mpi2_ioc.h Version: 02.00.22
*
* NOTE: Names (typedefs, defines, etc.) beginning with an MPI25 or Mpi25
* prefix are for use only on MPI v2.5 products, and must not be used
@ -124,6 +124,9 @@
* Marked MPI2_PM_CONTROL_FEATURE_PCIE_LINK as obsolete.
* 11-18-11 02.00.20 Incorporating additions for MPI v2.5.
* 03-29-12 02.00.21 Added a product specific range to event values.
* 07-26-12 02.00.22 Added MPI2_IOCFACTS_EXCEPT_PARTIAL_MEMORY_FAILURE.
* Added ElapsedSeconds field to
* MPI2_EVENT_DATA_IR_OPERATION_STATUS.
* --------------------------------------------------------------------------
*/
@ -283,6 +286,7 @@ typedef struct _MPI2_IOC_FACTS_REPLY {
#define MPI2_IOCFACTS_HDRVERSION_DEV_SHIFT (0)
/*IOCExceptions */
#define MPI2_IOCFACTS_EXCEPT_PARTIAL_MEMORY_FAILURE (0x0200)
#define MPI2_IOCFACTS_EXCEPT_IR_FOREIGN_CONFIG_MAX (0x0100)
#define MPI2_IOCFACTS_EXCEPT_BOOTSTAT_MASK (0x00E0)
@ -634,7 +638,7 @@ typedef struct _MPI2_EVENT_DATA_IR_OPERATION_STATUS {
U8 RAIDOperation; /*0x04 */
U8 PercentComplete; /*0x05 */
U16 Reserved2; /*0x06 */
U32 Resereved3; /*0x08 */
U32 ElapsedSeconds; /*0x08 */
} MPI2_EVENT_DATA_IR_OPERATION_STATUS,
*PTR_MPI2_EVENT_DATA_IR_OPERATION_STATUS,
Mpi2EventDataIrOperationStatus_t,

View File

@ -1,12 +1,12 @@
/*
* Copyright (c) 2000-2012 LSI Corporation.
* Copyright (c) 2000-2013 LSI Corporation.
*
*
* Name: mpi2_raid.h
* Title: MPI Integrated RAID messages and structures
* Creation Date: April 26, 2007
*
* mpi2_raid.h Version: 02.00.08
* mpi2_raid.h Version: 02.00.09
*
* Version History
* ---------------
@ -28,6 +28,8 @@
* Added product-specific range to RAID Action values.
* 11-18-11 02.00.07 Incorporating additions for MPI v2.5.
* 02-06-12 02.00.08 Added MPI2_RAID_ACTION_PHYSDISK_HIDDEN.
* 07-26-12 02.00.09 Added ElapsedSeconds field to MPI2_RAID_VOL_INDICATOR.
* Added MPI2_RAID_VOL_FLAGS_ELAPSED_SECONDS_VALID define.
* --------------------------------------------------------------------------
*/
@ -269,10 +271,12 @@ typedef struct _MPI2_RAID_VOL_INDICATOR {
U64 TotalBlocks; /*0x00 */
U64 BlocksRemaining; /*0x08 */
U32 Flags; /*0x10 */
U32 ElapsedSeconds; /* 0x14 */
} MPI2_RAID_VOL_INDICATOR, *PTR_MPI2_RAID_VOL_INDICATOR,
Mpi2RaidVolIndicator_t, *pMpi2RaidVolIndicator_t;
/*defines for RAID Volume Indicator Flags field */
#define MPI2_RAID_VOL_FLAGS_ELAPSED_SECONDS_VALID (0x80000000)
#define MPI2_RAID_VOL_FLAGS_OP_MASK (0x0000000F)
#define MPI2_RAID_VOL_FLAGS_OP_BACKGROUND_INIT (0x00000000)
#define MPI2_RAID_VOL_FLAGS_OP_ONLINE_CAP_EXPANSION (0x00000001)
@ -312,7 +316,7 @@ typedef struct _MPI2_RAID_COMPATIBILITY_RESULT_STRUCT {
/*RAID Action Reply ActionData union */
typedef union _MPI2_RAID_ACTION_REPLY_DATA {
U32 Word[5];
U32 Word[6];
MPI2_RAID_VOL_INDICATOR RaidVolumeIndicator;
U16 VolDevHandle;
U8 VolumeState;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000-2012 LSI Corporation.
* Copyright (c) 2000-2013 LSI Corporation.
*
*
* Name: mpi2_sas.h

View File

@ -1,12 +1,12 @@
/*
* Copyright (c) 2000-2012 LSI Corporation.
* Copyright (c) 2000-2013 LSI Corporation.
*
*
* Name: mpi2_tool.h
* Title: MPI diagnostic tool structures and definitions
* Creation Date: March 26, 2007
*
* mpi2_tool.h Version: 02.00.09
* mpi2_tool.h Version: 02.00.10
*
* Version History
* ---------------
@ -30,6 +30,8 @@
* 11-18-11 02.00.08 Incorporating additions for MPI v2.5.
* 07-10-12 02.00.09 Add MPI v2.5 Toolbox Diagnostic CLI Tool Request
* message.
* 07-26-12 02.00.10 Modified MPI2_TOOLBOX_DIAGNOSTIC_CLI_REQUEST so that
* it uses MPI Chain SGE as well as MPI Simple SGE.
* --------------------------------------------------------------------------
*/
@ -279,7 +281,7 @@ typedef struct _MPI2_TOOLBOX_DIAGNOSTIC_CLI_REQUEST {
U16 Reserved6; /*0x0E */
U32 DataLength; /*0x10 */
U8 DiagnosticCliCommand[MPI2_TOOLBOX_DIAG_CLI_CMD_LENGTH];/*0x14 */
MPI2_SGE_SIMPLE_UNION SGL; /*0x70 */
MPI2_MPI_SGE_IO_UNION SGL; /*0x70 */
} MPI2_TOOLBOX_DIAGNOSTIC_CLI_REQUEST,
*PTR_MPI2_TOOLBOX_DIAGNOSTIC_CLI_REQUEST,
Mpi2ToolboxDiagnosticCliRequest_t,
@ -302,7 +304,7 @@ typedef struct _MPI25_TOOLBOX_DIAGNOSTIC_CLI_REQUEST {
U32 Reserved5; /*0x0C */
U32 DataLength; /*0x10 */
U8 DiagnosticCliCommand[MPI2_TOOLBOX_DIAG_CLI_CMD_LENGTH];/*0x14 */
MPI25_SGE_IO_UNION SGL; /*0x70 */
MPI25_SGE_IO_UNION SGL; /* 0x70 */
} MPI25_TOOLBOX_DIAGNOSTIC_CLI_REQUEST,
*PTR_MPI25_TOOLBOX_DIAGNOSTIC_CLI_REQUEST,
Mpi25ToolboxDiagnosticCliRequest_t,

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000-2007 LSI Corporation.
* Copyright (c) 2000-2013 LSI Corporation.
*
*
* Name: mpi2_type.h

View File

@ -3,7 +3,7 @@
* for access to MPT (Message Passing Technology) firmware.
*
* This code is based on drivers/scsi/mpt3sas/mpt3sas_base.c
* Copyright (C) 2012 LSI Corporation
* Copyright (C) 2012-2013 LSI Corporation
* (mailto:DL-MPTFusionLinux@lsi.com)
*
* This program is free software; you can redistribute it and/or
@ -4090,11 +4090,15 @@ _base_diag_reset(struct MPT3SAS_ADAPTER *ioc, int sleep_flag)
writel(host_diagnostic | MPI2_DIAG_RESET_ADAPTER,
&ioc->chip->HostDiagnostic);
/* don't access any registers for 50 milliseconds */
msleep(50);
/*This delay allows the chip PCIe hardware time to finish reset tasks*/
if (sleep_flag == CAN_SLEEP)
msleep(MPI2_HARD_RESET_PCIE_FIRST_READ_DELAY_MICRO_SEC/1000);
else
mdelay(MPI2_HARD_RESET_PCIE_FIRST_READ_DELAY_MICRO_SEC/1000);
/* 300 second max wait */
for (count = 0; count < 3000000 ; count++) {
/* Approximately 300 second max wait */
for (count = 0; count < (300000000 /
MPI2_HARD_RESET_PCIE_SECOND_READ_DELAY_MICRO_SEC); count++) {
host_diagnostic = readl(&ioc->chip->HostDiagnostic);
@ -4103,11 +4107,13 @@ _base_diag_reset(struct MPT3SAS_ADAPTER *ioc, int sleep_flag)
if (!(host_diagnostic & MPI2_DIAG_RESET_ADAPTER))
break;
/* wait 1 msec */
/* Wait to pass the second read delay window */
if (sleep_flag == CAN_SLEEP)
usleep_range(1000, 1500);
msleep(MPI2_HARD_RESET_PCIE_SECOND_READ_DELAY_MICRO_SEC
/ 1000);
else
mdelay(1);
mdelay(MPI2_HARD_RESET_PCIE_SECOND_READ_DELAY_MICRO_SEC
/ 1000);
}
if (host_diagnostic & MPI2_DIAG_HCB_MODE) {

View File

@ -3,7 +3,7 @@
* for access to MPT (Message Passing Technology) firmware.
*
* This code is based on drivers/scsi/mpt3sas/mpt3sas_base.h
* Copyright (C) 2012 LSI Corporation
* Copyright (C) 2012-2013 LSI Corporation
* (mailto:DL-MPTFusionLinux@lsi.com)
*
* This program is free software; you can redistribute it and/or
@ -70,10 +70,10 @@
#define MPT3SAS_DRIVER_NAME "mpt3sas"
#define MPT3SAS_AUTHOR "LSI Corporation <DL-MPTFusionLinux@lsi.com>"
#define MPT3SAS_DESCRIPTION "LSI MPT Fusion SAS 3.0 Device Driver"
#define MPT3SAS_DRIVER_VERSION "01.100.01.00"
#define MPT3SAS_MAJOR_VERSION 1
#define MPT3SAS_DRIVER_VERSION "02.100.00.00"
#define MPT3SAS_MAJOR_VERSION 2
#define MPT3SAS_MINOR_VERSION 100
#define MPT3SAS_BUILD_VERSION 1
#define MPT3SAS_BUILD_VERSION 0
#define MPT3SAS_RELEASE_VERSION 00
/*

View File

@ -2,7 +2,7 @@
* This module provides common API for accessing firmware configuration pages
*
* This code is based on drivers/scsi/mpt3sas/mpt3sas_base.c
* Copyright (C) 2012 LSI Corporation
* Copyright (C) 2012-2013 LSI Corporation
* (mailto:DL-MPTFusionLinux@lsi.com)
*
* This program is free software; you can redistribute it and/or

View File

@ -3,7 +3,7 @@
* controllers
*
* This code is based on drivers/scsi/mpt3sas/mpt3sas_ctl.c
* Copyright (C) 2012 LSI Corporation
* Copyright (C) 2012-2013 LSI Corporation
* (mailto:DL-MPTFusionLinux@lsi.com)
*
* This program is free software; you can redistribute it and/or

View File

@ -3,7 +3,7 @@
* controllers
*
* This code is based on drivers/scsi/mpt3sas/mpt3sas_ctl.h
* Copyright (C) 2012 LSI Corporation
* Copyright (C) 2012-2013 LSI Corporation
* (mailto:DL-MPTFusionLinux@lsi.com)
*
* This program is free software; you can redistribute it and/or

View File

@ -2,7 +2,7 @@
* Logging Support for MPT (Message Passing Technology) based controllers
*
* This code is based on drivers/scsi/mpt3sas/mpt3sas_debug.c
* Copyright (C) 2012 LSI Corporation
* Copyright (C) 2012-2013 LSI Corporation
* (mailto:DL-MPTFusionLinux@lsi.com)
*
* This program is free software; you can redistribute it and/or

View File

@ -2,7 +2,7 @@
* Scsi Host Layer for MPT (Message Passing Technology) based controllers
*
* This code is based on drivers/scsi/mpt3sas/mpt3sas_scsih.c
* Copyright (C) 2012 LSI Corporation
* Copyright (C) 2012-2013 LSI Corporation
* (mailto:DL-MPTFusionLinux@lsi.com)
*
* This program is free software; you can redistribute it and/or
@ -675,11 +675,12 @@ _scsih_sas_device_add(struct MPT3SAS_ADAPTER *ioc,
* devices while scanning is turned on due to an oops in
* scsi_sysfs_add_sdev()->add_device()->sysfs_addrm_start()
*/
if (!ioc->is_driver_loading)
if (!ioc->is_driver_loading) {
mpt3sas_transport_port_remove(ioc,
sas_device->sas_address,
sas_device->sas_address_parent);
_scsih_sas_device_remove(ioc, sas_device);
_scsih_sas_device_remove(ioc, sas_device);
}
}
}
@ -1273,6 +1274,7 @@ _scsih_slave_alloc(struct scsi_device *sdev)
struct MPT3SAS_DEVICE *sas_device_priv_data;
struct scsi_target *starget;
struct _raid_device *raid_device;
struct _sas_device *sas_device;
unsigned long flags;
sas_device_priv_data = kzalloc(sizeof(struct scsi_device), GFP_KERNEL);
@ -1301,6 +1303,19 @@ _scsih_slave_alloc(struct scsi_device *sdev)
spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
}
if (!(sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME)) {
spin_lock_irqsave(&ioc->sas_device_lock, flags);
sas_device = mpt3sas_scsih_sas_device_find_by_sas_address(ioc,
sas_target_priv_data->sas_address);
if (sas_device && (sas_device->starget == NULL)) {
sdev_printk(KERN_INFO, sdev,
"%s : sas_device->starget set to starget @ %d\n",
__func__, __LINE__);
sas_device->starget = starget;
}
spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
}
return 0;
}
@ -6392,7 +6407,7 @@ _scsih_search_responding_sas_devices(struct MPT3SAS_ADAPTER *ioc)
handle))) {
ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
MPI2_IOCSTATUS_MASK;
if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
if (ioc_status != MPI2_IOCSTATUS_SUCCESS)
break;
handle = le16_to_cpu(sas_device_pg0.DevHandle);
device_info = le32_to_cpu(sas_device_pg0.DeviceInfo);
@ -6494,7 +6509,7 @@ _scsih_search_responding_raid_devices(struct MPT3SAS_ADAPTER *ioc)
&volume_pg1, MPI2_RAID_VOLUME_PGAD_FORM_GET_NEXT_HANDLE, handle))) {
ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
MPI2_IOCSTATUS_MASK;
if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
if (ioc_status != MPI2_IOCSTATUS_SUCCESS)
break;
handle = le16_to_cpu(volume_pg1.DevHandle);
@ -6518,7 +6533,7 @@ _scsih_search_responding_raid_devices(struct MPT3SAS_ADAPTER *ioc)
phys_disk_num))) {
ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
MPI2_IOCSTATUS_MASK;
if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
if (ioc_status != MPI2_IOCSTATUS_SUCCESS)
break;
phys_disk_num = pd_pg0.PhysDiskNum;
handle = le16_to_cpu(pd_pg0.DevHandle);
@ -6597,7 +6612,7 @@ _scsih_search_responding_expanders(struct MPT3SAS_ADAPTER *ioc)
ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
MPI2_IOCSTATUS_MASK;
if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
if (ioc_status != MPI2_IOCSTATUS_SUCCESS)
break;
handle = le16_to_cpu(expander_pg0.DevHandle);
@ -6742,8 +6757,6 @@ _scsih_scan_for_devices_after_reset(struct MPT3SAS_ADAPTER *ioc)
MPI2_SAS_EXPAND_PGAD_FORM_GET_NEXT_HNDL, handle))) {
ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
MPI2_IOCSTATUS_MASK;
if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
break;
if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
pr_info(MPT3SAS_FMT "\tbreak from expander scan: " \
"ioc_status(0x%04x), loginfo(0x%08x)\n",
@ -6787,8 +6800,6 @@ _scsih_scan_for_devices_after_reset(struct MPT3SAS_ADAPTER *ioc)
phys_disk_num))) {
ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
MPI2_IOCSTATUS_MASK;
if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
break;
if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
pr_info(MPT3SAS_FMT "\tbreak from phys disk scan: "\
"ioc_status(0x%04x), loginfo(0x%08x)\n",
@ -6854,8 +6865,6 @@ _scsih_scan_for_devices_after_reset(struct MPT3SAS_ADAPTER *ioc)
&volume_pg1, MPI2_RAID_VOLUME_PGAD_FORM_GET_NEXT_HANDLE, handle))) {
ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
MPI2_IOCSTATUS_MASK;
if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
break;
if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
pr_info(MPT3SAS_FMT "\tbreak from volume scan: " \
"ioc_status(0x%04x), loginfo(0x%08x)\n",
@ -6914,8 +6923,6 @@ _scsih_scan_for_devices_after_reset(struct MPT3SAS_ADAPTER *ioc)
handle))) {
ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
MPI2_IOCSTATUS_MASK;
if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
break;
if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
pr_info(MPT3SAS_FMT "\tbreak from end device scan:"\
" ioc_status(0x%04x), loginfo(0x%08x)\n",
@ -7525,10 +7532,12 @@ _scsih_probe_boot_devices(struct MPT3SAS_ADAPTER *ioc)
sas_address_parent)) {
_scsih_sas_device_remove(ioc, sas_device);
} else if (!sas_device->starget) {
if (!ioc->is_driver_loading)
mpt3sas_transport_port_remove(ioc, sas_address,
if (!ioc->is_driver_loading) {
mpt3sas_transport_port_remove(ioc,
sas_address,
sas_address_parent);
_scsih_sas_device_remove(ioc, sas_device);
_scsih_sas_device_remove(ioc, sas_device);
}
}
}
}
@ -7584,13 +7593,14 @@ _scsih_probe_sas(struct MPT3SAS_ADAPTER *ioc)
* oops in scsi_sysfs_add_sdev()->add_device()->
* sysfs_addrm_start()
*/
if (!ioc->is_driver_loading)
if (!ioc->is_driver_loading) {
mpt3sas_transport_port_remove(ioc,
sas_device->sas_address,
sas_device->sas_address_parent);
list_del(&sas_device->list);
kfree(sas_device);
continue;
list_del(&sas_device->list);
kfree(sas_device);
continue;
}
}
spin_lock_irqsave(&ioc->sas_device_lock, flags);

View File

@ -2,7 +2,7 @@
* SAS Transport Layer for MPT (Message Passing Technology) based controllers
*
* This code is based on drivers/scsi/mpt3sas/mpt3sas_transport.c
* Copyright (C) 2012 LSI Corporation
* Copyright (C) 2012-2013 LSI Corporation
* (mailto:DL-MPTFusionLinux@lsi.com)
*
* This program is free software; you can redistribute it and/or

View File

@ -3,7 +3,7 @@
* (Message Passing Technology) based controllers
*
* This code is based on drivers/scsi/mpt3sas/mpt3sas_trigger_diag.c
* Copyright (C) 2012 LSI Corporation
* Copyright (C) 2012-2013 LSI Corporation
* (mailto:DL-MPTFusionLinux@lsi.com)
*
* This program is free software; you can redistribute it and/or

View File

@ -4,7 +4,7 @@
* controllers
*
* This code is based on drivers/scsi/mpt3sas/mpt3sas_base.h
* Copyright (C) 2012 LSI Corporation
* Copyright (C) 2012-2013 LSI Corporation
* (mailto:DL-MPTFusionLinux@lsi.com)
*
* This program is free software; you can redistribute it and/or

View File

@ -912,14 +912,13 @@ static int pm8001_pci_suspend(struct pci_dev *pdev, pm_message_t state)
{
struct sas_ha_struct *sha = pci_get_drvdata(pdev);
struct pm8001_hba_info *pm8001_ha;
int i , pos;
int i;
u32 device_state;
pm8001_ha = sha->lldd_ha;
flush_workqueue(pm8001_wq);
scsi_block_requests(pm8001_ha->shost);
pos = pci_find_capability(pdev, PCI_CAP_ID_PM);
if (pos == 0) {
printk(KERN_ERR " PCI PM not supported\n");
if (!pdev->pm_cap) {
dev_err(&pdev->dev, " PCI PM not supported\n");
return -ENODEV;
}
PM8001_CHIP_DISP->interrupt_disable(pm8001_ha, 0xFF);

View File

@ -1691,6 +1691,9 @@ qla2x00_get_fc_host_stats(struct Scsi_Host *shost)
if (unlikely(pci_channel_offline(ha->pdev)))
goto done;
if (qla2x00_reset_active(vha))
goto done;
stats = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &stats_dma);
if (stats == NULL) {
ql_log(ql_log_warn, vha, 0x707d,
@ -1703,7 +1706,7 @@ qla2x00_get_fc_host_stats(struct Scsi_Host *shost)
if (IS_FWI2_CAPABLE(ha)) {
rval = qla24xx_get_isp_stats(base_vha, stats, stats_dma);
} else if (atomic_read(&base_vha->loop_state) == LOOP_READY &&
!qla2x00_reset_active(vha) && !ha->dpc_active) {
!ha->dpc_active) {
/* Must be in a 'READY' state for statistics retrieval. */
rval = qla2x00_get_link_status(base_vha, base_vha->loop_id,
stats, stats_dma);

View File

@ -269,6 +269,12 @@ qla2x00_process_els(struct fc_bsg_job *bsg_job)
type = "FC_BSG_HST_ELS_NOLOGIN";
}
if (!vha->flags.online) {
ql_log(ql_log_warn, vha, 0x7005, "Host not online.\n");
rval = -EIO;
goto done;
}
/* pass through is supported only for ISP 4Gb or higher */
if (!IS_FWI2_CAPABLE(ha)) {
ql_dbg(ql_dbg_user, vha, 0x7001,
@ -326,12 +332,6 @@ qla2x00_process_els(struct fc_bsg_job *bsg_job)
NPH_FABRIC_CONTROLLER : NPH_F_PORT;
}
if (!vha->flags.online) {
ql_log(ql_log_warn, vha, 0x7005, "Host not online.\n");
rval = -EIO;
goto done;
}
req_sg_cnt =
dma_map_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
@ -399,7 +399,7 @@ done_unmap_sg:
goto done_free_fcport;
done_free_fcport:
if (bsg_job->request->msgcode == FC_BSG_HST_ELS_NOLOGIN)
if (bsg_job->request->msgcode == FC_BSG_RPT_ELS)
kfree(fcport);
done:
return rval;
@ -1084,14 +1084,6 @@ qla84xx_mgmt_cmd(struct fc_bsg_job *bsg_job)
return -EINVAL;
}
ql84_mgmt = (struct qla_bsg_a84_mgmt *)((char *)bsg_job->request +
sizeof(struct fc_bsg_request));
if (!ql84_mgmt) {
ql_log(ql_log_warn, vha, 0x703b,
"MGMT header not provided, exiting.\n");
return -EINVAL;
}
mn = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &mn_dma);
if (!mn) {
ql_log(ql_log_warn, vha, 0x703c,
@ -1102,7 +1094,7 @@ qla84xx_mgmt_cmd(struct fc_bsg_job *bsg_job)
memset(mn, 0, sizeof(struct access_chip_84xx));
mn->entry_type = ACCESS_CHIP_IOCB_TYPE;
mn->entry_count = 1;
ql84_mgmt = (void *)bsg_job->request + sizeof(struct fc_bsg_request);
switch (ql84_mgmt->mgmt.cmd) {
case QLA84_MGMT_READ_MEM:
case QLA84_MGMT_GET_INFO:
@ -1282,14 +1274,7 @@ qla24xx_iidma(struct fc_bsg_job *bsg_job)
return -EINVAL;
}
port_param = (struct qla_port_param *)((char *)bsg_job->request +
sizeof(struct fc_bsg_request));
if (!port_param) {
ql_log(ql_log_warn, vha, 0x7047,
"port_param header not provided.\n");
return -EINVAL;
}
port_param = (void *)bsg_job->request + sizeof(struct fc_bsg_request);
if (port_param->fc_scsi_addr.dest_type != EXT_DEF_TYPE_WWPN) {
ql_log(ql_log_warn, vha, 0x7048,
"Invalid destination type.\n");
@ -2153,6 +2138,7 @@ qla24xx_bsg_timeout(struct fc_bsg_job *bsg_job)
(sp->type == SRB_ELS_CMD_HST) ||
(sp->type == SRB_FXIOCB_BCMD))
&& (sp->u.bsg_job == bsg_job)) {
req->outstanding_cmds[cnt] = NULL;
spin_unlock_irqrestore(&ha->hardware_lock, flags);
if (ha->isp_ops->abort_command(sp)) {
ql_log(ql_log_warn, vha, 0x7089,
@ -2180,8 +2166,6 @@ qla24xx_bsg_timeout(struct fc_bsg_job *bsg_job)
done:
spin_unlock_irqrestore(&ha->hardware_lock, flags);
if (bsg_job->request->msgcode == FC_BSG_HST_CT)
kfree(sp->fcport);
qla2x00_rel_sp(vha, sp);
sp->free(vha, sp);
return 0;
}

View File

@ -12,9 +12,10 @@
* | Level | Last Value Used | Holes |
* ----------------------------------------------------------------------
* | Module Init and Probe | 0x014f | 0x4b,0xba,0xfa |
* | Mailbox commands | 0x1179 | 0x111a-0x111b |
* | Mailbox commands | 0x117a | 0x111a-0x111b |
* | | | 0x1155-0x1158 |
* | Device Discovery | 0x2095 | 0x2020-0x2022, |
* | | | 0x2011-0x2012, |
* | | | 0x2016 |
* | Queue Command and IO tracing | 0x3058 | 0x3006-0x300b |
* | | | 0x3027-0x3028 |
@ -35,7 +36,8 @@
* | | | 0x70a5,0x70a6, |
* | | | 0x70a8,0x70ab, |
* | | | 0x70ad-0x70ae, |
* | | | 0x70d1-0x70da |
* | | | 0x70d1-0x70da, |
* | | | 0x7047,0x703b |
* | Task Management | 0x803c | 0x8025-0x8026 |
* | | | 0x800b,0x8039 |
* | AER/EEH | 0x9011 | |
@ -1468,7 +1470,7 @@ qla25xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
nxt = qla2xxx_copy_queues(ha, nxt);
nxt = qla24xx_copy_eft(ha, nxt);
qla24xx_copy_eft(ha, nxt);
/* Chain entries -- started with MQ. */
nxt_chain = qla25xx_copy_fce(ha, nxt_chain, &last_chain);
@ -1787,7 +1789,7 @@ qla81xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
nxt = qla2xxx_copy_queues(ha, nxt);
nxt = qla24xx_copy_eft(ha, nxt);
qla24xx_copy_eft(ha, nxt);
/* Chain entries -- started with MQ. */
nxt_chain = qla25xx_copy_fce(ha, nxt_chain, &last_chain);
@ -2289,7 +2291,7 @@ qla83xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
copy_queue:
nxt = qla2xxx_copy_queues(ha, nxt);
nxt = qla24xx_copy_eft(ha, nxt);
qla24xx_copy_eft(ha, nxt);
/* Chain entries -- started with MQ. */
nxt_chain = qla25xx_copy_fce(ha, nxt_chain, &last_chain);

View File

@ -323,7 +323,7 @@ struct srb_iocb {
uint32_t lun;
uint32_t data;
struct completion comp;
uint32_t comp_status;
__le16 comp_status;
} tmf;
struct {
#define SRB_FXDISC_REQ_DMA_VALID BIT_0
@ -338,21 +338,21 @@ struct srb_iocb {
void *rsp_addr;
dma_addr_t req_dma_handle;
dma_addr_t rsp_dma_handle;
uint32_t adapter_id;
uint32_t adapter_id_hi;
uint32_t req_func_type;
uint32_t req_data;
uint32_t req_data_extra;
uint32_t result;
uint32_t seq_number;
uint32_t fw_flags;
__le32 adapter_id;
__le32 adapter_id_hi;
__le16 req_func_type;
__le32 req_data;
__le32 req_data_extra;
__le32 result;
__le32 seq_number;
__le16 fw_flags;
struct completion fxiocb_comp;
uint32_t reserved_0;
__le32 reserved_0;
uint8_t reserved_1;
} fxiocb;
struct {
uint32_t cmd_hndl;
uint32_t comp_status;
__le16 comp_status;
struct completion comp;
} abt;
} u;
@ -1196,14 +1196,14 @@ typedef struct {
struct init_cb_fx {
uint16_t version;
uint16_t reserved_1[13];
uint16_t request_q_outpointer;
uint16_t response_q_inpointer;
__le16 request_q_outpointer;
__le16 response_q_inpointer;
uint16_t reserved_2[2];
uint16_t response_q_length;
uint16_t request_q_length;
__le16 response_q_length;
__le16 request_q_length;
uint16_t reserved_3[2];
uint32_t request_q_address[2];
uint32_t response_q_address[2];
__le32 request_q_address[2];
__le32 response_q_address[2];
uint16_t reserved_4[4];
uint8_t response_q_msivec;
uint8_t reserved_5[19];

View File

@ -587,7 +587,7 @@ extern int qlafx00_init_firmware(scsi_qla_host_t *, uint16_t);
extern int qlafx00_fw_ready(scsi_qla_host_t *);
extern int qlafx00_configure_devices(scsi_qla_host_t *);
extern int qlafx00_reset_initialize(scsi_qla_host_t *);
extern int qlafx00_fx_disc(scsi_qla_host_t *, fc_port_t *, uint8_t);
extern int qlafx00_fx_disc(scsi_qla_host_t *, fc_port_t *, uint16_t);
extern int qlafx00_process_aen(struct scsi_qla_host *, struct qla_work_evt *);
extern int qlafx00_post_aenfx_work(struct scsi_qla_host *, uint32_t,
uint32_t *, int);

View File

@ -99,17 +99,17 @@ qla24xx_prep_ms_iocb(scsi_qla_host_t *vha, uint32_t req_size, uint32_t rsp_size)
* Returns a pointer to the intitialized @ct_req.
*/
static inline struct ct_sns_req *
qla2x00_prep_ct_req(struct ct_sns_req *ct_req, uint16_t cmd, uint16_t rsp_size)
qla2x00_prep_ct_req(struct ct_sns_pkt *p, uint16_t cmd, uint16_t rsp_size)
{
memset(ct_req, 0, sizeof(struct ct_sns_pkt));
memset(p, 0, sizeof(struct ct_sns_pkt));
ct_req->header.revision = 0x01;
ct_req->header.gs_type = 0xFC;
ct_req->header.gs_subtype = 0x02;
ct_req->command = cpu_to_be16(cmd);
ct_req->max_rsp_size = cpu_to_be16((rsp_size - 16) / 4);
p->p.req.header.revision = 0x01;
p->p.req.header.gs_type = 0xFC;
p->p.req.header.gs_subtype = 0x02;
p->p.req.command = cpu_to_be16(cmd);
p->p.req.max_rsp_size = cpu_to_be16((rsp_size - 16) / 4);
return (ct_req);
return &p->p.req;
}
static int
@ -188,7 +188,7 @@ qla2x00_ga_nxt(scsi_qla_host_t *vha, fc_port_t *fcport)
GA_NXT_RSP_SIZE);
/* Prepare CT request */
ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, GA_NXT_CMD,
ct_req = qla2x00_prep_ct_req(ha->ct_sns, GA_NXT_CMD,
GA_NXT_RSP_SIZE);
ct_rsp = &ha->ct_sns->p.rsp;
@ -284,8 +284,7 @@ qla2x00_gid_pt(scsi_qla_host_t *vha, sw_info_t *list)
gid_pt_rsp_size);
/* Prepare CT request */
ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, GID_PT_CMD,
gid_pt_rsp_size);
ct_req = qla2x00_prep_ct_req(ha->ct_sns, GID_PT_CMD, gid_pt_rsp_size);
ct_rsp = &ha->ct_sns->p.rsp;
/* Prepare CT arguments -- port_type */
@ -359,7 +358,7 @@ qla2x00_gpn_id(scsi_qla_host_t *vha, sw_info_t *list)
GPN_ID_RSP_SIZE);
/* Prepare CT request */
ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, GPN_ID_CMD,
ct_req = qla2x00_prep_ct_req(ha->ct_sns, GPN_ID_CMD,
GPN_ID_RSP_SIZE);
ct_rsp = &ha->ct_sns->p.rsp;
@ -421,7 +420,7 @@ qla2x00_gnn_id(scsi_qla_host_t *vha, sw_info_t *list)
GNN_ID_RSP_SIZE);
/* Prepare CT request */
ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, GNN_ID_CMD,
ct_req = qla2x00_prep_ct_req(ha->ct_sns, GNN_ID_CMD,
GNN_ID_RSP_SIZE);
ct_rsp = &ha->ct_sns->p.rsp;
@ -495,7 +494,7 @@ qla2x00_rft_id(scsi_qla_host_t *vha)
RFT_ID_RSP_SIZE);
/* Prepare CT request */
ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, RFT_ID_CMD,
ct_req = qla2x00_prep_ct_req(ha->ct_sns, RFT_ID_CMD,
RFT_ID_RSP_SIZE);
ct_rsp = &ha->ct_sns->p.rsp;
@ -551,7 +550,7 @@ qla2x00_rff_id(scsi_qla_host_t *vha)
RFF_ID_RSP_SIZE);
/* Prepare CT request */
ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, RFF_ID_CMD,
ct_req = qla2x00_prep_ct_req(ha->ct_sns, RFF_ID_CMD,
RFF_ID_RSP_SIZE);
ct_rsp = &ha->ct_sns->p.rsp;
@ -606,8 +605,7 @@ qla2x00_rnn_id(scsi_qla_host_t *vha)
RNN_ID_RSP_SIZE);
/* Prepare CT request */
ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, RNN_ID_CMD,
RNN_ID_RSP_SIZE);
ct_req = qla2x00_prep_ct_req(ha->ct_sns, RNN_ID_CMD, RNN_ID_RSP_SIZE);
ct_rsp = &ha->ct_sns->p.rsp;
/* Prepare CT arguments -- port_id, node_name */
@ -676,7 +674,7 @@ qla2x00_rsnn_nn(scsi_qla_host_t *vha)
ms_pkt = ha->isp_ops->prep_ms_iocb(vha, 0, RSNN_NN_RSP_SIZE);
/* Prepare CT request */
ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, RSNN_NN_CMD,
ct_req = qla2x00_prep_ct_req(ha->ct_sns, RSNN_NN_CMD,
RSNN_NN_RSP_SIZE);
ct_rsp = &ha->ct_sns->p.rsp;
@ -1262,18 +1260,18 @@ qla2x00_update_ms_fdmi_iocb(scsi_qla_host_t *vha, uint32_t req_size)
* Returns a pointer to the intitialized @ct_req.
*/
static inline struct ct_sns_req *
qla2x00_prep_ct_fdmi_req(struct ct_sns_req *ct_req, uint16_t cmd,
qla2x00_prep_ct_fdmi_req(struct ct_sns_pkt *p, uint16_t cmd,
uint16_t rsp_size)
{
memset(ct_req, 0, sizeof(struct ct_sns_pkt));
memset(p, 0, sizeof(struct ct_sns_pkt));
ct_req->header.revision = 0x01;
ct_req->header.gs_type = 0xFA;
ct_req->header.gs_subtype = 0x10;
ct_req->command = cpu_to_be16(cmd);
ct_req->max_rsp_size = cpu_to_be16((rsp_size - 16) / 4);
p->p.req.header.revision = 0x01;
p->p.req.header.gs_type = 0xFA;
p->p.req.header.gs_subtype = 0x10;
p->p.req.command = cpu_to_be16(cmd);
p->p.req.max_rsp_size = cpu_to_be16((rsp_size - 16) / 4);
return ct_req;
return &p->p.req;
}
/**
@ -1301,8 +1299,7 @@ qla2x00_fdmi_rhba(scsi_qla_host_t *vha)
ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(vha, 0, RHBA_RSP_SIZE);
/* Prepare CT request */
ct_req = qla2x00_prep_ct_fdmi_req(&ha->ct_sns->p.req, RHBA_CMD,
RHBA_RSP_SIZE);
ct_req = qla2x00_prep_ct_fdmi_req(ha->ct_sns, RHBA_CMD, RHBA_RSP_SIZE);
ct_rsp = &ha->ct_sns->p.rsp;
/* Prepare FDMI command arguments -- attribute block, attributes. */
@ -1370,8 +1367,7 @@ qla2x00_fdmi_rhba(scsi_qla_host_t *vha)
/* Model description. */
eiter = (struct ct_fdmi_hba_attr *) (entries + size);
eiter->type = __constant_cpu_to_be16(FDMI_HBA_MODEL_DESCRIPTION);
if (ha->model_desc)
strncpy(eiter->a.model_desc, ha->model_desc, 80);
strncpy(eiter->a.model_desc, ha->model_desc, 80);
alen = strlen(eiter->a.model_desc);
alen += (alen & 3) ? (4 - (alen & 3)) : 4;
eiter->len = cpu_to_be16(4 + alen);
@ -1491,8 +1487,7 @@ qla2x00_fdmi_dhba(scsi_qla_host_t *vha)
DHBA_RSP_SIZE);
/* Prepare CT request */
ct_req = qla2x00_prep_ct_fdmi_req(&ha->ct_sns->p.req, DHBA_CMD,
DHBA_RSP_SIZE);
ct_req = qla2x00_prep_ct_fdmi_req(ha->ct_sns, DHBA_CMD, DHBA_RSP_SIZE);
ct_rsp = &ha->ct_sns->p.rsp;
/* Prepare FDMI command arguments -- portname. */
@ -1548,8 +1543,7 @@ qla2x00_fdmi_rpa(scsi_qla_host_t *vha)
ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(vha, 0, RPA_RSP_SIZE);
/* Prepare CT request */
ct_req = qla2x00_prep_ct_fdmi_req(&ha->ct_sns->p.req, RPA_CMD,
RPA_RSP_SIZE);
ct_req = qla2x00_prep_ct_fdmi_req(ha->ct_sns, RPA_CMD, RPA_RSP_SIZE);
ct_rsp = &ha->ct_sns->p.rsp;
/* Prepare FDMI command arguments -- attribute block, attributes. */
@ -1776,7 +1770,7 @@ qla2x00_gfpn_id(scsi_qla_host_t *vha, sw_info_t *list)
GFPN_ID_RSP_SIZE);
/* Prepare CT request */
ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, GFPN_ID_CMD,
ct_req = qla2x00_prep_ct_req(ha->ct_sns, GFPN_ID_CMD,
GFPN_ID_RSP_SIZE);
ct_rsp = &ha->ct_sns->p.rsp;
@ -1843,18 +1837,18 @@ qla24xx_prep_ms_fm_iocb(scsi_qla_host_t *vha, uint32_t req_size,
static inline struct ct_sns_req *
qla24xx_prep_ct_fm_req(struct ct_sns_req *ct_req, uint16_t cmd,
qla24xx_prep_ct_fm_req(struct ct_sns_pkt *p, uint16_t cmd,
uint16_t rsp_size)
{
memset(ct_req, 0, sizeof(struct ct_sns_pkt));
memset(p, 0, sizeof(struct ct_sns_pkt));
ct_req->header.revision = 0x01;
ct_req->header.gs_type = 0xFA;
ct_req->header.gs_subtype = 0x01;
ct_req->command = cpu_to_be16(cmd);
ct_req->max_rsp_size = cpu_to_be16((rsp_size - 16) / 4);
p->p.req.header.revision = 0x01;
p->p.req.header.gs_type = 0xFA;
p->p.req.header.gs_subtype = 0x01;
p->p.req.command = cpu_to_be16(cmd);
p->p.req.max_rsp_size = cpu_to_be16((rsp_size - 16) / 4);
return ct_req;
return &p->p.req;
}
/**
@ -1890,8 +1884,8 @@ qla2x00_gpsc(scsi_qla_host_t *vha, sw_info_t *list)
GPSC_RSP_SIZE);
/* Prepare CT request */
ct_req = qla24xx_prep_ct_fm_req(&ha->ct_sns->p.req,
GPSC_CMD, GPSC_RSP_SIZE);
ct_req = qla24xx_prep_ct_fm_req(ha->ct_sns, GPSC_CMD,
GPSC_RSP_SIZE);
ct_rsp = &ha->ct_sns->p.rsp;
/* Prepare CT arguments -- port_name */
@ -2001,7 +1995,7 @@ qla2x00_gff_id(scsi_qla_host_t *vha, sw_info_t *list)
GFF_ID_RSP_SIZE);
/* Prepare CT request */
ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, GFF_ID_CMD,
ct_req = qla2x00_prep_ct_req(ha->ct_sns, GFF_ID_CMD,
GFF_ID_RSP_SIZE);
ct_rsp = &ha->ct_sns->p.rsp;

View File

@ -2309,14 +2309,6 @@ qla2x00_configure_hba(scsi_qla_host_t *vha)
"Topology - %s, Host Loop address 0x%x.\n",
connect_type, vha->loop_id);
if (rval) {
ql_log(ql_log_warn, vha, 0x2011,
"%s FAILED\n", __func__);
} else {
ql_dbg(ql_dbg_disc, vha, 0x2012,
"%s success\n", __func__);
}
return(rval);
}

View File

@ -83,7 +83,7 @@ static inline void
host_to_adap(uint8_t *src, uint8_t *dst, uint32_t bsize)
{
uint32_t *isrc = (uint32_t *) src;
uint32_t *odest = (uint32_t *) dst;
__le32 *odest = (__le32 *) dst;
uint32_t iter = bsize >> 2;
for (; iter ; iter--)

View File

@ -1189,7 +1189,6 @@ qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt,
uint32_t *cur_dsd, *fcp_dl;
scsi_qla_host_t *vha;
struct scsi_cmnd *cmd;
struct scatterlist *cur_seg;
int sgc;
uint32_t total_bytes = 0;
uint32_t data_bytes;
@ -1396,7 +1395,6 @@ qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt,
if (bundling && tot_prot_dsds) {
/* Walks dif segments */
cur_seg = scsi_prot_sglist(cmd);
cmd_pkt->control_flags |=
__constant_cpu_to_le16(CF_DIF_SEG_DESCR_ENABLE);
cur_dsd = (uint32_t *) &crc_ctx_pkt->u.bundling.dif_address;
@ -1863,8 +1861,8 @@ skip_cmd_array:
pkt = req->ring_ptr;
memset(pkt, 0, REQUEST_ENTRY_SIZE);
if (IS_QLAFX00(ha)) {
WRT_REG_BYTE(&pkt->entry_count, req_cnt);
WRT_REG_WORD(&pkt->handle, handle);
WRT_REG_BYTE((void __iomem *)&pkt->entry_count, req_cnt);
WRT_REG_WORD((void __iomem *)&pkt->handle, handle);
} else {
pkt->entry_count = req_cnt;
pkt->handle = handle;

View File

@ -2485,6 +2485,7 @@ qla2xxx_check_risc_status(scsi_qla_host_t *vha)
if (rval == QLA_SUCCESS)
goto next_test;
rval = QLA_SUCCESS;
WRT_REG_DWORD(&reg->iobase_window, 0x0003);
for (cnt = 100; (RD_REG_DWORD(&reg->iobase_window) & BIT_0) == 0 &&
rval == QLA_SUCCESS; cnt--) {

View File

@ -177,8 +177,14 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
WRT_REG_WORD(&reg->isp.hccr, HCCR_SET_HOST_INT);
spin_unlock_irqrestore(&ha->hardware_lock, flags);
wait_for_completion_timeout(&ha->mbx_intr_comp, mcp->tov * HZ);
if (!wait_for_completion_timeout(&ha->mbx_intr_comp,
mcp->tov * HZ)) {
ql_dbg(ql_dbg_mbx, vha, 0x117a,
"cmd=%x Timeout.\n", command);
spin_lock_irqsave(&ha->hardware_lock, flags);
clear_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);
spin_unlock_irqrestore(&ha->hardware_lock, flags);
}
} else {
ql_dbg(ql_dbg_mbx, vha, 0x1011,
"Cmd=%x Polling Mode.\n", command);
@ -275,9 +281,11 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
/*
* Attempt to capture a firmware dump for further analysis
* of the current firmware state
* of the current firmware state. We do not need to do this
* if we are intentionally generating a dump.
*/
ha->isp_ops->fw_dump(vha, 0);
if (mcp->mb[0] != MBC_GEN_SYSTEM_ERROR)
ha->isp_ops->fw_dump(vha, 0);
rval = QLA_FUNCTION_TIMEOUT;
}

View File

@ -707,7 +707,7 @@ qlafx00_tmf_iocb_timeout(void *data)
srb_t *sp = (srb_t *)data;
struct srb_iocb *tmf = &sp->u.iocb_cmd;
tmf->u.tmf.comp_status = CS_TIMEOUT;
tmf->u.tmf.comp_status = cpu_to_le16((uint16_t)CS_TIMEOUT);
complete(&tmf->u.tmf.comp);
}
@ -1418,7 +1418,8 @@ qlafx00_init_response_q_entries(struct rsp_que *rsp)
pkt = rsp->ring_ptr;
for (cnt = 0; cnt < rsp->length; cnt++) {
pkt->signature = RESPONSE_PROCESSED;
WRT_REG_DWORD(&pkt->signature, RESPONSE_PROCESSED);
WRT_REG_DWORD((void __iomem *)&pkt->signature,
RESPONSE_PROCESSED);
pkt++;
}
}
@ -1733,7 +1734,7 @@ qla2x00_fxdisc_sp_done(void *data, void *ptr, int res)
}
int
qlafx00_fx_disc(scsi_qla_host_t *vha, fc_port_t *fcport, uint8_t fx_type)
qlafx00_fx_disc(scsi_qla_host_t *vha, fc_port_t *fcport, uint16_t fx_type)
{
srb_t *sp;
struct srb_iocb *fdisc;
@ -1759,13 +1760,13 @@ qlafx00_fx_disc(scsi_qla_host_t *vha, fc_port_t *fcport, uint8_t fx_type)
fdisc->u.fxiocb.flags =
SRB_FXDISC_RESP_DMA_VALID | SRB_FXDISC_REQ_DWRD_VALID;
fdisc->u.fxiocb.rsp_len = QLAFX00_PORT_DATA_INFO;
fdisc->u.fxiocb.req_data = fcport->port_id;
fdisc->u.fxiocb.req_data = cpu_to_le32(fcport->port_id);
break;
case FXDISC_GET_TGT_NODE_INFO:
fdisc->u.fxiocb.flags =
SRB_FXDISC_RESP_DMA_VALID | SRB_FXDISC_REQ_DWRD_VALID;
fdisc->u.fxiocb.rsp_len = QLAFX00_TGT_NODE_INFO;
fdisc->u.fxiocb.req_data = fcport->tgt_id;
fdisc->u.fxiocb.req_data = cpu_to_le32(fcport->tgt_id);
break;
case FXDISC_GET_TGT_NODE_LIST:
fdisc->u.fxiocb.flags =
@ -1851,7 +1852,7 @@ qlafx00_fx_disc(scsi_qla_host_t *vha, fc_port_t *fcport, uint8_t fx_type)
sp->name = "fxdisc";
qla2x00_init_timer(sp, FXDISC_TIMEOUT);
fdisc->timeout = qla2x00_fxdisc_iocb_timeout;
fdisc->u.fxiocb.req_func_type = fx_type;
fdisc->u.fxiocb.req_func_type = cpu_to_le16(fx_type);
sp->done = qla2x00_fxdisc_sp_done;
rval = qla2x00_start_sp(sp);
@ -1904,7 +1905,7 @@ qlafx00_fx_disc(scsi_qla_host_t *vha, fc_port_t *fcport, uint8_t fx_type)
(uint8_t *)pinfo, 16);
memcpy(vha->hw->gid_list, pinfo, QLAFX00_TGT_NODE_LIST_SIZE);
}
rval = fdisc->u.fxiocb.result;
rval = le32_to_cpu(fdisc->u.fxiocb.result);
done_unmap_dma:
if (fdisc->u.fxiocb.rsp_addr)
@ -1927,7 +1928,7 @@ qlafx00_abort_iocb_timeout(void *data)
srb_t *sp = (srb_t *)data;
struct srb_iocb *abt = &sp->u.iocb_cmd;
abt->u.abt.comp_status = CS_TIMEOUT;
abt->u.abt.comp_status = cpu_to_le16((uint16_t)CS_TIMEOUT);
complete(&abt->u.abt.comp);
}
@ -2169,14 +2170,14 @@ qlafx00_handle_sense(srb_t *sp, uint8_t *sense_data, uint32_t par_sense_len,
static void
qlafx00_tm_iocb_entry(scsi_qla_host_t *vha, struct req_que *req,
struct tsk_mgmt_entry_fx00 *pkt, srb_t *sp,
uint16_t sstatus, uint16_t cpstatus)
__le16 sstatus, __le16 cpstatus)
{
struct srb_iocb *tmf;
tmf = &sp->u.iocb_cmd;
if (cpstatus != CS_COMPLETE ||
(sstatus & SS_RESPONSE_INFO_LEN_VALID))
cpstatus = CS_INCOMPLETE;
if (cpstatus != cpu_to_le16((uint16_t)CS_COMPLETE) ||
(sstatus & cpu_to_le16((uint16_t)SS_RESPONSE_INFO_LEN_VALID)))
cpstatus = cpu_to_le16((uint16_t)CS_INCOMPLETE);
tmf->u.tmf.comp_status = cpstatus;
sp->done(vha, sp, 0);
}
@ -2194,7 +2195,7 @@ qlafx00_abort_iocb_entry(scsi_qla_host_t *vha, struct req_que *req,
return;
abt = &sp->u.iocb_cmd;
abt->u.abt.comp_status = le32_to_cpu(pkt->tgt_id_sts);
abt->u.abt.comp_status = pkt->tgt_id_sts;
sp->done(vha, sp, 0);
}
@ -2216,12 +2217,12 @@ qlafx00_ioctl_iosb_entry(scsi_qla_host_t *vha, struct req_que *req,
if (sp->type == SRB_FXIOCB_DCMD) {
iocb_job = &sp->u.iocb_cmd;
iocb_job->u.fxiocb.seq_number = le32_to_cpu(pkt->seq_no);
iocb_job->u.fxiocb.fw_flags = le32_to_cpu(pkt->fw_iotcl_flags);
iocb_job->u.fxiocb.result = le32_to_cpu(pkt->status);
iocb_job->u.fxiocb.seq_number = pkt->seq_no;
iocb_job->u.fxiocb.fw_flags = pkt->fw_iotcl_flags;
iocb_job->u.fxiocb.result = pkt->status;
if (iocb_job->u.fxiocb.flags & SRB_FXDISC_RSP_DWRD_VALID)
iocb_job->u.fxiocb.req_data =
le32_to_cpu(pkt->dataword_r);
pkt->dataword_r;
} else {
bsg_job = sp->u.bsg_job;
@ -2275,10 +2276,10 @@ qlafx00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
fc_port_t *fcport;
struct scsi_cmnd *cp;
struct sts_entry_fx00 *sts;
uint16_t comp_status;
uint16_t scsi_status;
__le16 comp_status;
__le16 scsi_status;
uint16_t ox_id;
uint8_t lscsi_status;
__le16 lscsi_status;
int32_t resid;
uint32_t sense_len, par_sense_len, rsp_info_len, resid_len,
fw_resid_len;
@ -2292,8 +2293,8 @@ qlafx00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
sts = (struct sts_entry_fx00 *) pkt;
comp_status = le16_to_cpu(sts->comp_status);
scsi_status = le16_to_cpu(sts->scsi_status) & SS_MASK;
comp_status = sts->comp_status;
scsi_status = sts->scsi_status & cpu_to_le16((uint16_t)SS_MASK);
hindex = sts->handle;
handle = LSW(hindex);
@ -2339,38 +2340,40 @@ qlafx00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
return;
}
lscsi_status = scsi_status & STATUS_MASK;
lscsi_status = scsi_status & cpu_to_le16((uint16_t)STATUS_MASK);
fcport = sp->fcport;
ox_id = 0;
sense_len = par_sense_len = rsp_info_len = resid_len =
fw_resid_len = 0;
if (scsi_status & SS_SENSE_LEN_VALID)
sense_len = le32_to_cpu(sts->sense_len);
if (scsi_status & (SS_RESIDUAL_UNDER | SS_RESIDUAL_OVER))
if (scsi_status & cpu_to_le16((uint16_t)SS_SENSE_LEN_VALID))
sense_len = sts->sense_len;
if (scsi_status & cpu_to_le16(((uint16_t)SS_RESIDUAL_UNDER
| (uint16_t)SS_RESIDUAL_OVER)))
resid_len = le32_to_cpu(sts->residual_len);
if (comp_status == CS_DATA_UNDERRUN)
if (comp_status == cpu_to_le16((uint16_t)CS_DATA_UNDERRUN))
fw_resid_len = le32_to_cpu(sts->residual_len);
rsp_info = sense_data = sts->data;
par_sense_len = sizeof(sts->data);
/* Check for overrun. */
if (comp_status == CS_COMPLETE &&
scsi_status & SS_RESIDUAL_OVER)
comp_status = CS_DATA_OVERRUN;
scsi_status & cpu_to_le16((uint16_t)SS_RESIDUAL_OVER))
comp_status = cpu_to_le16((uint16_t)CS_DATA_OVERRUN);
/*
* Based on Host and scsi status generate status code for Linux
*/
switch (comp_status) {
switch (le16_to_cpu(comp_status)) {
case CS_COMPLETE:
case CS_QUEUE_FULL:
if (scsi_status == 0) {
res = DID_OK << 16;
break;
}
if (scsi_status & (SS_RESIDUAL_UNDER | SS_RESIDUAL_OVER)) {
if (scsi_status & cpu_to_le16(((uint16_t)SS_RESIDUAL_UNDER
| (uint16_t)SS_RESIDUAL_OVER))) {
resid = resid_len;
scsi_set_resid(cp, resid);
@ -2386,19 +2389,20 @@ qlafx00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
break;
}
}
res = DID_OK << 16 | lscsi_status;
res = DID_OK << 16 | le16_to_cpu(lscsi_status);
if (lscsi_status == SAM_STAT_TASK_SET_FULL) {
if (lscsi_status ==
cpu_to_le16((uint16_t)SAM_STAT_TASK_SET_FULL)) {
ql_dbg(ql_dbg_io, fcport->vha, 0x3051,
"QUEUE FULL detected.\n");
break;
}
logit = 0;
if (lscsi_status != SS_CHECK_CONDITION)
if (lscsi_status != cpu_to_le16((uint16_t)SS_CHECK_CONDITION))
break;
memset(cp->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
if (!(scsi_status & SS_SENSE_LEN_VALID))
if (!(scsi_status & cpu_to_le16((uint16_t)SS_SENSE_LEN_VALID)))
break;
qlafx00_handle_sense(sp, sense_data, par_sense_len, sense_len,
@ -2412,7 +2416,7 @@ qlafx00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
else
resid = resid_len;
scsi_set_resid(cp, resid);
if (scsi_status & SS_RESIDUAL_UNDER) {
if (scsi_status & cpu_to_le16((uint16_t)SS_RESIDUAL_UNDER)) {
if ((IS_FWI2_CAPABLE(ha) || IS_QLAFX00(ha))
&& fw_resid_len != resid_len) {
ql_dbg(ql_dbg_io, fcport->vha, 0x3052,
@ -2420,7 +2424,8 @@ qlafx00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
"(0x%x of 0x%x bytes).\n",
resid, scsi_bufflen(cp));
res = DID_ERROR << 16 | lscsi_status;
res = DID_ERROR << 16 |
le16_to_cpu(lscsi_status);
goto check_scsi_status;
}
@ -2436,8 +2441,9 @@ qlafx00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
res = DID_ERROR << 16;
break;
}
} else if (lscsi_status != SAM_STAT_TASK_SET_FULL &&
lscsi_status != SAM_STAT_BUSY) {
} else if (lscsi_status !=
cpu_to_le16((uint16_t)SAM_STAT_TASK_SET_FULL) &&
lscsi_status != cpu_to_le16((uint16_t)SAM_STAT_BUSY)) {
/*
* scsi status of task set and busy are considered
* to be task not completed.
@ -2448,7 +2454,7 @@ qlafx00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
"of 0x%x bytes).\n", resid,
scsi_bufflen(cp));
res = DID_ERROR << 16 | lscsi_status;
res = DID_ERROR << 16 | le16_to_cpu(lscsi_status);
goto check_scsi_status;
} else {
ql_dbg(ql_dbg_io, fcport->vha, 0x3055,
@ -2456,7 +2462,7 @@ qlafx00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
scsi_status, lscsi_status);
}
res = DID_OK << 16 | lscsi_status;
res = DID_OK << 16 | le16_to_cpu(lscsi_status);
logit = 0;
check_scsi_status:
@ -2465,17 +2471,20 @@ check_scsi_status:
* Status.
*/
if (lscsi_status != 0) {
if (lscsi_status == SAM_STAT_TASK_SET_FULL) {
if (lscsi_status ==
cpu_to_le16((uint16_t)SAM_STAT_TASK_SET_FULL)) {
ql_dbg(ql_dbg_io, fcport->vha, 0x3056,
"QUEUE FULL detected.\n");
logit = 1;
break;
}
if (lscsi_status != SS_CHECK_CONDITION)
if (lscsi_status !=
cpu_to_le16((uint16_t)SS_CHECK_CONDITION))
break;
memset(cp->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
if (!(scsi_status & SS_SENSE_LEN_VALID))
if (!(scsi_status &
cpu_to_le16((uint16_t)SS_SENSE_LEN_VALID)))
break;
qlafx00_handle_sense(sp, sense_data, par_sense_len,
@ -2629,7 +2638,7 @@ qlafx00_multistatus_entry(struct scsi_qla_host *vha,
uint32_t handle, hindex, handle_count, i;
uint16_t que;
struct req_que *req;
uint32_t *handle_ptr;
__le32 *handle_ptr;
stsmfx = (struct multi_sts_entry_fx00 *) pkt;
@ -2643,7 +2652,7 @@ qlafx00_multistatus_entry(struct scsi_qla_host *vha,
return;
}
handle_ptr = (uint32_t *) &stsmfx->handles[0];
handle_ptr = &stsmfx->handles[0];
for (i = 0; i < handle_count; i++) {
hindex = le32_to_cpu(*handle_ptr);
@ -2714,10 +2723,11 @@ qlafx00_process_response_queue(struct scsi_qla_host *vha,
if (!vha->flags.online)
return;
while (RD_REG_DWORD(&(rsp->ring_ptr->signature)) !=
while (RD_REG_DWORD((void __iomem *)&(rsp->ring_ptr->signature)) !=
RESPONSE_PROCESSED) {
lptr = rsp->ring_ptr;
memcpy_fromio(rsp->rsp_pkt, lptr, sizeof(rsp->rsp_pkt));
memcpy_fromio(rsp->rsp_pkt, (void __iomem *)lptr,
sizeof(rsp->rsp_pkt));
pkt = (struct sts_entry_fx00 *)rsp->rsp_pkt;
rsp->ring_index++;
@ -2768,7 +2778,8 @@ qlafx00_process_response_queue(struct scsi_qla_host *vha,
break;
}
next_iter:
WRT_REG_DWORD(&lptr->signature, RESPONSE_PROCESSED);
WRT_REG_DWORD((void __iomem *)&lptr->signature,
RESPONSE_PROCESSED);
wmb();
}
@ -2958,8 +2969,7 @@ qlafx00_prep_cont_type1_iocb(struct req_que *req,
cont_pkt = (cont_a64_entry_t *)req->ring_ptr;
/* Load packet defaults. */
*((uint32_t *)(&lcont_pkt->entry_type)) =
__constant_cpu_to_le32(CONTINUE_A64_TYPE_FX00);
lcont_pkt->entry_type = CONTINUE_A64_TYPE_FX00;
return cont_pkt;
}
@ -2969,7 +2979,7 @@ qlafx00_build_scsi_iocbs(srb_t *sp, struct cmd_type_7_fx00 *cmd_pkt,
uint16_t tot_dsds, struct cmd_type_7_fx00 *lcmd_pkt)
{
uint16_t avail_dsds;
uint32_t *cur_dsd;
__le32 *cur_dsd;
scsi_qla_host_t *vha;
struct scsi_cmnd *cmd;
struct scatterlist *sg;
@ -2986,8 +2996,7 @@ qlafx00_build_scsi_iocbs(srb_t *sp, struct cmd_type_7_fx00 *cmd_pkt,
cont_pkt = NULL;
/* Update entry type to indicate Command Type 3 IOCB */
*((uint32_t *)(&lcmd_pkt->entry_type)) =
__constant_cpu_to_le32(FX00_COMMAND_TYPE_7);
lcmd_pkt->entry_type = FX00_COMMAND_TYPE_7;
/* No data transfer */
if (!scsi_bufflen(cmd) || cmd->sc_data_direction == DMA_NONE) {
@ -3006,7 +3015,7 @@ qlafx00_build_scsi_iocbs(srb_t *sp, struct cmd_type_7_fx00 *cmd_pkt,
/* One DSD is available in the Command Type 3 IOCB */
avail_dsds = 1;
cur_dsd = (uint32_t *)&lcmd_pkt->dseg_0_address;
cur_dsd = (__le32 *)&lcmd_pkt->dseg_0_address;
/* Load data segments */
scsi_for_each_sg(cmd, sg, tot_dsds, i) {
@ -3021,7 +3030,7 @@ qlafx00_build_scsi_iocbs(srb_t *sp, struct cmd_type_7_fx00 *cmd_pkt,
memset(&lcont_pkt, 0, REQUEST_ENTRY_SIZE);
cont_pkt =
qlafx00_prep_cont_type1_iocb(req, &lcont_pkt);
cur_dsd = (uint32_t *)lcont_pkt.dseg_0_address;
cur_dsd = (__le32 *)lcont_pkt.dseg_0_address;
avail_dsds = 5;
cont = 1;
}
@ -3224,13 +3233,13 @@ qlafx00_tm_iocb(srb_t *sp, struct tsk_mgmt_entry_fx00 *ptm_iocb)
tm_iocb.timeout = cpu_to_le16(qla2x00_get_async_timeout(vha) + 2);
tm_iocb.tgt_id = cpu_to_le16(sp->fcport->tgt_id);
tm_iocb.control_flags = cpu_to_le32(fxio->u.tmf.flags);
if (tm_iocb.control_flags == TCF_LUN_RESET) {
if (tm_iocb.control_flags == cpu_to_le32((uint32_t)TCF_LUN_RESET)) {
int_to_scsilun(fxio->u.tmf.lun, &llun);
host_to_adap((uint8_t *)&llun, (uint8_t *)&tm_iocb.lun,
sizeof(struct scsi_lun));
}
memcpy((void __iomem *)ptm_iocb, &tm_iocb,
memcpy((void *)ptm_iocb, &tm_iocb,
sizeof(struct tsk_mgmt_entry_fx00));
wmb();
}
@ -3252,7 +3261,7 @@ qlafx00_abort_iocb(srb_t *sp, struct abort_iocb_entry_fx00 *pabt_iocb)
abt_iocb.tgt_id_sts = cpu_to_le16(sp->fcport->tgt_id);
abt_iocb.req_que_no = cpu_to_le16(req->id);
memcpy((void __iomem *)pabt_iocb, &abt_iocb,
memcpy((void *)pabt_iocb, &abt_iocb,
sizeof(struct abort_iocb_entry_fx00));
wmb();
}
@ -3273,13 +3282,12 @@ qlafx00_fxdisc_iocb(srb_t *sp, struct fxdisc_entry_fx00 *pfxiocb)
if (sp->type == SRB_FXIOCB_DCMD) {
fx_iocb.func_num =
cpu_to_le16(sp->u.iocb_cmd.u.fxiocb.req_func_type);
fx_iocb.adapid = cpu_to_le32(fxio->u.fxiocb.adapter_id);
fx_iocb.adapid_hi = cpu_to_le32(fxio->u.fxiocb.adapter_id_hi);
fx_iocb.reserved_0 = cpu_to_le32(fxio->u.fxiocb.reserved_0);
fx_iocb.reserved_1 = cpu_to_le32(fxio->u.fxiocb.reserved_1);
fx_iocb.dataword_extra =
cpu_to_le32(fxio->u.fxiocb.req_data_extra);
sp->u.iocb_cmd.u.fxiocb.req_func_type;
fx_iocb.adapid = fxio->u.fxiocb.adapter_id;
fx_iocb.adapid_hi = fxio->u.fxiocb.adapter_id_hi;
fx_iocb.reserved_0 = fxio->u.fxiocb.reserved_0;
fx_iocb.reserved_1 = fxio->u.fxiocb.reserved_1;
fx_iocb.dataword_extra = fxio->u.fxiocb.req_data_extra;
if (fxio->u.fxiocb.flags & SRB_FXDISC_REQ_DMA_VALID) {
fx_iocb.req_dsdcnt = cpu_to_le16(1);
@ -3306,8 +3314,7 @@ qlafx00_fxdisc_iocb(srb_t *sp, struct fxdisc_entry_fx00 *pfxiocb)
}
if (fxio->u.fxiocb.flags & SRB_FXDISC_REQ_DWRD_VALID) {
fx_iocb.dataword =
cpu_to_le32(fxio->u.fxiocb.req_data);
fx_iocb.dataword = fxio->u.fxiocb.req_data;
}
fx_iocb.flags = fxio->u.fxiocb.flags;
} else {
@ -3323,21 +3330,21 @@ qlafx00_fxdisc_iocb(srb_t *sp, struct fxdisc_entry_fx00 *pfxiocb)
fx_iocb.reserved_1 = piocb_rqst->reserved_1;
fx_iocb.dataword_extra = piocb_rqst->dataword_extra;
fx_iocb.dataword = piocb_rqst->dataword;
fx_iocb.req_xfrcnt = cpu_to_le16(piocb_rqst->req_len);
fx_iocb.rsp_xfrcnt = cpu_to_le16(piocb_rqst->rsp_len);
fx_iocb.req_xfrcnt = piocb_rqst->req_len;
fx_iocb.rsp_xfrcnt = piocb_rqst->rsp_len;
if (piocb_rqst->flags & SRB_FXDISC_REQ_DMA_VALID) {
int avail_dsds, tot_dsds;
cont_a64_entry_t lcont_pkt;
cont_a64_entry_t *cont_pkt = NULL;
uint32_t *cur_dsd;
__le32 *cur_dsd;
int index = 0, cont = 0;
fx_iocb.req_dsdcnt =
cpu_to_le16(bsg_job->request_payload.sg_cnt);
tot_dsds =
cpu_to_le32(bsg_job->request_payload.sg_cnt);
cur_dsd = (uint32_t *)&fx_iocb.dseg_rq_address[0];
bsg_job->request_payload.sg_cnt;
cur_dsd = (__le32 *)&fx_iocb.dseg_rq_address[0];
avail_dsds = 1;
for_each_sg(bsg_job->request_payload.sg_list, sg,
tot_dsds, index) {
@ -3355,7 +3362,7 @@ qlafx00_fxdisc_iocb(srb_t *sp, struct fxdisc_entry_fx00 *pfxiocb)
qlafx00_prep_cont_type1_iocb(
sp->fcport->vha->req,
&lcont_pkt);
cur_dsd = (uint32_t *)
cur_dsd = (__le32 *)
lcont_pkt.dseg_0_address;
avail_dsds = 5;
cont = 1;
@ -3393,13 +3400,13 @@ qlafx00_fxdisc_iocb(srb_t *sp, struct fxdisc_entry_fx00 *pfxiocb)
int avail_dsds, tot_dsds;
cont_a64_entry_t lcont_pkt;
cont_a64_entry_t *cont_pkt = NULL;
uint32_t *cur_dsd;
__le32 *cur_dsd;
int index = 0, cont = 0;
fx_iocb.rsp_dsdcnt =
cpu_to_le16(bsg_job->reply_payload.sg_cnt);
tot_dsds = cpu_to_le32(bsg_job->reply_payload.sg_cnt);
cur_dsd = (uint32_t *)&fx_iocb.dseg_rsp_address[0];
tot_dsds = bsg_job->reply_payload.sg_cnt;
cur_dsd = (__le32 *)&fx_iocb.dseg_rsp_address[0];
avail_dsds = 1;
for_each_sg(bsg_job->reply_payload.sg_list, sg,
@ -3418,7 +3425,7 @@ qlafx00_fxdisc_iocb(srb_t *sp, struct fxdisc_entry_fx00 *pfxiocb)
qlafx00_prep_cont_type1_iocb(
sp->fcport->vha->req,
&lcont_pkt);
cur_dsd = (uint32_t *)
cur_dsd = (__le32 *)
lcont_pkt.dseg_0_address;
avail_dsds = 5;
cont = 1;
@ -3453,7 +3460,7 @@ qlafx00_fxdisc_iocb(srb_t *sp, struct fxdisc_entry_fx00 *pfxiocb)
}
if (piocb_rqst->flags & SRB_FXDISC_REQ_DWRD_VALID)
fx_iocb.dataword = cpu_to_le32(piocb_rqst->dataword);
fx_iocb.dataword = piocb_rqst->dataword;
fx_iocb.flags = piocb_rqst->flags;
fx_iocb.entry_count = entry_cnt;
}
@ -3462,7 +3469,7 @@ qlafx00_fxdisc_iocb(srb_t *sp, struct fxdisc_entry_fx00 *pfxiocb)
sp->fcport->vha, 0x3047,
(uint8_t *)&fx_iocb, sizeof(struct fxdisc_entry_fx00));
memcpy((void __iomem *)pfxiocb, &fx_iocb,
memcpy((void *)pfxiocb, &fx_iocb,
sizeof(struct fxdisc_entry_fx00));
wmb();
}

View File

@ -24,10 +24,10 @@ struct cmd_type_7_fx00 {
uint32_t handle; /* System handle. */
uint32_t handle_hi;
uint16_t tgt_idx; /* Target Idx. */
__le16 tgt_idx; /* Target Idx. */
uint16_t timeout; /* Command timeout. */
uint16_t dseg_count; /* Data segment count. */
__le16 dseg_count; /* Data segment count. */
uint16_t scsi_rsp_dsd_len;
struct scsi_lun lun; /* LUN (LE). */
@ -41,7 +41,7 @@ struct cmd_type_7_fx00 {
uint8_t crn;
uint8_t fcp_cdb[MAX_CMDSZ]; /* SCSI command words. */
uint32_t byte_count; /* Total byte count. */
__le32 byte_count; /* Total byte count. */
uint32_t dseg_0_address[2]; /* Data segment 0 address. */
uint32_t dseg_0_len; /* Data segment 0 length. */
@ -81,16 +81,16 @@ struct sts_entry_fx00 {
uint32_t handle; /* System handle. */
uint32_t handle_hi; /* System handle. */
uint16_t comp_status; /* Completion status. */
__le16 comp_status; /* Completion status. */
uint16_t reserved_0; /* OX_ID used by the firmware. */
uint32_t residual_len; /* FW calc residual transfer length. */
__le32 residual_len; /* FW calc residual transfer length. */
uint16_t reserved_1;
uint16_t state_flags; /* State flags. */
uint16_t reserved_2;
uint16_t scsi_status; /* SCSI status. */
__le16 scsi_status; /* SCSI status. */
uint32_t sense_len; /* FCP SENSE length. */
uint8_t data[32]; /* FCP response/sense information. */
@ -106,7 +106,7 @@ struct multi_sts_entry_fx00 {
uint8_t handle_count;
uint8_t entry_status;
uint32_t handles[MAX_HANDLE_COUNT];
__le32 handles[MAX_HANDLE_COUNT];
};
#define TSK_MGMT_IOCB_TYPE_FX00 0x05
@ -116,21 +116,21 @@ struct tsk_mgmt_entry_fx00 {
uint8_t sys_define;
uint8_t entry_status; /* Entry Status. */
uint32_t handle; /* System handle. */
__le32 handle; /* System handle. */
uint32_t handle_hi; /* System handle. */
uint16_t tgt_id; /* Target Idx. */
__le16 tgt_id; /* Target Idx. */
uint16_t reserved_1;
uint16_t delay; /* Activity delay in seconds. */
uint16_t timeout; /* Command timeout. */
__le16 timeout; /* Command timeout. */
struct scsi_lun lun; /* LUN (LE). */
uint32_t control_flags; /* Control Flags. */
__le32 control_flags; /* Control Flags. */
uint8_t reserved_2[32];
};
@ -143,16 +143,16 @@ struct abort_iocb_entry_fx00 {
uint8_t sys_define; /* System defined. */
uint8_t entry_status; /* Entry Status. */
uint32_t handle; /* System handle. */
uint32_t handle_hi; /* System handle. */
__le32 handle; /* System handle. */
__le32 handle_hi; /* System handle. */
uint16_t tgt_id_sts; /* Completion status. */
uint16_t options;
__le16 tgt_id_sts; /* Completion status. */
__le16 options;
uint32_t abort_handle; /* System handle. */
uint32_t abort_handle_hi; /* System handle. */
__le32 abort_handle; /* System handle. */
__le32 abort_handle_hi; /* System handle. */
uint16_t req_que_no;
__le16 req_que_no;
uint8_t reserved_1[38];
};
@ -167,17 +167,17 @@ struct ioctl_iocb_entry_fx00 {
uint32_t reserved_0; /* System handle. */
uint16_t comp_func_num;
uint16_t fw_iotcl_flags;
__le16 fw_iotcl_flags;
uint32_t dataword_r; /* Data word returned */
__le32 dataword_r; /* Data word returned */
uint32_t adapid; /* Adapter ID */
uint32_t adapid_hi; /* Adapter ID high */
uint32_t reserved_1;
uint32_t seq_no;
__le32 seq_no;
uint8_t reserved_2[20];
uint32_t residuallen;
uint32_t status;
__le32 status;
};
#define STATUS_CONT_TYPE_FX00 0x04
@ -189,26 +189,26 @@ struct fxdisc_entry_fx00 {
uint8_t sys_define; /* System Defined. */
uint8_t entry_status; /* Entry Status. */
uint32_t handle; /* System handle. */
uint32_t reserved_0; /* System handle. */
__le32 handle; /* System handle. */
__le32 reserved_0; /* System handle. */
uint16_t func_num;
uint16_t req_xfrcnt;
uint16_t req_dsdcnt;
uint16_t rsp_xfrcnt;
uint16_t rsp_dsdcnt;
__le16 func_num;
__le16 req_xfrcnt;
__le16 req_dsdcnt;
__le16 rsp_xfrcnt;
__le16 rsp_dsdcnt;
uint8_t flags;
uint8_t reserved_1;
uint32_t dseg_rq_address[2]; /* Data segment 0 address. */
uint32_t dseg_rq_len; /* Data segment 0 length. */
uint32_t dseg_rsp_address[2]; /* Data segment 1 address. */
uint32_t dseg_rsp_len; /* Data segment 1 length. */
__le32 dseg_rq_address[2]; /* Data segment 0 address. */
__le32 dseg_rq_len; /* Data segment 0 length. */
__le32 dseg_rsp_address[2]; /* Data segment 1 address. */
__le32 dseg_rsp_len; /* Data segment 1 length. */
uint32_t dataword;
uint32_t adapid;
uint32_t adapid_hi;
uint32_t dataword_extra;
__le32 dataword;
__le32 adapid;
__le32 adapid_hi;
__le32 dataword_extra;
};
struct qlafx00_tgt_node_info {
@ -421,43 +421,43 @@ struct config_info_data {
WRT_REG_DWORD((ha)->cregbase + off, val)
struct qla_mt_iocb_rqst_fx00 {
uint32_t reserved_0;
__le32 reserved_0;
uint16_t func_type;
__le16 func_type;
uint8_t flags;
uint8_t reserved_1;
uint32_t dataword;
__le32 dataword;
uint32_t adapid;
uint32_t adapid_hi;
__le32 adapid;
__le32 adapid_hi;
uint32_t dataword_extra;
__le32 dataword_extra;
uint32_t req_len;
__le32 req_len;
uint32_t rsp_len;
__le32 rsp_len;
};
struct qla_mt_iocb_rsp_fx00 {
uint32_t reserved_1;
uint16_t func_type;
uint16_t ioctl_flags;
__le16 ioctl_flags;
uint32_t ioctl_data;
__le32 ioctl_data;
uint32_t adapid;
uint32_t adapid_hi;
uint32_t reserved_2;
uint32_t seq_number;
__le32 seq_number;
uint8_t reserved_3[20];
int32_t res_count;
uint32_t status;
__le32 status;
};

View File

@ -104,8 +104,6 @@ MODULE_PARM_DESC(ql2xshiftctondsd,
"Set to control shifting of command type processing "
"based on total number of SG elements.");
static void qla2x00_free_device(scsi_qla_host_t *);
int ql2xfdmienable=1;
module_param(ql2xfdmienable, int, S_IRUGO);
MODULE_PARM_DESC(ql2xfdmienable,
@ -237,6 +235,7 @@ static int qla2xxx_eh_host_reset(struct scsi_cmnd *);
static int qla2x00_change_queue_depth(struct scsi_device *, int, int);
static int qla2x00_change_queue_type(struct scsi_device *, int);
static void qla2x00_free_device(scsi_qla_host_t *);
struct scsi_host_template qla2xxx_driver_template = {
.module = THIS_MODULE,
@ -2840,8 +2839,7 @@ skip_dpc:
qla2x00_dfs_setup(base_vha);
ql_log(ql_log_info, base_vha, 0x00fb,
"QLogic %s - %s.\n",
ha->model_number, ha->model_desc ? ha->model_desc : "");
"QLogic %s - %s.\n", ha->model_number, ha->model_desc);
ql_log(ql_log_info, base_vha, 0x00fc,
"ISP%04X: %s @ %s hdma%c host#=%ld fw=%s.\n",
pdev->device, ha->isp_ops->pci_info_str(base_vha, pci_info),
@ -2981,14 +2979,12 @@ qla2x00_remove_one(struct pci_dev *pdev)
set_bit(UNLOADING, &base_vha->dpc_flags);
mutex_lock(&ha->vport_lock);
while (ha->cur_vport_count) {
struct Scsi_Host *scsi_host;
spin_lock_irqsave(&ha->vport_slock, flags);
BUG_ON(base_vha->list.next == &ha->vp_list);
/* This assumes first entry in ha->vp_list is always base vha */
vha = list_first_entry(&base_vha->list, scsi_qla_host_t, list);
scsi_host = scsi_host_get(vha->host);
scsi_host_get(vha->host);
spin_unlock_irqrestore(&ha->vport_slock, flags);
mutex_unlock(&ha->vport_lock);

View File

@ -258,7 +258,7 @@ struct sdebug_queued_cmd {
static struct sdebug_queued_cmd queued_arr[SCSI_DEBUG_CANQUEUE];
static unsigned char * fake_storep; /* ramdisk storage */
static unsigned char *dif_storep; /* protection info */
static struct sd_dif_tuple *dif_storep; /* protection info */
static void *map_storep; /* provisioning map */
static unsigned long map_size;
@ -277,11 +277,6 @@ static char sdebug_proc_name[] = "scsi_debug";
static struct bus_type pseudo_lld_bus;
static inline sector_t dif_offset(sector_t sector)
{
return sector << 3;
}
static struct device_driver sdebug_driverfs_driver = {
.name = sdebug_proc_name,
.bus = &pseudo_lld_bus,
@ -1736,6 +1731,50 @@ static int do_device_access(struct scsi_cmnd *scmd,
return ret;
}
static u16 dif_compute_csum(const void *buf, int len)
{
u16 csum;
switch (scsi_debug_guard) {
case 1:
csum = ip_compute_csum(buf, len);
break;
case 0:
csum = cpu_to_be16(crc_t10dif(buf, len));
break;
}
return csum;
}
static int dif_verify(struct sd_dif_tuple *sdt, const void *data,
sector_t sector, u32 ei_lba)
{
u16 csum = dif_compute_csum(data, scsi_debug_sector_size);
if (sdt->guard_tag != csum) {
pr_err("%s: GUARD check failed on sector %lu rcvd 0x%04x, data 0x%04x\n",
__func__,
(unsigned long)sector,
be16_to_cpu(sdt->guard_tag),
be16_to_cpu(csum));
return 0x01;
}
if (scsi_debug_dif == SD_DIF_TYPE1_PROTECTION &&
be32_to_cpu(sdt->ref_tag) != (sector & 0xffffffff)) {
pr_err("%s: REF check failed on sector %lu\n",
__func__, (unsigned long)sector);
return 0x03;
}
if (scsi_debug_dif == SD_DIF_TYPE2_PROTECTION &&
be32_to_cpu(sdt->ref_tag) != ei_lba) {
pr_err("%s: REF check failed on sector %lu\n",
__func__, (unsigned long)sector);
dif_errors++;
return 0x03;
}
return 0;
}
static int prot_verify_read(struct scsi_cmnd *SCpnt, sector_t start_sec,
unsigned int sectors, u32 ei_lba)
{
@ -1748,71 +1787,38 @@ static int prot_verify_read(struct scsi_cmnd *SCpnt, sector_t start_sec,
start_sec = do_div(tmp_sec, sdebug_store_sectors);
sdt = (struct sd_dif_tuple *)(dif_storep + dif_offset(start_sec));
sdt = dif_storep + start_sec;
for (i = 0 ; i < sectors ; i++) {
u16 csum;
int ret;
if (sdt[i].app_tag == 0xffff)
continue;
sector = start_sec + i;
switch (scsi_debug_guard) {
case 1:
csum = ip_compute_csum(fake_storep +
sector * scsi_debug_sector_size,
scsi_debug_sector_size);
break;
case 0:
csum = crc_t10dif(fake_storep +
sector * scsi_debug_sector_size,
scsi_debug_sector_size);
csum = cpu_to_be16(csum);
break;
default:
BUG();
}
if (sdt[i].guard_tag != csum) {
printk(KERN_ERR "%s: GUARD check failed on sector %lu" \
" rcvd 0x%04x, data 0x%04x\n", __func__,
(unsigned long)sector,
be16_to_cpu(sdt[i].guard_tag),
be16_to_cpu(csum));
ret = dif_verify(&sdt[i],
fake_storep + sector * scsi_debug_sector_size,
sector, ei_lba);
if (ret) {
dif_errors++;
return 0x01;
}
if (scsi_debug_dif == SD_DIF_TYPE1_PROTECTION &&
be32_to_cpu(sdt[i].ref_tag) != (sector & 0xffffffff)) {
printk(KERN_ERR "%s: REF check failed on sector %lu\n",
__func__, (unsigned long)sector);
dif_errors++;
return 0x03;
}
if (scsi_debug_dif == SD_DIF_TYPE2_PROTECTION &&
be32_to_cpu(sdt[i].ref_tag) != ei_lba) {
printk(KERN_ERR "%s: REF check failed on sector %lu\n",
__func__, (unsigned long)sector);
dif_errors++;
return 0x03;
return ret;
}
ei_lba++;
}
resid = sectors * 8; /* Bytes of protection data to copy into sgl */
/* Bytes of protection data to copy into sgl */
resid = sectors * sizeof(*dif_storep);
sector = start_sec;
scsi_for_each_prot_sg(SCpnt, psgl, scsi_prot_sg_count(SCpnt), i) {
int len = min(psgl->length, resid);
paddr = kmap_atomic(sg_page(psgl)) + psgl->offset;
memcpy(paddr, dif_storep + dif_offset(sector), len);
memcpy(paddr, dif_storep + sector, len);
sector += len >> 3;
sector += len / sizeof(*dif_storep);
if (sector >= sdebug_store_sectors) {
/* Force wrap */
tmp_sec = sector;
@ -1910,22 +1916,21 @@ static int prot_verify_write(struct scsi_cmnd *SCpnt, sector_t start_sec,
sector_t tmp_sec = start_sec;
sector_t sector;
int ppage_offset;
unsigned short csum;
sector = do_div(tmp_sec, sdebug_store_sectors);
BUG_ON(scsi_sg_count(SCpnt) == 0);
BUG_ON(scsi_prot_sg_count(SCpnt) == 0);
paddr = kmap_atomic(sg_page(psgl)) + psgl->offset;
ppage_offset = 0;
/* For each data page */
scsi_for_each_sg(SCpnt, dsgl, scsi_sg_count(SCpnt), i) {
daddr = kmap_atomic(sg_page(dsgl)) + dsgl->offset;
paddr = kmap_atomic(sg_page(psgl)) + psgl->offset;
/* For each sector-sized chunk in data page */
for (j = 0 ; j < dsgl->length ; j += scsi_debug_sector_size) {
for (j = 0; j < dsgl->length; j += scsi_debug_sector_size) {
/* If we're at the end of the current
* protection page advance to the next one
@ -1941,51 +1946,9 @@ static int prot_verify_write(struct scsi_cmnd *SCpnt, sector_t start_sec,
sdt = paddr + ppage_offset;
switch (scsi_debug_guard) {
case 1:
csum = ip_compute_csum(daddr,
scsi_debug_sector_size);
break;
case 0:
csum = cpu_to_be16(crc_t10dif(daddr,
scsi_debug_sector_size));
break;
default:
BUG();
ret = 0;
goto out;
}
if (sdt->guard_tag != csum) {
printk(KERN_ERR
"%s: GUARD check failed on sector %lu " \
"rcvd 0x%04x, calculated 0x%04x\n",
__func__, (unsigned long)sector,
be16_to_cpu(sdt->guard_tag),
be16_to_cpu(csum));
ret = 0x01;
dump_sector(daddr, scsi_debug_sector_size);
goto out;
}
if (scsi_debug_dif == SD_DIF_TYPE1_PROTECTION &&
be32_to_cpu(sdt->ref_tag)
!= (start_sec & 0xffffffff)) {
printk(KERN_ERR
"%s: REF check failed on sector %lu\n",
__func__, (unsigned long)sector);
ret = 0x03;
dump_sector(daddr, scsi_debug_sector_size);
goto out;
}
if (scsi_debug_dif == SD_DIF_TYPE2_PROTECTION &&
be32_to_cpu(sdt->ref_tag) != ei_lba) {
printk(KERN_ERR
"%s: REF check failed on sector %lu\n",
__func__, (unsigned long)sector);
ret = 0x03;
dump_sector(daddr, scsi_debug_sector_size);
ret = dif_verify(sdt, daddr + j, start_sec, ei_lba);
if (ret) {
dump_sector(daddr + j, scsi_debug_sector_size);
goto out;
}
@ -1994,7 +1957,7 @@ static int prot_verify_write(struct scsi_cmnd *SCpnt, sector_t start_sec,
* correctness we need to verify each sector
* before writing it to "stable" storage
*/
memcpy(dif_storep + dif_offset(sector), sdt, 8);
memcpy(dif_storep + sector, sdt, sizeof(*sdt));
sector++;
@ -2003,23 +1966,21 @@ static int prot_verify_write(struct scsi_cmnd *SCpnt, sector_t start_sec,
start_sec++;
ei_lba++;
daddr += scsi_debug_sector_size;
ppage_offset += sizeof(struct sd_dif_tuple);
}
kunmap_atomic(paddr);
kunmap_atomic(daddr);
}
kunmap_atomic(paddr);
dix_writes++;
return 0;
out:
dif_errors++;
kunmap_atomic(daddr);
kunmap_atomic(paddr);
kunmap_atomic(daddr);
return ret;
}
@ -2092,6 +2053,11 @@ static void unmap_region(sector_t lba, unsigned int len)
scsi_debug_sector_size *
scsi_debug_unmap_granularity);
}
if (dif_storep) {
memset(dif_storep + lba, 0xff,
sizeof(*dif_storep) *
scsi_debug_unmap_granularity);
}
}
lba = map_index_to_lba(index + 1);
}
@ -3400,7 +3366,7 @@ static int __init scsi_debug_init(void)
if (scsi_debug_num_parts > 0)
sdebug_build_parts(fake_storep, sz);
if (scsi_debug_dif) {
if (scsi_debug_dix) {
int dif_size;
dif_size = sdebug_store_sectors * sizeof(struct sd_dif_tuple);

View File

@ -434,6 +434,8 @@ static void scsi_run_queue(struct request_queue *q)
list_splice_init(&shost->starved_list, &starved_list);
while (!list_empty(&starved_list)) {
struct request_queue *slq;
/*
* As long as shost is accepting commands and we have
* starved queues, call blk_run_queue. scsi_request_fn
@ -456,11 +458,25 @@ static void scsi_run_queue(struct request_queue *q)
continue;
}
spin_unlock(shost->host_lock);
spin_lock(sdev->request_queue->queue_lock);
__blk_run_queue(sdev->request_queue);
spin_unlock(sdev->request_queue->queue_lock);
spin_lock(shost->host_lock);
/*
* Once we drop the host lock, a racing scsi_remove_device()
* call may remove the sdev from the starved list and destroy
* it and the queue. Mitigate by taking a reference to the
* queue and never touching the sdev again after we drop the
* host lock. Note: if __scsi_remove_device() invokes
* blk_cleanup_queue() before the queue is run from this
* function then blk_run_queue() will return immediately since
* blk_cleanup_queue() marks the queue with QUEUE_FLAG_DYING.
*/
slq = sdev->request_queue;
if (!blk_get_queue(slq))
continue;
spin_unlock_irqrestore(shost->host_lock, flags);
blk_run_queue(slq);
blk_put_queue(slq);
spin_lock_irqsave(shost->host_lock, flags);
}
/* put any unprocessed entries back */
list_splice(&starved_list, &shost->starved_list);
@ -2177,6 +2193,7 @@ scsi_device_set_state(struct scsi_device *sdev, enum scsi_device_state state)
case SDEV_OFFLINE:
case SDEV_TRANSPORT_OFFLINE:
case SDEV_CANCEL:
case SDEV_CREATED_BLOCK:
break;
default:
goto illegal;

View File

@ -326,7 +326,9 @@ MODULE_PARM_DESC(storvsc_ringbuffer_size, "Ring buffer size (bytes)");
*/
static int storvsc_timeout = 180;
#define STORVSC_MAX_IO_REQUESTS 128
#define STORVSC_MAX_IO_REQUESTS 200
static void storvsc_on_channel_callback(void *context);
/*
* In Hyper-V, each port/path/target maps to 1 scsi host adapter. In
@ -364,6 +366,7 @@ struct storvsc_device {
bool destroy;
bool drain_notify;
bool open_sub_channel;
atomic_t num_outstanding_req;
struct Scsi_Host *host;
@ -755,12 +758,104 @@ static unsigned int copy_to_bounce_buffer(struct scatterlist *orig_sgl,
return total_copied;
}
static void handle_sc_creation(struct vmbus_channel *new_sc)
{
struct hv_device *device = new_sc->primary_channel->device_obj;
struct storvsc_device *stor_device;
struct vmstorage_channel_properties props;
stor_device = get_out_stor_device(device);
if (!stor_device)
return;
if (stor_device->open_sub_channel == false)
return;
memset(&props, 0, sizeof(struct vmstorage_channel_properties));
vmbus_open(new_sc,
storvsc_ringbuffer_size,
storvsc_ringbuffer_size,
(void *)&props,
sizeof(struct vmstorage_channel_properties),
storvsc_on_channel_callback, new_sc);
}
static void handle_multichannel_storage(struct hv_device *device, int max_chns)
{
struct storvsc_device *stor_device;
int num_cpus = num_online_cpus();
int num_sc;
struct storvsc_cmd_request *request;
struct vstor_packet *vstor_packet;
int ret, t;
num_sc = ((max_chns > num_cpus) ? num_cpus : max_chns);
stor_device = get_out_stor_device(device);
if (!stor_device)
return;
request = &stor_device->init_request;
vstor_packet = &request->vstor_packet;
stor_device->open_sub_channel = true;
/*
* Establish a handler for dealing with subchannels.
*/
vmbus_set_sc_create_callback(device->channel, handle_sc_creation);
/*
* Check to see if sub-channels have already been created. This
* can happen when this driver is re-loaded after unloading.
*/
if (vmbus_are_subchannels_present(device->channel))
return;
stor_device->open_sub_channel = false;
/*
* Request the host to create sub-channels.
*/
memset(request, 0, sizeof(struct storvsc_cmd_request));
init_completion(&request->wait_event);
vstor_packet->operation = VSTOR_OPERATION_CREATE_SUB_CHANNELS;
vstor_packet->flags = REQUEST_COMPLETION_FLAG;
vstor_packet->sub_channel_count = num_sc;
ret = vmbus_sendpacket(device->channel, vstor_packet,
(sizeof(struct vstor_packet) -
vmscsi_size_delta),
(unsigned long)request,
VM_PKT_DATA_INBAND,
VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
if (ret != 0)
return;
t = wait_for_completion_timeout(&request->wait_event, 10*HZ);
if (t == 0)
return;
if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO ||
vstor_packet->status != 0)
return;
/*
* Now that we created the sub-channels, invoke the check; this
* may trigger the callback.
*/
stor_device->open_sub_channel = true;
vmbus_are_subchannels_present(device->channel);
}
static int storvsc_channel_init(struct hv_device *device)
{
struct storvsc_device *stor_device;
struct storvsc_cmd_request *request;
struct vstor_packet *vstor_packet;
int ret, t;
int max_chns;
bool process_sub_channels = false;
stor_device = get_out_stor_device(device);
if (!stor_device)
@ -855,6 +950,19 @@ static int storvsc_channel_init(struct hv_device *device)
vstor_packet->status != 0)
goto cleanup;
/*
* Check to see if multi-channel support is there.
* Hosts that implement protocol version of 5.1 and above
* support multi-channel.
*/
max_chns = vstor_packet->storage_channel_properties.max_channel_cnt;
if ((vmbus_proto_version != VERSION_WIN7) &&
(vmbus_proto_version != VERSION_WS2008)) {
if (vstor_packet->storage_channel_properties.flags &
STORAGE_CHANNEL_SUPPORTS_MULTI_CHANNEL)
process_sub_channels = true;
}
memset(vstor_packet, 0, sizeof(struct vstor_packet));
vstor_packet->operation = VSTOR_OPERATION_END_INITIALIZATION;
vstor_packet->flags = REQUEST_COMPLETION_FLAG;
@ -879,6 +987,9 @@ static int storvsc_channel_init(struct hv_device *device)
vstor_packet->status != 0)
goto cleanup;
if (process_sub_channels)
handle_multichannel_storage(device, max_chns);
cleanup:
return ret;
@ -1100,7 +1211,8 @@ static void storvsc_on_receive(struct hv_device *device,
static void storvsc_on_channel_callback(void *context)
{
struct hv_device *device = (struct hv_device *)context;
struct vmbus_channel *channel = (struct vmbus_channel *)context;
struct hv_device *device;
struct storvsc_device *stor_device;
u32 bytes_recvd;
u64 request_id;
@ -1108,13 +1220,17 @@ static void storvsc_on_channel_callback(void *context)
struct storvsc_cmd_request *request;
int ret;
if (channel->primary_channel != NULL)
device = channel->primary_channel->device_obj;
else
device = channel->device_obj;
stor_device = get_in_stor_device(device);
if (!stor_device)
return;
do {
ret = vmbus_recvpacket(device->channel, packet,
ret = vmbus_recvpacket(channel, packet,
ALIGN((sizeof(struct vstor_packet) -
vmscsi_size_delta), 8),
&bytes_recvd, &request_id);
@ -1155,7 +1271,7 @@ static int storvsc_connect_to_vsp(struct hv_device *device, u32 ring_size)
ring_size,
(void *)&props,
sizeof(struct vmstorage_channel_properties),
storvsc_on_channel_callback, device);
storvsc_on_channel_callback, device->channel);
if (ret != 0)
return ret;
@ -1207,6 +1323,7 @@ static int storvsc_do_io(struct hv_device *device,
{
struct storvsc_device *stor_device;
struct vstor_packet *vstor_packet;
struct vmbus_channel *outgoing_channel;
int ret = 0;
vstor_packet = &request->vstor_packet;
@ -1217,6 +1334,11 @@ static int storvsc_do_io(struct hv_device *device,
request->device = device;
/*
* Select an an appropriate channel to send the request out.
*/
outgoing_channel = vmbus_get_outgoing_channel(device->channel);
vstor_packet->flags |= REQUEST_COMPLETION_FLAG;
@ -1234,7 +1356,7 @@ static int storvsc_do_io(struct hv_device *device,
vstor_packet->operation = VSTOR_OPERATION_EXECUTE_SRB;
if (request->data_buffer.len) {
ret = vmbus_sendpacket_multipagebuffer(device->channel,
ret = vmbus_sendpacket_multipagebuffer(outgoing_channel,
&request->data_buffer,
vstor_packet,
(sizeof(struct vstor_packet) -
@ -1580,6 +1702,7 @@ static struct scsi_host_template scsi_driver = {
enum {
SCSI_GUID,
IDE_GUID,
SFC_GUID,
};
static const struct hv_vmbus_device_id id_table[] = {
@ -1591,6 +1714,11 @@ static const struct hv_vmbus_device_id id_table[] = {
{ HV_IDE_GUID,
.driver_data = IDE_GUID
},
/* Fibre Channel GUID */
{
HV_SYNTHFC_GUID,
.driver_data = SFC_GUID
},
{ },
};
@ -1643,6 +1771,7 @@ static int storvsc_probe(struct hv_device *device,
}
stor_device->destroy = false;
stor_device->open_sub_channel = false;
init_waitqueue_head(&stor_device->waiting_to_drain);
stor_device->device = device;
stor_device->host = host;