PageRenderTime 115ms CodeModel.GetById 6ms app.highlight 88ms RepoModel.GetById 2ms app.codeStats 1ms

/linux-2.6.21.x/drivers/scsi/ipr.c

https://bitbucket.org/altlc/wive-rtnl-ralink-rt305x-routers-firmware-amod
C | 7617 lines | 4767 code | 1002 blank | 1848 comment | 609 complexity | 01c35d6800260896eda7cec5504a6dec MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1/*
   2 * ipr.c -- driver for IBM Power Linux RAID adapters
   3 *
   4 * Written By: Brian King <brking@us.ibm.com>, IBM Corporation
   5 *
   6 * Copyright (C) 2003, 2004 IBM Corporation
   7 *
   8 * This program is free software; you can redistribute it and/or modify
   9 * it under the terms of the GNU General Public License as published by
  10 * the Free Software Foundation; either version 2 of the License, or
  11 * (at your option) any later version.
  12 *
  13 * This program is distributed in the hope that it will be useful,
  14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16 * GNU General Public License for more details.
  17 *
  18 * You should have received a copy of the GNU General Public License
  19 * along with this program; if not, write to the Free Software
  20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  21 *
  22 */
  23
  24/*
  25 * Notes:
  26 *
  27 * This driver is used to control the following SCSI adapters:
  28 *
  29 * IBM iSeries: 5702, 5703, 2780, 5709, 570A, 570B
  30 *
  31 * IBM pSeries: PCI-X Dual Channel Ultra 320 SCSI RAID Adapter
  32 *              PCI-X Dual Channel Ultra 320 SCSI Adapter
  33 *              PCI-X Dual Channel Ultra 320 SCSI RAID Enablement Card
  34 *              Embedded SCSI adapter on p615 and p655 systems
  35 *
  36 * Supported Hardware Features:
  37 *	- Ultra 320 SCSI controller
  38 *	- PCI-X host interface
  39 *	- Embedded PowerPC RISC Processor and Hardware XOR DMA Engine
  40 *	- Non-Volatile Write Cache
  41 *	- Supports attachment of non-RAID disks, tape, and optical devices
  42 *	- RAID Levels 0, 5, 10
  43 *	- Hot spare
  44 *	- Background Parity Checking
  45 *	- Background Data Scrubbing
  46 *	- Ability to increase the capacity of an existing RAID 5 disk array
  47 *		by adding disks
  48 *
  49 * Driver Features:
  50 *	- Tagged command queuing
  51 *	- Adapter microcode download
  52 *	- PCI hot plug
  53 *	- SCSI device hot plug
  54 *
  55 */
  56
  57#include <linux/fs.h>
  58#include <linux/init.h>
  59#include <linux/types.h>
  60#include <linux/errno.h>
  61#include <linux/kernel.h>
  62#include <linux/ioport.h>
  63#include <linux/delay.h>
  64#include <linux/pci.h>
  65#include <linux/wait.h>
  66#include <linux/spinlock.h>
  67#include <linux/sched.h>
  68#include <linux/interrupt.h>
  69#include <linux/blkdev.h>
  70#include <linux/firmware.h>
  71#include <linux/module.h>
  72#include <linux/moduleparam.h>
  73#include <linux/libata.h>
  74#include <asm/io.h>
  75#include <asm/irq.h>
  76#include <asm/processor.h>
  77#include <scsi/scsi.h>
  78#include <scsi/scsi_host.h>
  79#include <scsi/scsi_tcq.h>
  80#include <scsi/scsi_eh.h>
  81#include <scsi/scsi_cmnd.h>
  82#include "ipr.h"
  83
  84/*
  85 *   Global Data
  86 */
  87static struct list_head ipr_ioa_head = LIST_HEAD_INIT(ipr_ioa_head);
  88static unsigned int ipr_log_level = IPR_DEFAULT_LOG_LEVEL;
  89static unsigned int ipr_max_speed = 1;
  90static int ipr_testmode = 0;
  91static unsigned int ipr_fastfail = 0;
  92static unsigned int ipr_transop_timeout = IPR_OPERATIONAL_TIMEOUT;
  93static unsigned int ipr_enable_cache = 1;
  94static unsigned int ipr_debug = 0;
  95static int ipr_auto_create = 1;
  96static DEFINE_SPINLOCK(ipr_driver_lock);
  97
  98/* This table describes the differences between DMA controller chips */
  99static const struct ipr_chip_cfg_t ipr_chip_cfg[] = {
 100	{ /* Gemstone, Citrine, Obsidian, and Obsidian-E */
 101		.mailbox = 0x0042C,
 102		.cache_line_size = 0x20,
 103		{
 104			.set_interrupt_mask_reg = 0x0022C,
 105			.clr_interrupt_mask_reg = 0x00230,
 106			.sense_interrupt_mask_reg = 0x0022C,
 107			.clr_interrupt_reg = 0x00228,
 108			.sense_interrupt_reg = 0x00224,
 109			.ioarrin_reg = 0x00404,
 110			.sense_uproc_interrupt_reg = 0x00214,
 111			.set_uproc_interrupt_reg = 0x00214,
 112			.clr_uproc_interrupt_reg = 0x00218
 113		}
 114	},
 115	{ /* Snipe and Scamp */
 116		.mailbox = 0x0052C,
 117		.cache_line_size = 0x20,
 118		{
 119			.set_interrupt_mask_reg = 0x00288,
 120			.clr_interrupt_mask_reg = 0x0028C,
 121			.sense_interrupt_mask_reg = 0x00288,
 122			.clr_interrupt_reg = 0x00284,
 123			.sense_interrupt_reg = 0x00280,
 124			.ioarrin_reg = 0x00504,
 125			.sense_uproc_interrupt_reg = 0x00290,
 126			.set_uproc_interrupt_reg = 0x00290,
 127			.clr_uproc_interrupt_reg = 0x00294
 128		}
 129	},
 130};
 131
 132static const struct ipr_chip_t ipr_chip[] = {
 133	{ PCI_VENDOR_ID_MYLEX, PCI_DEVICE_ID_IBM_GEMSTONE, &ipr_chip_cfg[0] },
 134	{ PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CITRINE, &ipr_chip_cfg[0] },
 135	{ PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_OBSIDIAN, &ipr_chip_cfg[0] },
 136	{ PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN, &ipr_chip_cfg[0] },
 137	{ PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E, &ipr_chip_cfg[0] },
 138	{ PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_SNIPE, &ipr_chip_cfg[1] },
 139	{ PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_SCAMP, &ipr_chip_cfg[1] }
 140};
 141
 142static int ipr_max_bus_speeds [] = {
 143	IPR_80MBs_SCSI_RATE, IPR_U160_SCSI_RATE, IPR_U320_SCSI_RATE
 144};
 145
 146MODULE_AUTHOR("Brian King <brking@us.ibm.com>");
 147MODULE_DESCRIPTION("IBM Power RAID SCSI Adapter Driver");
 148module_param_named(max_speed, ipr_max_speed, uint, 0);
 149MODULE_PARM_DESC(max_speed, "Maximum bus speed (0-2). Default: 1=U160. Speeds: 0=80 MB/s, 1=U160, 2=U320");
 150module_param_named(log_level, ipr_log_level, uint, 0);
 151MODULE_PARM_DESC(log_level, "Set to 0 - 4 for increasing verbosity of device driver");
 152module_param_named(testmode, ipr_testmode, int, 0);
 153MODULE_PARM_DESC(testmode, "DANGEROUS!!! Allows unsupported configurations");
 154module_param_named(fastfail, ipr_fastfail, int, 0);
 155MODULE_PARM_DESC(fastfail, "Reduce timeouts and retries");
 156module_param_named(transop_timeout, ipr_transop_timeout, int, 0);
 157MODULE_PARM_DESC(transop_timeout, "Time in seconds to wait for adapter to come operational (default: 300)");
 158module_param_named(enable_cache, ipr_enable_cache, int, 0);
 159MODULE_PARM_DESC(enable_cache, "Enable adapter's non-volatile write cache (default: 1)");
 160module_param_named(debug, ipr_debug, int, 0);
 161MODULE_PARM_DESC(debug, "Enable device driver debugging logging. Set to 1 to enable. (default: 0)");
 162module_param_named(auto_create, ipr_auto_create, int, 0);
 163MODULE_PARM_DESC(auto_create, "Auto-create single device RAID 0 arrays when initialized (default: 1)");
 164MODULE_LICENSE("GPL");
 165MODULE_VERSION(IPR_DRIVER_VERSION);
 166
 167/*  A constant array of IOASCs/URCs/Error Messages */
 168static const
 169struct ipr_error_table_t ipr_error_table[] = {
 170	{0x00000000, 1, 1,
 171	"8155: An unknown error was received"},
 172	{0x00330000, 0, 0,
 173	"Soft underlength error"},
 174	{0x005A0000, 0, 0,
 175	"Command to be cancelled not found"},
 176	{0x00808000, 0, 0,
 177	"Qualified success"},
 178	{0x01080000, 1, 1,
 179	"FFFE: Soft device bus error recovered by the IOA"},
 180	{0x01088100, 0, 1,
 181	"4101: Soft device bus fabric error"},
 182	{0x01170600, 0, 1,
 183	"FFF9: Device sector reassign successful"},
 184	{0x01170900, 0, 1,
 185	"FFF7: Media error recovered by device rewrite procedures"},
 186	{0x01180200, 0, 1,
 187	"7001: IOA sector reassignment successful"},
 188	{0x01180500, 0, 1,
 189	"FFF9: Soft media error. Sector reassignment recommended"},
 190	{0x01180600, 0, 1,
 191	"FFF7: Media error recovered by IOA rewrite procedures"},
 192	{0x01418000, 0, 1,
 193	"FF3D: Soft PCI bus error recovered by the IOA"},
 194	{0x01440000, 1, 1,
 195	"FFF6: Device hardware error recovered by the IOA"},
 196	{0x01448100, 0, 1,
 197	"FFF6: Device hardware error recovered by the device"},
 198	{0x01448200, 1, 1,
 199	"FF3D: Soft IOA error recovered by the IOA"},
 200	{0x01448300, 0, 1,
 201	"FFFA: Undefined device response recovered by the IOA"},
 202	{0x014A0000, 1, 1,
 203	"FFF6: Device bus error, message or command phase"},
 204	{0x014A8000, 0, 1,
 205	"FFFE: Task Management Function failed"},
 206	{0x015D0000, 0, 1,
 207	"FFF6: Failure prediction threshold exceeded"},
 208	{0x015D9200, 0, 1,
 209	"8009: Impending cache battery pack failure"},
 210	{0x02040400, 0, 0,
 211	"34FF: Disk device format in progress"},
 212	{0x023F0000, 0, 0,
 213	"Synchronization required"},
 214	{0x024E0000, 0, 0,
 215	"No ready, IOA shutdown"},
 216	{0x025A0000, 0, 0,
 217	"Not ready, IOA has been shutdown"},
 218	{0x02670100, 0, 1,
 219	"3020: Storage subsystem configuration error"},
 220	{0x03110B00, 0, 0,
 221	"FFF5: Medium error, data unreadable, recommend reassign"},
 222	{0x03110C00, 0, 0,
 223	"7000: Medium error, data unreadable, do not reassign"},
 224	{0x03310000, 0, 1,
 225	"FFF3: Disk media format bad"},
 226	{0x04050000, 0, 1,
 227	"3002: Addressed device failed to respond to selection"},
 228	{0x04080000, 1, 1,
 229	"3100: Device bus error"},
 230	{0x04080100, 0, 1,
 231	"3109: IOA timed out a device command"},
 232	{0x04088000, 0, 0,
 233	"3120: SCSI bus is not operational"},
 234	{0x04088100, 0, 1,
 235	"4100: Hard device bus fabric error"},
 236	{0x04118000, 0, 1,
 237	"9000: IOA reserved area data check"},
 238	{0x04118100, 0, 1,
 239	"9001: IOA reserved area invalid data pattern"},
 240	{0x04118200, 0, 1,
 241	"9002: IOA reserved area LRC error"},
 242	{0x04320000, 0, 1,
 243	"102E: Out of alternate sectors for disk storage"},
 244	{0x04330000, 1, 1,
 245	"FFF4: Data transfer underlength error"},
 246	{0x04338000, 1, 1,
 247	"FFF4: Data transfer overlength error"},
 248	{0x043E0100, 0, 1,
 249	"3400: Logical unit failure"},
 250	{0x04408500, 0, 1,
 251	"FFF4: Device microcode is corrupt"},
 252	{0x04418000, 1, 1,
 253	"8150: PCI bus error"},
 254	{0x04430000, 1, 0,
 255	"Unsupported device bus message received"},
 256	{0x04440000, 1, 1,
 257	"FFF4: Disk device problem"},
 258	{0x04448200, 1, 1,
 259	"8150: Permanent IOA failure"},
 260	{0x04448300, 0, 1,
 261	"3010: Disk device returned wrong response to IOA"},
 262	{0x04448400, 0, 1,
 263	"8151: IOA microcode error"},
 264	{0x04448500, 0, 0,
 265	"Device bus status error"},
 266	{0x04448600, 0, 1,
 267	"8157: IOA error requiring IOA reset to recover"},
 268	{0x04448700, 0, 0,
 269	"ATA device status error"},
 270	{0x04490000, 0, 0,
 271	"Message reject received from the device"},
 272	{0x04449200, 0, 1,
 273	"8008: A permanent cache battery pack failure occurred"},
 274	{0x0444A000, 0, 1,
 275	"9090: Disk unit has been modified after the last known status"},
 276	{0x0444A200, 0, 1,
 277	"9081: IOA detected device error"},
 278	{0x0444A300, 0, 1,
 279	"9082: IOA detected device error"},
 280	{0x044A0000, 1, 1,
 281	"3110: Device bus error, message or command phase"},
 282	{0x044A8000, 1, 1,
 283	"3110: SAS Command / Task Management Function failed"},
 284	{0x04670400, 0, 1,
 285	"9091: Incorrect hardware configuration change has been detected"},
 286	{0x04678000, 0, 1,
 287	"9073: Invalid multi-adapter configuration"},
 288	{0x04678100, 0, 1,
 289	"4010: Incorrect connection between cascaded expanders"},
 290	{0x04678200, 0, 1,
 291	"4020: Connections exceed IOA design limits"},
 292	{0x04678300, 0, 1,
 293	"4030: Incorrect multipath connection"},
 294	{0x04679000, 0, 1,
 295	"4110: Unsupported enclosure function"},
 296	{0x046E0000, 0, 1,
 297	"FFF4: Command to logical unit failed"},
 298	{0x05240000, 1, 0,
 299	"Illegal request, invalid request type or request packet"},
 300	{0x05250000, 0, 0,
 301	"Illegal request, invalid resource handle"},
 302	{0x05258000, 0, 0,
 303	"Illegal request, commands not allowed to this device"},
 304	{0x05258100, 0, 0,
 305	"Illegal request, command not allowed to a secondary adapter"},
 306	{0x05260000, 0, 0,
 307	"Illegal request, invalid field in parameter list"},
 308	{0x05260100, 0, 0,
 309	"Illegal request, parameter not supported"},
 310	{0x05260200, 0, 0,
 311	"Illegal request, parameter value invalid"},
 312	{0x052C0000, 0, 0,
 313	"Illegal request, command sequence error"},
 314	{0x052C8000, 1, 0,
 315	"Illegal request, dual adapter support not enabled"},
 316	{0x06040500, 0, 1,
 317	"9031: Array protection temporarily suspended, protection resuming"},
 318	{0x06040600, 0, 1,
 319	"9040: Array protection temporarily suspended, protection resuming"},
 320	{0x06288000, 0, 1,
 321	"3140: Device bus not ready to ready transition"},
 322	{0x06290000, 0, 1,
 323	"FFFB: SCSI bus was reset"},
 324	{0x06290500, 0, 0,
 325	"FFFE: SCSI bus transition to single ended"},
 326	{0x06290600, 0, 0,
 327	"FFFE: SCSI bus transition to LVD"},
 328	{0x06298000, 0, 1,
 329	"FFFB: SCSI bus was reset by another initiator"},
 330	{0x063F0300, 0, 1,
 331	"3029: A device replacement has occurred"},
 332	{0x064C8000, 0, 1,
 333	"9051: IOA cache data exists for a missing or failed device"},
 334	{0x064C8100, 0, 1,
 335	"9055: Auxiliary cache IOA contains cache data needed by the primary IOA"},
 336	{0x06670100, 0, 1,
 337	"9025: Disk unit is not supported at its physical location"},
 338	{0x06670600, 0, 1,
 339	"3020: IOA detected a SCSI bus configuration error"},
 340	{0x06678000, 0, 1,
 341	"3150: SCSI bus configuration error"},
 342	{0x06678100, 0, 1,
 343	"9074: Asymmetric advanced function disk configuration"},
 344	{0x06678300, 0, 1,
 345	"4040: Incomplete multipath connection between IOA and enclosure"},
 346	{0x06678400, 0, 1,
 347	"4041: Incomplete multipath connection between enclosure and device"},
 348	{0x06678500, 0, 1,
 349	"9075: Incomplete multipath connection between IOA and remote IOA"},
 350	{0x06678600, 0, 1,
 351	"9076: Configuration error, missing remote IOA"},
 352	{0x06679100, 0, 1,
 353	"4050: Enclosure does not support a required multipath function"},
 354	{0x06690200, 0, 1,
 355	"9041: Array protection temporarily suspended"},
 356	{0x06698200, 0, 1,
 357	"9042: Corrupt array parity detected on specified device"},
 358	{0x066B0200, 0, 1,
 359	"9030: Array no longer protected due to missing or failed disk unit"},
 360	{0x066B8000, 0, 1,
 361	"9071: Link operational transition"},
 362	{0x066B8100, 0, 1,
 363	"9072: Link not operational transition"},
 364	{0x066B8200, 0, 1,
 365	"9032: Array exposed but still protected"},
 366	{0x066B9100, 0, 1,
 367	"4061: Multipath redundancy level got better"},
 368	{0x066B9200, 0, 1,
 369	"4060: Multipath redundancy level got worse"},
 370	{0x07270000, 0, 0,
 371	"Failure due to other device"},
 372	{0x07278000, 0, 1,
 373	"9008: IOA does not support functions expected by devices"},
 374	{0x07278100, 0, 1,
 375	"9010: Cache data associated with attached devices cannot be found"},
 376	{0x07278200, 0, 1,
 377	"9011: Cache data belongs to devices other than those attached"},
 378	{0x07278400, 0, 1,
 379	"9020: Array missing 2 or more devices with only 1 device present"},
 380	{0x07278500, 0, 1,
 381	"9021: Array missing 2 or more devices with 2 or more devices present"},
 382	{0x07278600, 0, 1,
 383	"9022: Exposed array is missing a required device"},
 384	{0x07278700, 0, 1,
 385	"9023: Array member(s) not at required physical locations"},
 386	{0x07278800, 0, 1,
 387	"9024: Array not functional due to present hardware configuration"},
 388	{0x07278900, 0, 1,
 389	"9026: Array not functional due to present hardware configuration"},
 390	{0x07278A00, 0, 1,
 391	"9027: Array is missing a device and parity is out of sync"},
 392	{0x07278B00, 0, 1,
 393	"9028: Maximum number of arrays already exist"},
 394	{0x07278C00, 0, 1,
 395	"9050: Required cache data cannot be located for a disk unit"},
 396	{0x07278D00, 0, 1,
 397	"9052: Cache data exists for a device that has been modified"},
 398	{0x07278F00, 0, 1,
 399	"9054: IOA resources not available due to previous problems"},
 400	{0x07279100, 0, 1,
 401	"9092: Disk unit requires initialization before use"},
 402	{0x07279200, 0, 1,
 403	"9029: Incorrect hardware configuration change has been detected"},
 404	{0x07279600, 0, 1,
 405	"9060: One or more disk pairs are missing from an array"},
 406	{0x07279700, 0, 1,
 407	"9061: One or more disks are missing from an array"},
 408	{0x07279800, 0, 1,
 409	"9062: One or more disks are missing from an array"},
 410	{0x07279900, 0, 1,
 411	"9063: Maximum number of functional arrays has been exceeded"},
 412	{0x0B260000, 0, 0,
 413	"Aborted command, invalid descriptor"},
 414	{0x0B5A0000, 0, 0,
 415	"Command terminated by host"}
 416};
 417
 418static const struct ipr_ses_table_entry ipr_ses_table[] = {
 419	{ "2104-DL1        ", "XXXXXXXXXXXXXXXX", 80 },
 420	{ "2104-TL1        ", "XXXXXXXXXXXXXXXX", 80 },
 421	{ "HSBP07M P U2SCSI", "XXXXXXXXXXXXXXXX", 80 }, /* Hidive 7 slot */
 422	{ "HSBP05M P U2SCSI", "XXXXXXXXXXXXXXXX", 80 }, /* Hidive 5 slot */
 423	{ "HSBP05M S U2SCSI", "XXXXXXXXXXXXXXXX", 80 }, /* Bowtie */
 424	{ "HSBP06E ASU2SCSI", "XXXXXXXXXXXXXXXX", 80 }, /* MartinFenning */
 425	{ "2104-DU3        ", "XXXXXXXXXXXXXXXX", 160 },
 426	{ "2104-TU3        ", "XXXXXXXXXXXXXXXX", 160 },
 427	{ "HSBP04C RSU2SCSI", "XXXXXXX*XXXXXXXX", 160 },
 428	{ "HSBP06E RSU2SCSI", "XXXXXXX*XXXXXXXX", 160 },
 429	{ "St  V1S2        ", "XXXXXXXXXXXXXXXX", 160 },
 430	{ "HSBPD4M  PU3SCSI", "XXXXXXX*XXXXXXXX", 160 },
 431	{ "VSBPD1H   U3SCSI", "XXXXXXX*XXXXXXXX", 160 }
 432};
 433
 434/*
 435 *  Function Prototypes
 436 */
 437static int ipr_reset_alert(struct ipr_cmnd *);
 438static void ipr_process_ccn(struct ipr_cmnd *);
 439static void ipr_process_error(struct ipr_cmnd *);
 440static void ipr_reset_ioa_job(struct ipr_cmnd *);
 441static void ipr_initiate_ioa_reset(struct ipr_ioa_cfg *,
 442				   enum ipr_shutdown_type);
 443
 444#ifdef CONFIG_SCSI_IPR_TRACE
 445/**
 446 * ipr_trc_hook - Add a trace entry to the driver trace
 447 * @ipr_cmd:	ipr command struct
 448 * @type:		trace type
 449 * @add_data:	additional data
 450 *
 451 * Return value:
 452 * 	none
 453 **/
 454static void ipr_trc_hook(struct ipr_cmnd *ipr_cmd,
 455			 u8 type, u32 add_data)
 456{
 457	struct ipr_trace_entry *trace_entry;
 458	struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
 459
 460	trace_entry = &ioa_cfg->trace[ioa_cfg->trace_index++];
 461	trace_entry->time = jiffies;
 462	trace_entry->op_code = ipr_cmd->ioarcb.cmd_pkt.cdb[0];
 463	trace_entry->type = type;
 464	trace_entry->ata_op_code = ipr_cmd->ioarcb.add_data.u.regs.command;
 465	trace_entry->cmd_index = ipr_cmd->cmd_index & 0xff;
 466	trace_entry->res_handle = ipr_cmd->ioarcb.res_handle;
 467	trace_entry->u.add_data = add_data;
 468}
 469#else
 470#define ipr_trc_hook(ipr_cmd, type, add_data) do { } while(0)
 471#endif
 472
 473/**
 474 * ipr_reinit_ipr_cmnd - Re-initialize an IPR Cmnd block for reuse
 475 * @ipr_cmd:	ipr command struct
 476 *
 477 * Return value:
 478 * 	none
 479 **/
 480static void ipr_reinit_ipr_cmnd(struct ipr_cmnd *ipr_cmd)
 481{
 482	struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
 483	struct ipr_ioasa *ioasa = &ipr_cmd->ioasa;
 484
 485	memset(&ioarcb->cmd_pkt, 0, sizeof(struct ipr_cmd_pkt));
 486	ioarcb->write_data_transfer_length = 0;
 487	ioarcb->read_data_transfer_length = 0;
 488	ioarcb->write_ioadl_len = 0;
 489	ioarcb->read_ioadl_len = 0;
 490	ioasa->ioasc = 0;
 491	ioasa->residual_data_len = 0;
 492	ioasa->u.gata.status = 0;
 493
 494	ipr_cmd->scsi_cmd = NULL;
 495	ipr_cmd->qc = NULL;
 496	ipr_cmd->sense_buffer[0] = 0;
 497	ipr_cmd->dma_use_sg = 0;
 498}
 499
 500/**
 501 * ipr_init_ipr_cmnd - Initialize an IPR Cmnd block
 502 * @ipr_cmd:	ipr command struct
 503 *
 504 * Return value:
 505 * 	none
 506 **/
 507static void ipr_init_ipr_cmnd(struct ipr_cmnd *ipr_cmd)
 508{
 509	ipr_reinit_ipr_cmnd(ipr_cmd);
 510	ipr_cmd->u.scratch = 0;
 511	ipr_cmd->sibling = NULL;
 512	init_timer(&ipr_cmd->timer);
 513}
 514
 515/**
 516 * ipr_get_free_ipr_cmnd - Get a free IPR Cmnd block
 517 * @ioa_cfg:	ioa config struct
 518 *
 519 * Return value:
 520 * 	pointer to ipr command struct
 521 **/
 522static
 523struct ipr_cmnd *ipr_get_free_ipr_cmnd(struct ipr_ioa_cfg *ioa_cfg)
 524{
 525	struct ipr_cmnd *ipr_cmd;
 526
 527	ipr_cmd = list_entry(ioa_cfg->free_q.next, struct ipr_cmnd, queue);
 528	list_del(&ipr_cmd->queue);
 529	ipr_init_ipr_cmnd(ipr_cmd);
 530
 531	return ipr_cmd;
 532}
 533
 534/**
 535 * ipr_unmap_sglist - Unmap scatterlist if mapped
 536 * @ioa_cfg:	ioa config struct
 537 * @ipr_cmd:	ipr command struct
 538 *
 539 * Return value:
 540 * 	nothing
 541 **/
 542static void ipr_unmap_sglist(struct ipr_ioa_cfg *ioa_cfg,
 543			     struct ipr_cmnd *ipr_cmd)
 544{
 545	struct scsi_cmnd *scsi_cmd = ipr_cmd->scsi_cmd;
 546
 547	if (ipr_cmd->dma_use_sg) {
 548		if (scsi_cmd->use_sg > 0) {
 549			pci_unmap_sg(ioa_cfg->pdev, scsi_cmd->request_buffer,
 550				     scsi_cmd->use_sg,
 551				     scsi_cmd->sc_data_direction);
 552		} else {
 553			pci_unmap_single(ioa_cfg->pdev, ipr_cmd->dma_handle,
 554					 scsi_cmd->request_bufflen,
 555					 scsi_cmd->sc_data_direction);
 556		}
 557	}
 558}
 559
 560/**
 561 * ipr_mask_and_clear_interrupts - Mask all and clear specified interrupts
 562 * @ioa_cfg:	ioa config struct
 563 * @clr_ints:     interrupts to clear
 564 *
 565 * This function masks all interrupts on the adapter, then clears the
 566 * interrupts specified in the mask
 567 *
 568 * Return value:
 569 * 	none
 570 **/
 571static void ipr_mask_and_clear_interrupts(struct ipr_ioa_cfg *ioa_cfg,
 572					  u32 clr_ints)
 573{
 574	volatile u32 int_reg;
 575
 576	/* Stop new interrupts */
 577	ioa_cfg->allow_interrupts = 0;
 578
 579	/* Set interrupt mask to stop all new interrupts */
 580	writel(~0, ioa_cfg->regs.set_interrupt_mask_reg);
 581
 582	/* Clear any pending interrupts */
 583	writel(clr_ints, ioa_cfg->regs.clr_interrupt_reg);
 584	int_reg = readl(ioa_cfg->regs.sense_interrupt_reg);
 585}
 586
 587/**
 588 * ipr_save_pcix_cmd_reg - Save PCI-X command register
 589 * @ioa_cfg:	ioa config struct
 590 *
 591 * Return value:
 592 * 	0 on success / -EIO on failure
 593 **/
 594static int ipr_save_pcix_cmd_reg(struct ipr_ioa_cfg *ioa_cfg)
 595{
 596	int pcix_cmd_reg = pci_find_capability(ioa_cfg->pdev, PCI_CAP_ID_PCIX);
 597
 598	if (pcix_cmd_reg == 0)
 599		return 0;
 600
 601	if (pci_read_config_word(ioa_cfg->pdev, pcix_cmd_reg + PCI_X_CMD,
 602				 &ioa_cfg->saved_pcix_cmd_reg) != PCIBIOS_SUCCESSFUL) {
 603		dev_err(&ioa_cfg->pdev->dev, "Failed to save PCI-X command register\n");
 604		return -EIO;
 605	}
 606
 607	ioa_cfg->saved_pcix_cmd_reg |= PCI_X_CMD_DPERR_E | PCI_X_CMD_ERO;
 608	return 0;
 609}
 610
 611/**
 612 * ipr_set_pcix_cmd_reg - Setup PCI-X command register
 613 * @ioa_cfg:	ioa config struct
 614 *
 615 * Return value:
 616 * 	0 on success / -EIO on failure
 617 **/
 618static int ipr_set_pcix_cmd_reg(struct ipr_ioa_cfg *ioa_cfg)
 619{
 620	int pcix_cmd_reg = pci_find_capability(ioa_cfg->pdev, PCI_CAP_ID_PCIX);
 621
 622	if (pcix_cmd_reg) {
 623		if (pci_write_config_word(ioa_cfg->pdev, pcix_cmd_reg + PCI_X_CMD,
 624					  ioa_cfg->saved_pcix_cmd_reg) != PCIBIOS_SUCCESSFUL) {
 625			dev_err(&ioa_cfg->pdev->dev, "Failed to setup PCI-X command register\n");
 626			return -EIO;
 627		}
 628	}
 629
 630	return 0;
 631}
 632
 633/**
 634 * ipr_sata_eh_done - done function for aborted SATA commands
 635 * @ipr_cmd:	ipr command struct
 636 *
 637 * This function is invoked for ops generated to SATA
 638 * devices which are being aborted.
 639 *
 640 * Return value:
 641 * 	none
 642 **/
 643static void ipr_sata_eh_done(struct ipr_cmnd *ipr_cmd)
 644{
 645	struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
 646	struct ata_queued_cmd *qc = ipr_cmd->qc;
 647	struct ipr_sata_port *sata_port = qc->ap->private_data;
 648
 649	qc->err_mask |= AC_ERR_OTHER;
 650	sata_port->ioasa.status |= ATA_BUSY;
 651	list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q);
 652	ata_qc_complete(qc);
 653}
 654
 655/**
 656 * ipr_scsi_eh_done - mid-layer done function for aborted ops
 657 * @ipr_cmd:	ipr command struct
 658 *
 659 * This function is invoked by the interrupt handler for
 660 * ops generated by the SCSI mid-layer which are being aborted.
 661 *
 662 * Return value:
 663 * 	none
 664 **/
 665static void ipr_scsi_eh_done(struct ipr_cmnd *ipr_cmd)
 666{
 667	struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
 668	struct scsi_cmnd *scsi_cmd = ipr_cmd->scsi_cmd;
 669
 670	scsi_cmd->result |= (DID_ERROR << 16);
 671
 672	ipr_unmap_sglist(ioa_cfg, ipr_cmd);
 673	scsi_cmd->scsi_done(scsi_cmd);
 674	list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q);
 675}
 676
 677/**
 678 * ipr_fail_all_ops - Fails all outstanding ops.
 679 * @ioa_cfg:	ioa config struct
 680 *
 681 * This function fails all outstanding ops.
 682 *
 683 * Return value:
 684 * 	none
 685 **/
 686static void ipr_fail_all_ops(struct ipr_ioa_cfg *ioa_cfg)
 687{
 688	struct ipr_cmnd *ipr_cmd, *temp;
 689
 690	ENTER;
 691	list_for_each_entry_safe(ipr_cmd, temp, &ioa_cfg->pending_q, queue) {
 692		list_del(&ipr_cmd->queue);
 693
 694		ipr_cmd->ioasa.ioasc = cpu_to_be32(IPR_IOASC_IOA_WAS_RESET);
 695		ipr_cmd->ioasa.ilid = cpu_to_be32(IPR_DRIVER_ILID);
 696
 697		if (ipr_cmd->scsi_cmd)
 698			ipr_cmd->done = ipr_scsi_eh_done;
 699		else if (ipr_cmd->qc)
 700			ipr_cmd->done = ipr_sata_eh_done;
 701
 702		ipr_trc_hook(ipr_cmd, IPR_TRACE_FINISH, IPR_IOASC_IOA_WAS_RESET);
 703		del_timer(&ipr_cmd->timer);
 704		ipr_cmd->done(ipr_cmd);
 705	}
 706
 707	LEAVE;
 708}
 709
 710/**
 711 * ipr_do_req -  Send driver initiated requests.
 712 * @ipr_cmd:		ipr command struct
 713 * @done:			done function
 714 * @timeout_func:	timeout function
 715 * @timeout:		timeout value
 716 *
 717 * This function sends the specified command to the adapter with the
 718 * timeout given. The done function is invoked on command completion.
 719 *
 720 * Return value:
 721 * 	none
 722 **/
 723static void ipr_do_req(struct ipr_cmnd *ipr_cmd,
 724		       void (*done) (struct ipr_cmnd *),
 725		       void (*timeout_func) (struct ipr_cmnd *), u32 timeout)
 726{
 727	struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
 728
 729	list_add_tail(&ipr_cmd->queue, &ioa_cfg->pending_q);
 730
 731	ipr_cmd->done = done;
 732
 733	ipr_cmd->timer.data = (unsigned long) ipr_cmd;
 734	ipr_cmd->timer.expires = jiffies + timeout;
 735	ipr_cmd->timer.function = (void (*)(unsigned long))timeout_func;
 736
 737	add_timer(&ipr_cmd->timer);
 738
 739	ipr_trc_hook(ipr_cmd, IPR_TRACE_START, 0);
 740
 741	mb();
 742	writel(be32_to_cpu(ipr_cmd->ioarcb.ioarcb_host_pci_addr),
 743	       ioa_cfg->regs.ioarrin_reg);
 744}
 745
 746/**
 747 * ipr_internal_cmd_done - Op done function for an internally generated op.
 748 * @ipr_cmd:	ipr command struct
 749 *
 750 * This function is the op done function for an internally generated,
 751 * blocking op. It simply wakes the sleeping thread.
 752 *
 753 * Return value:
 754 * 	none
 755 **/
 756static void ipr_internal_cmd_done(struct ipr_cmnd *ipr_cmd)
 757{
 758	if (ipr_cmd->sibling)
 759		ipr_cmd->sibling = NULL;
 760	else
 761		complete(&ipr_cmd->completion);
 762}
 763
 764/**
 765 * ipr_send_blocking_cmd - Send command and sleep on its completion.
 766 * @ipr_cmd:	ipr command struct
 767 * @timeout_func:	function to invoke if command times out
 768 * @timeout:	timeout
 769 *
 770 * Return value:
 771 * 	none
 772 **/
 773static void ipr_send_blocking_cmd(struct ipr_cmnd *ipr_cmd,
 774				  void (*timeout_func) (struct ipr_cmnd *ipr_cmd),
 775				  u32 timeout)
 776{
 777	struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
 778
 779	init_completion(&ipr_cmd->completion);
 780	ipr_do_req(ipr_cmd, ipr_internal_cmd_done, timeout_func, timeout);
 781
 782	spin_unlock_irq(ioa_cfg->host->host_lock);
 783	wait_for_completion(&ipr_cmd->completion);
 784	spin_lock_irq(ioa_cfg->host->host_lock);
 785}
 786
 787/**
 788 * ipr_send_hcam - Send an HCAM to the adapter.
 789 * @ioa_cfg:	ioa config struct
 790 * @type:		HCAM type
 791 * @hostrcb:	hostrcb struct
 792 *
 793 * This function will send a Host Controlled Async command to the adapter.
 794 * If HCAMs are currently not allowed to be issued to the adapter, it will
 795 * place the hostrcb on the free queue.
 796 *
 797 * Return value:
 798 * 	none
 799 **/
 800static void ipr_send_hcam(struct ipr_ioa_cfg *ioa_cfg, u8 type,
 801			  struct ipr_hostrcb *hostrcb)
 802{
 803	struct ipr_cmnd *ipr_cmd;
 804	struct ipr_ioarcb *ioarcb;
 805
 806	if (ioa_cfg->allow_cmds) {
 807		ipr_cmd = ipr_get_free_ipr_cmnd(ioa_cfg);
 808		list_add_tail(&ipr_cmd->queue, &ioa_cfg->pending_q);
 809		list_add_tail(&hostrcb->queue, &ioa_cfg->hostrcb_pending_q);
 810
 811		ipr_cmd->u.hostrcb = hostrcb;
 812		ioarcb = &ipr_cmd->ioarcb;
 813
 814		ioarcb->res_handle = cpu_to_be32(IPR_IOA_RES_HANDLE);
 815		ioarcb->cmd_pkt.request_type = IPR_RQTYPE_HCAM;
 816		ioarcb->cmd_pkt.cdb[0] = IPR_HOST_CONTROLLED_ASYNC;
 817		ioarcb->cmd_pkt.cdb[1] = type;
 818		ioarcb->cmd_pkt.cdb[7] = (sizeof(hostrcb->hcam) >> 8) & 0xff;
 819		ioarcb->cmd_pkt.cdb[8] = sizeof(hostrcb->hcam) & 0xff;
 820
 821		ioarcb->read_data_transfer_length = cpu_to_be32(sizeof(hostrcb->hcam));
 822		ioarcb->read_ioadl_len = cpu_to_be32(sizeof(struct ipr_ioadl_desc));
 823		ipr_cmd->ioadl[0].flags_and_data_len =
 824			cpu_to_be32(IPR_IOADL_FLAGS_READ_LAST | sizeof(hostrcb->hcam));
 825		ipr_cmd->ioadl[0].address = cpu_to_be32(hostrcb->hostrcb_dma);
 826
 827		if (type == IPR_HCAM_CDB_OP_CODE_CONFIG_CHANGE)
 828			ipr_cmd->done = ipr_process_ccn;
 829		else
 830			ipr_cmd->done = ipr_process_error;
 831
 832		ipr_trc_hook(ipr_cmd, IPR_TRACE_START, IPR_IOA_RES_ADDR);
 833
 834		mb();
 835		writel(be32_to_cpu(ipr_cmd->ioarcb.ioarcb_host_pci_addr),
 836		       ioa_cfg->regs.ioarrin_reg);
 837	} else {
 838		list_add_tail(&hostrcb->queue, &ioa_cfg->hostrcb_free_q);
 839	}
 840}
 841
 842/**
 843 * ipr_init_res_entry - Initialize a resource entry struct.
 844 * @res:	resource entry struct
 845 *
 846 * Return value:
 847 * 	none
 848 **/
 849static void ipr_init_res_entry(struct ipr_resource_entry *res)
 850{
 851	res->needs_sync_complete = 0;
 852	res->in_erp = 0;
 853	res->add_to_ml = 0;
 854	res->del_from_ml = 0;
 855	res->resetting_device = 0;
 856	res->sdev = NULL;
 857	res->sata_port = NULL;
 858}
 859
 860/**
 861 * ipr_handle_config_change - Handle a config change from the adapter
 862 * @ioa_cfg:	ioa config struct
 863 * @hostrcb:	hostrcb
 864 *
 865 * Return value:
 866 * 	none
 867 **/
 868static void ipr_handle_config_change(struct ipr_ioa_cfg *ioa_cfg,
 869			      struct ipr_hostrcb *hostrcb)
 870{
 871	struct ipr_resource_entry *res = NULL;
 872	struct ipr_config_table_entry *cfgte;
 873	u32 is_ndn = 1;
 874
 875	cfgte = &hostrcb->hcam.u.ccn.cfgte;
 876
 877	list_for_each_entry(res, &ioa_cfg->used_res_q, queue) {
 878		if (!memcmp(&res->cfgte.res_addr, &cfgte->res_addr,
 879			    sizeof(cfgte->res_addr))) {
 880			is_ndn = 0;
 881			break;
 882		}
 883	}
 884
 885	if (is_ndn) {
 886		if (list_empty(&ioa_cfg->free_res_q)) {
 887			ipr_send_hcam(ioa_cfg,
 888				      IPR_HCAM_CDB_OP_CODE_CONFIG_CHANGE,
 889				      hostrcb);
 890			return;
 891		}
 892
 893		res = list_entry(ioa_cfg->free_res_q.next,
 894				 struct ipr_resource_entry, queue);
 895
 896		list_del(&res->queue);
 897		ipr_init_res_entry(res);
 898		list_add_tail(&res->queue, &ioa_cfg->used_res_q);
 899	}
 900
 901	memcpy(&res->cfgte, cfgte, sizeof(struct ipr_config_table_entry));
 902
 903	if (hostrcb->hcam.notify_type == IPR_HOST_RCB_NOTIF_TYPE_REM_ENTRY) {
 904		if (res->sdev) {
 905			res->del_from_ml = 1;
 906			res->cfgte.res_handle = IPR_INVALID_RES_HANDLE;
 907			if (ioa_cfg->allow_ml_add_del)
 908				schedule_work(&ioa_cfg->work_q);
 909		} else
 910			list_move_tail(&res->queue, &ioa_cfg->free_res_q);
 911	} else if (!res->sdev) {
 912		res->add_to_ml = 1;
 913		if (ioa_cfg->allow_ml_add_del)
 914			schedule_work(&ioa_cfg->work_q);
 915	}
 916
 917	ipr_send_hcam(ioa_cfg, IPR_HCAM_CDB_OP_CODE_CONFIG_CHANGE, hostrcb);
 918}
 919
 920/**
 921 * ipr_process_ccn - Op done function for a CCN.
 922 * @ipr_cmd:	ipr command struct
 923 *
 924 * This function is the op done function for a configuration
 925 * change notification host controlled async from the adapter.
 926 *
 927 * Return value:
 928 * 	none
 929 **/
 930static void ipr_process_ccn(struct ipr_cmnd *ipr_cmd)
 931{
 932	struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
 933	struct ipr_hostrcb *hostrcb = ipr_cmd->u.hostrcb;
 934	u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc);
 935
 936	list_del(&hostrcb->queue);
 937	list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q);
 938
 939	if (ioasc) {
 940		if (ioasc != IPR_IOASC_IOA_WAS_RESET)
 941			dev_err(&ioa_cfg->pdev->dev,
 942				"Host RCB failed with IOASC: 0x%08X\n", ioasc);
 943
 944		ipr_send_hcam(ioa_cfg, IPR_HCAM_CDB_OP_CODE_CONFIG_CHANGE, hostrcb);
 945	} else {
 946		ipr_handle_config_change(ioa_cfg, hostrcb);
 947	}
 948}
 949
 950/**
 951 * ipr_log_vpd - Log the passed VPD to the error log.
 952 * @vpd:		vendor/product id/sn struct
 953 *
 954 * Return value:
 955 * 	none
 956 **/
 957static void ipr_log_vpd(struct ipr_vpd *vpd)
 958{
 959	char buffer[IPR_VENDOR_ID_LEN + IPR_PROD_ID_LEN
 960		    + IPR_SERIAL_NUM_LEN];
 961
 962	memcpy(buffer, vpd->vpids.vendor_id, IPR_VENDOR_ID_LEN);
 963	memcpy(buffer + IPR_VENDOR_ID_LEN, vpd->vpids.product_id,
 964	       IPR_PROD_ID_LEN);
 965	buffer[IPR_VENDOR_ID_LEN + IPR_PROD_ID_LEN] = '\0';
 966	ipr_err("Vendor/Product ID: %s\n", buffer);
 967
 968	memcpy(buffer, vpd->sn, IPR_SERIAL_NUM_LEN);
 969	buffer[IPR_SERIAL_NUM_LEN] = '\0';
 970	ipr_err("    Serial Number: %s\n", buffer);
 971}
 972
 973/**
 974 * ipr_log_ext_vpd - Log the passed extended VPD to the error log.
 975 * @vpd:		vendor/product id/sn/wwn struct
 976 *
 977 * Return value:
 978 * 	none
 979 **/
 980static void ipr_log_ext_vpd(struct ipr_ext_vpd *vpd)
 981{
 982	ipr_log_vpd(&vpd->vpd);
 983	ipr_err("    WWN: %08X%08X\n", be32_to_cpu(vpd->wwid[0]),
 984		be32_to_cpu(vpd->wwid[1]));
 985}
 986
 987/**
 988 * ipr_log_enhanced_cache_error - Log a cache error.
 989 * @ioa_cfg:	ioa config struct
 990 * @hostrcb:	hostrcb struct
 991 *
 992 * Return value:
 993 * 	none
 994 **/
 995static void ipr_log_enhanced_cache_error(struct ipr_ioa_cfg *ioa_cfg,
 996					 struct ipr_hostrcb *hostrcb)
 997{
 998	struct ipr_hostrcb_type_12_error *error =
 999		&hostrcb->hcam.u.error.u.type_12_error;
1000
1001	ipr_err("-----Current Configuration-----\n");
1002	ipr_err("Cache Directory Card Information:\n");
1003	ipr_log_ext_vpd(&error->ioa_vpd);
1004	ipr_err("Adapter Card Information:\n");
1005	ipr_log_ext_vpd(&error->cfc_vpd);
1006
1007	ipr_err("-----Expected Configuration-----\n");
1008	ipr_err("Cache Directory Card Information:\n");
1009	ipr_log_ext_vpd(&error->ioa_last_attached_to_cfc_vpd);
1010	ipr_err("Adapter Card Information:\n");
1011	ipr_log_ext_vpd(&error->cfc_last_attached_to_ioa_vpd);
1012
1013	ipr_err("Additional IOA Data: %08X %08X %08X\n",
1014		     be32_to_cpu(error->ioa_data[0]),
1015		     be32_to_cpu(error->ioa_data[1]),
1016		     be32_to_cpu(error->ioa_data[2]));
1017}
1018
1019/**
1020 * ipr_log_cache_error - Log a cache error.
1021 * @ioa_cfg:	ioa config struct
1022 * @hostrcb:	hostrcb struct
1023 *
1024 * Return value:
1025 * 	none
1026 **/
1027static void ipr_log_cache_error(struct ipr_ioa_cfg *ioa_cfg,
1028				struct ipr_hostrcb *hostrcb)
1029{
1030	struct ipr_hostrcb_type_02_error *error =
1031		&hostrcb->hcam.u.error.u.type_02_error;
1032
1033	ipr_err("-----Current Configuration-----\n");
1034	ipr_err("Cache Directory Card Information:\n");
1035	ipr_log_vpd(&error->ioa_vpd);
1036	ipr_err("Adapter Card Information:\n");
1037	ipr_log_vpd(&error->cfc_vpd);
1038
1039	ipr_err("-----Expected Configuration-----\n");
1040	ipr_err("Cache Directory Card Information:\n");
1041	ipr_log_vpd(&error->ioa_last_attached_to_cfc_vpd);
1042	ipr_err("Adapter Card Information:\n");
1043	ipr_log_vpd(&error->cfc_last_attached_to_ioa_vpd);
1044
1045	ipr_err("Additional IOA Data: %08X %08X %08X\n",
1046		     be32_to_cpu(error->ioa_data[0]),
1047		     be32_to_cpu(error->ioa_data[1]),
1048		     be32_to_cpu(error->ioa_data[2]));
1049}
1050
1051/**
1052 * ipr_log_enhanced_config_error - Log a configuration error.
1053 * @ioa_cfg:	ioa config struct
1054 * @hostrcb:	hostrcb struct
1055 *
1056 * Return value:
1057 * 	none
1058 **/
1059static void ipr_log_enhanced_config_error(struct ipr_ioa_cfg *ioa_cfg,
1060					  struct ipr_hostrcb *hostrcb)
1061{
1062	int errors_logged, i;
1063	struct ipr_hostrcb_device_data_entry_enhanced *dev_entry;
1064	struct ipr_hostrcb_type_13_error *error;
1065
1066	error = &hostrcb->hcam.u.error.u.type_13_error;
1067	errors_logged = be32_to_cpu(error->errors_logged);
1068
1069	ipr_err("Device Errors Detected/Logged: %d/%d\n",
1070		be32_to_cpu(error->errors_detected), errors_logged);
1071
1072	dev_entry = error->dev;
1073
1074	for (i = 0; i < errors_logged; i++, dev_entry++) {
1075		ipr_err_separator;
1076
1077		ipr_phys_res_err(ioa_cfg, dev_entry->dev_res_addr, "Device %d", i + 1);
1078		ipr_log_ext_vpd(&dev_entry->vpd);
1079
1080		ipr_err("-----New Device Information-----\n");
1081		ipr_log_ext_vpd(&dev_entry->new_vpd);
1082
1083		ipr_err("Cache Directory Card Information:\n");
1084		ipr_log_ext_vpd(&dev_entry->ioa_last_with_dev_vpd);
1085
1086		ipr_err("Adapter Card Information:\n");
1087		ipr_log_ext_vpd(&dev_entry->cfc_last_with_dev_vpd);
1088	}
1089}
1090
1091/**
1092 * ipr_log_config_error - Log a configuration error.
1093 * @ioa_cfg:	ioa config struct
1094 * @hostrcb:	hostrcb struct
1095 *
1096 * Return value:
1097 * 	none
1098 **/
1099static void ipr_log_config_error(struct ipr_ioa_cfg *ioa_cfg,
1100				 struct ipr_hostrcb *hostrcb)
1101{
1102	int errors_logged, i;
1103	struct ipr_hostrcb_device_data_entry *dev_entry;
1104	struct ipr_hostrcb_type_03_error *error;
1105
1106	error = &hostrcb->hcam.u.error.u.type_03_error;
1107	errors_logged = be32_to_cpu(error->errors_logged);
1108
1109	ipr_err("Device Errors Detected/Logged: %d/%d\n",
1110		be32_to_cpu(error->errors_detected), errors_logged);
1111
1112	dev_entry = error->dev;
1113
1114	for (i = 0; i < errors_logged; i++, dev_entry++) {
1115		ipr_err_separator;
1116
1117		ipr_phys_res_err(ioa_cfg, dev_entry->dev_res_addr, "Device %d", i + 1);
1118		ipr_log_vpd(&dev_entry->vpd);
1119
1120		ipr_err("-----New Device Information-----\n");
1121		ipr_log_vpd(&dev_entry->new_vpd);
1122
1123		ipr_err("Cache Directory Card Information:\n");
1124		ipr_log_vpd(&dev_entry->ioa_last_with_dev_vpd);
1125
1126		ipr_err("Adapter Card Information:\n");
1127		ipr_log_vpd(&dev_entry->cfc_last_with_dev_vpd);
1128
1129		ipr_err("Additional IOA Data: %08X %08X %08X %08X %08X\n",
1130			be32_to_cpu(dev_entry->ioa_data[0]),
1131			be32_to_cpu(dev_entry->ioa_data[1]),
1132			be32_to_cpu(dev_entry->ioa_data[2]),
1133			be32_to_cpu(dev_entry->ioa_data[3]),
1134			be32_to_cpu(dev_entry->ioa_data[4]));
1135	}
1136}
1137
1138/**
1139 * ipr_log_enhanced_array_error - Log an array configuration error.
1140 * @ioa_cfg:	ioa config struct
1141 * @hostrcb:	hostrcb struct
1142 *
1143 * Return value:
1144 * 	none
1145 **/
1146static void ipr_log_enhanced_array_error(struct ipr_ioa_cfg *ioa_cfg,
1147					 struct ipr_hostrcb *hostrcb)
1148{
1149	int i, num_entries;
1150	struct ipr_hostrcb_type_14_error *error;
1151	struct ipr_hostrcb_array_data_entry_enhanced *array_entry;
1152	const u8 zero_sn[IPR_SERIAL_NUM_LEN] = { [0 ... IPR_SERIAL_NUM_LEN-1] = '0' };
1153
1154	error = &hostrcb->hcam.u.error.u.type_14_error;
1155
1156	ipr_err_separator;
1157
1158	ipr_err("RAID %s Array Configuration: %d:%d:%d:%d\n",
1159		error->protection_level,
1160		ioa_cfg->host->host_no,
1161		error->last_func_vset_res_addr.bus,
1162		error->last_func_vset_res_addr.target,
1163		error->last_func_vset_res_addr.lun);
1164
1165	ipr_err_separator;
1166
1167	array_entry = error->array_member;
1168	num_entries = min_t(u32, be32_to_cpu(error->num_entries),
1169			    sizeof(error->array_member));
1170
1171	for (i = 0; i < num_entries; i++, array_entry++) {
1172		if (!memcmp(array_entry->vpd.vpd.sn, zero_sn, IPR_SERIAL_NUM_LEN))
1173			continue;
1174
1175		if (be32_to_cpu(error->exposed_mode_adn) == i)
1176			ipr_err("Exposed Array Member %d:\n", i);
1177		else
1178			ipr_err("Array Member %d:\n", i);
1179
1180		ipr_log_ext_vpd(&array_entry->vpd);
1181		ipr_phys_res_err(ioa_cfg, array_entry->dev_res_addr, "Current Location");
1182		ipr_phys_res_err(ioa_cfg, array_entry->expected_dev_res_addr,
1183				 "Expected Location");
1184
1185		ipr_err_separator;
1186	}
1187}
1188
1189/**
1190 * ipr_log_array_error - Log an array configuration error.
1191 * @ioa_cfg:	ioa config struct
1192 * @hostrcb:	hostrcb struct
1193 *
1194 * Return value:
1195 * 	none
1196 **/
1197static void ipr_log_array_error(struct ipr_ioa_cfg *ioa_cfg,
1198				struct ipr_hostrcb *hostrcb)
1199{
1200	int i;
1201	struct ipr_hostrcb_type_04_error *error;
1202	struct ipr_hostrcb_array_data_entry *array_entry;
1203	const u8 zero_sn[IPR_SERIAL_NUM_LEN] = { [0 ... IPR_SERIAL_NUM_LEN-1] = '0' };
1204
1205	error = &hostrcb->hcam.u.error.u.type_04_error;
1206
1207	ipr_err_separator;
1208
1209	ipr_err("RAID %s Array Configuration: %d:%d:%d:%d\n",
1210		error->protection_level,
1211		ioa_cfg->host->host_no,
1212		error->last_func_vset_res_addr.bus,
1213		error->last_func_vset_res_addr.target,
1214		error->last_func_vset_res_addr.lun);
1215
1216	ipr_err_separator;
1217
1218	array_entry = error->array_member;
1219
1220	for (i = 0; i < 18; i++) {
1221		if (!memcmp(array_entry->vpd.sn, zero_sn, IPR_SERIAL_NUM_LEN))
1222			continue;
1223
1224		if (be32_to_cpu(error->exposed_mode_adn) == i)
1225			ipr_err("Exposed Array Member %d:\n", i);
1226		else
1227			ipr_err("Array Member %d:\n", i);
1228
1229		ipr_log_vpd(&array_entry->vpd);
1230
1231		ipr_phys_res_err(ioa_cfg, array_entry->dev_res_addr, "Current Location");
1232		ipr_phys_res_err(ioa_cfg, array_entry->expected_dev_res_addr,
1233				 "Expected Location");
1234
1235		ipr_err_separator;
1236
1237		if (i == 9)
1238			array_entry = error->array_member2;
1239		else
1240			array_entry++;
1241	}
1242}
1243
1244/**
1245 * ipr_log_hex_data - Log additional hex IOA error data.
1246 * @ioa_cfg:	ioa config struct
1247 * @data:		IOA error data
1248 * @len:		data length
1249 *
1250 * Return value:
1251 * 	none
1252 **/
1253static void ipr_log_hex_data(struct ipr_ioa_cfg *ioa_cfg, u32 *data, int len)
1254{
1255	int i;
1256
1257	if (len == 0)
1258		return;
1259
1260	if (ioa_cfg->log_level <= IPR_DEFAULT_LOG_LEVEL)
1261		len = min_t(int, len, IPR_DEFAULT_MAX_ERROR_DUMP);
1262
1263	for (i = 0; i < len / 4; i += 4) {
1264		ipr_err("%08X: %08X %08X %08X %08X\n", i*4,
1265			be32_to_cpu(data[i]),
1266			be32_to_cpu(data[i+1]),
1267			be32_to_cpu(data[i+2]),
1268			be32_to_cpu(data[i+3]));
1269	}
1270}
1271
1272/**
1273 * ipr_log_enhanced_dual_ioa_error - Log an enhanced dual adapter error.
1274 * @ioa_cfg:	ioa config struct
1275 * @hostrcb:	hostrcb struct
1276 *
1277 * Return value:
1278 * 	none
1279 **/
1280static void ipr_log_enhanced_dual_ioa_error(struct ipr_ioa_cfg *ioa_cfg,
1281					    struct ipr_hostrcb *hostrcb)
1282{
1283	struct ipr_hostrcb_type_17_error *error;
1284
1285	error = &hostrcb->hcam.u.error.u.type_17_error;
1286	error->failure_reason[sizeof(error->failure_reason) - 1] = '\0';
1287
1288	ipr_err("%s\n", error->failure_reason);
1289	ipr_err("Remote Adapter VPD:\n");
1290	ipr_log_ext_vpd(&error->vpd);
1291	ipr_log_hex_data(ioa_cfg, error->data,
1292			 be32_to_cpu(hostrcb->hcam.length) -
1293			 (offsetof(struct ipr_hostrcb_error, u) +
1294			  offsetof(struct ipr_hostrcb_type_17_error, data)));
1295}
1296
1297/**
1298 * ipr_log_dual_ioa_error - Log a dual adapter error.
1299 * @ioa_cfg:	ioa config struct
1300 * @hostrcb:	hostrcb struct
1301 *
1302 * Return value:
1303 * 	none
1304 **/
1305static void ipr_log_dual_ioa_error(struct ipr_ioa_cfg *ioa_cfg,
1306				   struct ipr_hostrcb *hostrcb)
1307{
1308	struct ipr_hostrcb_type_07_error *error;
1309
1310	error = &hostrcb->hcam.u.error.u.type_07_error;
1311	error->failure_reason[sizeof(error->failure_reason) - 1] = '\0';
1312
1313	ipr_err("%s\n", error->failure_reason);
1314	ipr_err("Remote Adapter VPD:\n");
1315	ipr_log_vpd(&error->vpd);
1316	ipr_log_hex_data(ioa_cfg, error->data,
1317			 be32_to_cpu(hostrcb->hcam.length) -
1318			 (offsetof(struct ipr_hostrcb_error, u) +
1319			  offsetof(struct ipr_hostrcb_type_07_error, data)));
1320}
1321
1322static const struct {
1323	u8 active;
1324	char *desc;
1325} path_active_desc[] = {
1326	{ IPR_PATH_NO_INFO, "Path" },
1327	{ IPR_PATH_ACTIVE, "Active path" },
1328	{ IPR_PATH_NOT_ACTIVE, "Inactive path" }
1329};
1330
1331static const struct {
1332	u8 state;
1333	char *desc;
1334} path_state_desc[] = {
1335	{ IPR_PATH_STATE_NO_INFO, "has no path state information available" },
1336	{ IPR_PATH_HEALTHY, "is healthy" },
1337	{ IPR_PATH_DEGRADED, "is degraded" },
1338	{ IPR_PATH_FAILED, "is failed" }
1339};
1340
1341/**
1342 * ipr_log_fabric_path - Log a fabric path error
1343 * @hostrcb:	hostrcb struct
1344 * @fabric:		fabric descriptor
1345 *
1346 * Return value:
1347 * 	none
1348 **/
1349static void ipr_log_fabric_path(struct ipr_hostrcb *hostrcb,
1350				struct ipr_hostrcb_fabric_desc *fabric)
1351{
1352	int i, j;
1353	u8 path_state = fabric->path_state;
1354	u8 active = path_state & IPR_PATH_ACTIVE_MASK;
1355	u8 state = path_state & IPR_PATH_STATE_MASK;
1356
1357	for (i = 0; i < ARRAY_SIZE(path_active_desc); i++) {
1358		if (path_active_desc[i].active != active)
1359			continue;
1360
1361		for (j = 0; j < ARRAY_SIZE(path_state_desc); j++) {
1362			if (path_state_desc[j].state != state)
1363				continue;
1364
1365			if (fabric->cascaded_expander == 0xff && fabric->phy == 0xff) {
1366				ipr_hcam_err(hostrcb, "%s %s: IOA Port=%d\n",
1367					     path_active_desc[i].desc, path_state_desc[j].desc,
1368					     fabric->ioa_port);
1369			} else if (fabric->cascaded_expander == 0xff) {
1370				ipr_hcam_err(hostrcb, "%s %s: IOA Port=%d, Phy=%d\n",
1371					     path_active_desc[i].desc, path_state_desc[j].desc,
1372					     fabric->ioa_port, fabric->phy);
1373			} else if (fabric->phy == 0xff) {
1374				ipr_hcam_err(hostrcb, "%s %s: IOA Port=%d, Cascade=%d\n",
1375					     path_active_desc[i].desc, path_state_desc[j].desc,
1376					     fabric->ioa_port, fabric->cascaded_expander);
1377			} else {
1378				ipr_hcam_err(hostrcb, "%s %s: IOA Port=%d, Cascade=%d, Phy=%d\n",
1379					     path_active_desc[i].desc, path_state_desc[j].desc,
1380					     fabric->ioa_port, fabric->cascaded_expander, fabric->phy);
1381			}
1382			return;
1383		}
1384	}
1385
1386	ipr_err("Path state=%02X IOA Port=%d Cascade=%d Phy=%d\n", path_state,
1387		fabric->ioa_port, fabric->cascaded_expander, fabric->phy);
1388}
1389
1390static const struct {
1391	u8 type;
1392	char *desc;
1393} path_type_desc[] = {
1394	{ IPR_PATH_CFG_IOA_PORT, "IOA port" },
1395	{ IPR_PATH_CFG_EXP_PORT, "Expander port" },
1396	{ IPR_PATH_CFG_DEVICE_PORT, "Device port" },
1397	{ IPR_PATH_CFG_DEVICE_LUN, "Device LUN" }
1398};
1399
1400static const struct {
1401	u8 status;
1402	char *desc;
1403} path_status_desc[] = {
1404	{ IPR_PATH_CFG_NO_PROB, "Functional" },
1405	{ IPR_PATH_CFG_DEGRADED, "Degraded" },
1406	{ IPR_PATH_CFG_FAILED, "Failed" },
1407	{ IPR_PATH_CFG_SUSPECT, "Suspect" },
1408	{ IPR_PATH_NOT_DETECTED, "Missing" },
1409	{ IPR_PATH_INCORRECT_CONN, "Incorrectly connected" }
1410};
1411
1412static const char *link_rate[] = {
1413	"unknown",
1414	"disabled",
1415	"phy reset problem",
1416	"spinup hold",
1417	"port selector",
1418	"unknown",
1419	"unknown",
1420	"unknown",
1421	"1.5Gbps",
1422	"3.0Gbps",
1423	"unknown",
1424	"unknown",
1425	"unknown",
1426	"unknown",
1427	"unknown",
1428	"unknown"
1429};
1430
1431/**
1432 * ipr_log_path_elem - Log a fabric path element.
1433 * @hostrcb:	hostrcb struct
1434 * @cfg:		fabric path element struct
1435 *
1436 * Return value:
1437 * 	none
1438 **/
1439static void ipr_log_path_elem(struct ipr_hostrcb *hostrcb,
1440			      struct ipr_hostrcb_config_element *cfg)
1441{
1442	int i, j;
1443	u8 type = cfg->type_status & IPR_PATH_CFG_TYPE_MASK;
1444	u8 status = cfg->type_status & IPR_PATH_CFG_STATUS_MASK;
1445
1446	if (type == IPR_PATH_CFG_NOT_EXIST)
1447		return;
1448
1449	for (i = 0; i < ARRAY_SIZE(path_type_desc); i++) {
1450		if (path_type_desc[i].type != type)
1451			continue;
1452
1453		for (j = 0; j < ARRAY_SIZE(path_status_desc); j++) {
1454			if (path_status_desc[j].status != status)
1455				continue;
1456
1457			if (type == IPR_PATH_CFG_IOA_PORT) {
1458				ipr_hcam_err(hostrcb, "%s %s: Phy=%d, Link rate=%s, WWN=%08X%08X\n",
1459					     path_status_desc[j].desc, path_type_desc[i].desc,
1460					     cfg->phy, link_rate[cfg->link_rate & IPR_PHY_LINK_RATE_MASK],
1461					     be32_to_cpu(cfg->wwid[0]), be32_to_cpu(cfg->wwid[1]));
1462			} else {
1463				if (cfg->cascaded_expander == 0xff && cfg->phy == 0xff) {
1464					ipr_hcam_err(hostrcb, "%s %s: Link rate=%s, WWN=%08X%08X\n",
1465						     path_status_desc[j].desc, path_type_desc[i].desc,
1466						     link_rate[cfg->link_rate & IPR_PHY_LINK_RATE_MASK],
1467						     be32_to_cpu(cfg->wwid[0]), be32_to_cpu(cfg->wwid[1]));
1468				} else if (cfg->cascaded_expander == 0xff) {
1469					ipr_hcam_err(hostrcb, "%s %s: Phy=%d, Link rate=%s, "
1470						     "WWN=%08X%08X\n", path_status_desc[j].desc,
1471						     path_type_desc[i].desc, cfg->phy,
1472						     link_rate[cfg->link_rate & IPR_PHY_LINK_RATE_MASK],
1473						     be32_to_cpu(cfg->wwid[0]), be32_to_cpu(cfg->wwid[1]));
1474				} else if (cfg->phy == 0xff) {
1475					ipr_hcam_err(hostrcb, "%s %s: Cascade=%d, Link rate=%s, "
1476						     "WWN=%08X%08X\n", path_status_desc[j].desc,
1477						     path_type_desc[i].desc, cfg->cascaded_expander,
1478						     link_rate[cfg->link_rate & IPR_PHY_LINK_RATE_MASK],
1479						     be32_to_cpu(cfg->wwid[0]), be32_to_cpu(cfg->wwid[1]));
1480				} else {
1481					ipr_hcam_err(hostrcb, "%s %s: Cascade=%d, Phy=%d, Link rate=%s "
1482						     "WWN=%08X%08X\n", path_status_desc[j].desc,
1483						     path_type_desc[i].desc, cfg->cascaded_expander, cfg->phy,
1484						     link_rate[cfg->link_rate & IPR_PHY_LINK_RATE_MASK],
1485						     be32_to_cpu(cfg->wwid[0]), be32_to_cpu(cfg->wwid[1]));
1486				}
1487			}
1488			return;
1489		}
1490	}
1491
1492	ipr_hcam_err(hostrcb, "Path element=%02X: Cascade=%d Phy=%d Link rate=%s "
1493		     "WWN=%08X%08X\n", cfg->type_status, cfg->cascaded_expander, cfg->phy,
1494		     link_rate[cfg->link_rate & IPR_PHY_LINK_RATE_MASK],
1495		     be32_to_cpu(cfg->wwid[0]), be32_to_cpu(cfg->wwid[1]));
1496}
1497
1498/**
1499 * ipr_log_fabric_error - Log a fabric error.
1500 * @ioa_cfg:	ioa config struct
1501 * @hostrcb:	hostrcb struct
1502 *
1503 * Return value:
1504 * 	none
1505 **/
1506static void ipr_log_fabric_error(struct ipr_ioa_cfg *ioa_cfg,
1507				 struct ipr_hostrcb *hostrcb)
1508{
1509	struct ipr_hostrcb_type_20_error *error;
1510	struct ipr_hostrcb_fabric_desc *fabric;
1511	struct ipr_hostrcb_config_element *cfg;
1512	int i, add_len;
1513
1514	error = &hostrcb->hcam.u.error.u.type_20_error;
1515	error->failure_reason[sizeof(error->failure_reason) - 1] = '\0';
1516	ipr_hcam_err(hostrcb, "%s\n", error->failure_reason);
1517
1518	add_len = be32_to_cpu(hostrcb->hcam.length) -
1519		(offsetof(struct ipr_hostrcb_error, u) +
1520		 offsetof(struct ipr_hostrcb_type_20_error, desc));
1521
1522	for (i = 0, fabric = error->desc; i < error->num_entries; i++) {
1523		ipr_log_fabric_path(hostrcb, fabric);
1524		for_each_fabric_cfg(fabric, cfg)
1525			ipr_log_path_elem(hostrcb, cfg);
1526
1527		add_len -= be16_to_cpu(fabric->length);
1528		fabric = (struct ipr_hostrcb_fabric_desc *)
1529			((unsigned long)fabric + be16_to_cpu(fabric->length));
1530	}
1531
1532	ipr_log_hex_data(ioa_cfg, (u32 *)fabric, add_len);
1533}
1534
1535/**
1536 * ipr_log_generic_error - Log an adapter error.
1537 * @ioa_cfg:	ioa config struct
1538 * @hostrcb:	hostrcb struct
1539 *
1540 * Return value:
1541 * 	none
1542 **/
1543static void ipr_log_generic_error(struct ipr_ioa_cfg *ioa_cfg,
1544				  struct ipr_hostrcb *hostrcb)
1545{
1546	ipr_log_hex_data(ioa_cfg, hostrcb->hcam.u.raw.data,
1547			 be32_to_cpu(hostrcb->hcam.length));
1548}
1549
1550/**
1551 * ipr_get_error - Find the specfied IOASC in the ipr_error_table.
1552 * @ioasc:	IOASC
1553 *
1554 * This function will return the index of into the ipr_error_table
1555 * for the specified IOASC. If the IOASC is not in the table,
1556 * 0 will be returned, which points to the entry used for unknown errors.
1557 *
1558 * Return value:
1559 * 	index into the ipr_error_table
1560 **/
1561static u32 ipr_get_error(u32 ioasc)
1562{
1563	int i;
1564
1565	for (i = 0; i < ARRAY_SIZE(ipr_error_table); i++)
1566		if (ipr_error_table[i].ioasc == (ioasc & IPR_IOASC_IOASC_MASK))
1567			return i;
1568
1569	return 0;
1570}
1571
1572/**
1573 * ipr_handle_log_data - Log an adapter error.
1574 * @ioa_cfg:	ioa config struct
1575 * @hostrcb:	hostrcb struct
1576 *
1577 * This function logs an adapter error to the system.
1578 *
1579 * Return value:
1580 * 	none
1581 **/
1582static void ipr_handle_log_data(struct ipr_ioa_cfg *ioa_cfg,
1583				struct ipr_hostrcb *hostrcb)
1584{
1585	u32 ioasc;
1586	int error_index;
1587
1588	if (hostrcb->hcam.notify_type != IPR_HOST_RCB_NOTIF_TYPE_ERROR_LOG_ENTRY)
1589		return;
1590
1591	if (hostrcb->hcam.notifications_lost == IPR_HOST_RCB_NOTIFICATIONS_LOST)
1592		dev_err(&ioa_cfg->pdev->dev, "Error notifications lost\n");
1593
1594	ioasc = be32_to_cpu(hostrcb->hcam.u.error.failing_dev_ioasc);
1595
1596	if (ioasc == IPR_IOASC_BUS_WAS_RESET ||
1597	    ioasc == IPR_IOASC_BUS_WAS_RESET_BY_OTHER) {
1598		/* Tell the midlayer we had a bus reset so it will handle the UA properly */
1599		scsi_report_bus_reset(ioa_cfg->host,
1600				      hostrcb->hcam.u.error.failing_dev_res_addr.bus);
1601	}
1602
1603	error_index = ipr_get_error(ioasc);
1604
1605	if (!ipr_error_table[error_index].log_hcam)
1606		return;
1607
1608	ipr_hcam_err(hostrcb, "%s\n", ipr_error_table[error_index].error);
1609
1610	/* Set indication we have logged an error */
1611	ioa_cfg->errors_logged++;
1612
1613	if (ioa_cfg->log_level < IPR_DEFAULT_LOG_LEVEL)
1614		return;
1615	if (be32_to_cpu(hostrcb->hcam.length) > sizeof(hostrcb->hcam.u.raw))
1616		hostrcb->hcam.length = cpu_to_be32(sizeof(hostrcb->hcam.u.raw));
1617
1618	switch (hostrcb->hcam.overlay_id) {
1619	case IPR_HOST_RCB_OVERLAY_ID_2:
1620		ipr_log_cache_error(ioa_cfg, hostrcb);
1621		break;
1622	case IPR_HOST_RCB_OVERLAY_ID_3:
1623		ipr_log_config_error(ioa_cfg, hostrcb);
1624		break;
1625	case IPR_HOST_RCB_OVERLAY_ID_4:
1626	case IPR_HOST_RCB_OVERLAY_ID_6:
1627		ipr_log_array_error(ioa_cfg, hostrcb);
1628		break;
1629	case IPR_HOST_RCB_OVERLAY_ID_7:
1630		ipr_log_dual_ioa_error(ioa_cfg, hostrcb);
1631		break;
1632	case IPR_HOST_RCB_OVERLAY_ID_12:
1633		ipr_log_enhanced_cache_error(ioa_cfg, hostrcb);
1634		break;
1635	case IPR_HOST_RCB_OVERLAY_ID_13:
1636		ipr_log_enhanced_config_error(ioa_cfg, hostrcb);
1637		break;
1638	case IPR_HOST_RCB_OVERLAY_ID_14:
1639	case IPR_HOST_RCB_OVERLAY_ID_16:
1640		ipr_log_enhanced_array_error(ioa_cfg, hostrcb);
1641		break;
1642	case IPR_HOST_RCB_OVERLAY_ID_17:
1643		ipr_log_enhanced_dual_ioa_error(ioa_cfg, hostrcb);
1644		break;
1645	case IPR_HOST_RCB_OVERLAY_ID_20:
1646		ipr_log_fabric_error(ioa_cfg, hostrcb);
1647		break;
1648	case IPR_HOST_RCB_OVERLAY_ID_1:
1649	case IPR_HOST_RCB_OVERLAY_ID_DEFAULT:
1650	default:
1651		ipr_log_generic_error(ioa_cfg, hostrcb);
1652		break;
1653	}
1654}
1655
1656/**
1657 * ipr_process_error - Op done function for an adapter error log.
1658 * @ipr_cmd:	ipr command struct
1659 *
1660 * This function is the op done function for an error log host
1661 * controlled async from the adapter. It will log the error and
1662 * send the HCAM back to the adapter.
1663 *
1664 * Return value:
1665 * 	none
1666 **/
1667static void ipr_process_error(struct ipr_cmnd *ipr_cmd)
1668{
1669	struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
1670	struct ipr_hostrcb *hostrcb = ipr_cmd->u.hostrcb;
1671	u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc);
1672
1673	list_del(&hostrcb->queue);
1674	list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q);
1675
1676	if (!ioasc) {
1677		ipr_handle_log_data(ioa_cfg, hostrcb);
1678	} else if (ioasc != IPR_IOASC_IOA_WAS_RESET) {
1679		dev_err(&ioa_cfg->pdev->dev,
1680			"Host RCB failed with IOASC: 0x%08X\n", ioasc);
1681	}
1682
1683	ipr_send_hcam(ioa_cfg, IPR_HCAM_CDB_OP_CODE_LOG_DATA, hostrcb);
1684}
1685
1686/**
1687 * ipr_timeout -  An internally generated op has timed out.
1688 * @ipr_cmd:	ipr command struct
1689 *
1690 * This function blocks host requests and initiates an
1691 * adapter reset.
1692 *
1693 * Return value:
1694 *…

Large files files are truncated, but you can click here to view the full file