Commit a3b4924b authored by Linus Torvalds's avatar Linus Torvalds

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

Pull more SCSI updates from James Bottomley:
 "This is the set of stuff that didn't quite make the initial pull and a
  set of fixes for stuff which did.

  The new stuff is basically lpfc (nvme), qedi and aacraid. The fixes
  cover a lot of previously submitted stuff, the most important of which
  probably covers some of the failing irq vectors allocation and other
  fallout from having the SCSI command allocated as part of the block
  allocation functions"

* tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: (59 commits)
  scsi: qedi: Fix memory leak in tmf response processing.
  scsi: aacraid: remove redundant zero check on ret
  scsi: lpfc: use proper format string for dma_addr_t
  scsi: lpfc: use div_u64 for 64-bit division
  scsi: mac_scsi: Fix MAC_SCSI=m option when SCSI=m
  scsi: cciss: correct check map error.
  scsi: qla2xxx: fix spelling mistake: "seperator" -> "separator"
  scsi: aacraid: Fixed expander hotplug for SMART family
  scsi: mpt3sas: switch to pci_alloc_irq_vectors
  scsi: qedf: fixup compilation warning about atomic_t usage
  scsi: remove scsi_execute_req_flags
  scsi: merge __scsi_execute into scsi_execute
  scsi: simplify scsi_execute_req_flags
  scsi: make the sense header argument to scsi_test_unit_ready mandatory
  scsi: sd: improve TUR handling in sd_check_events
  scsi: always zero sshdr in scsi_normalize_sense
  scsi: scsi_dh_emc: return success in clariion_std_inquiry()
  scsi: fix memory leak of sdpk on when gd fails to allocate
  scsi: sd: make sd_devt_release() static
  scsi: qedf: Add QLogic FastLinQ offload FCoE driver framework.
  ...
parents 0b94da8d 42a70abd
......@@ -10336,6 +10336,12 @@ L: linux-scsi@vger.kernel.org
S: Supported
F: drivers/scsi/qedi/
QLOGIC QL41xxx FCOE DRIVER
M: QLogic-Storage-Upstream@cavium.com
L: linux-scsi@vger.kernel.org
S: Supported
F: drivers/scsi/qedf/
QNX4 FILESYSTEM
M: Anders Larsen <al@alarsen.net>
W: http://www.alarsen.net/linux/qnx4fs/
......
......@@ -600,6 +600,7 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg)
u8 args[4], *argbuf = NULL, *sensebuf = NULL;
int argsize = 0;
enum dma_data_direction data_dir;
struct scsi_sense_hdr sshdr;
int cmd_result;
if (arg == NULL)
......@@ -648,7 +649,7 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg)
/* Good values for timeout and retries? Values below
from scsi_ioctl_send_command() for default case... */
cmd_result = scsi_execute(scsidev, scsi_cmd, data_dir, argbuf, argsize,
sensebuf, (10*HZ), 5, 0, NULL);
sensebuf, &sshdr, (10*HZ), 5, 0, 0, NULL);
if (driver_byte(cmd_result) == DRIVER_SENSE) {/* sense data available */
u8 *desc = sensebuf + 8;
......@@ -657,9 +658,6 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg)
/* If we set cc then ATA pass-through will cause a
* check condition even if no error. Filter that. */
if (cmd_result & SAM_STAT_CHECK_CONDITION) {
struct scsi_sense_hdr sshdr;
scsi_normalize_sense(sensebuf, SCSI_SENSE_BUFFERSIZE,
&sshdr);
if (sshdr.sense_key == RECOVERED_ERROR &&
sshdr.asc == 0 && sshdr.ascq == 0x1d)
cmd_result &= ~SAM_STAT_CHECK_CONDITION;
......@@ -707,6 +705,7 @@ int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg)
int rc = 0;
u8 scsi_cmd[MAX_COMMAND_SIZE];
u8 args[7], *sensebuf = NULL;
struct scsi_sense_hdr sshdr;
int cmd_result;
if (arg == NULL)
......@@ -734,7 +733,7 @@ int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg)
/* Good values for timeout and retries? Values below
from scsi_ioctl_send_command() for default case... */
cmd_result = scsi_execute(scsidev, scsi_cmd, DMA_NONE, NULL, 0,
sensebuf, (10*HZ), 5, 0, NULL);
sensebuf, &sshdr, (10*HZ), 5, 0, 0, NULL);
if (driver_byte(cmd_result) == DRIVER_SENSE) {/* sense data available */
u8 *desc = sensebuf + 8;
......@@ -743,9 +742,6 @@ int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg)
/* If we set cc then ATA pass-through will cause a
* check condition even if no error. Filter that. */
if (cmd_result & SAM_STAT_CHECK_CONDITION) {
struct scsi_sense_hdr sshdr;
scsi_normalize_sense(sensebuf, SCSI_SENSE_BUFFERSIZE,
&sshdr);
if (sshdr.sense_key == RECOVERED_ERROR &&
sshdr.asc == 0 && sshdr.ascq == 0x1d)
cmd_result &= ~SAM_STAT_CHECK_CONDITION;
......
......@@ -348,7 +348,7 @@ static void cciss_unmap_sg_chain_block(ctlr_info_t *h, CommandList_struct *c)
pci_unmap_single(h->pdev, temp64.val, chain_sg->Len, PCI_DMA_TODEVICE);
}
static void cciss_map_sg_chain_block(ctlr_info_t *h, CommandList_struct *c,
static int cciss_map_sg_chain_block(ctlr_info_t *h, CommandList_struct *c,
SGDescriptor_struct *chain_block, int len)
{
SGDescriptor_struct *chain_sg;
......@@ -359,8 +359,16 @@ static void cciss_map_sg_chain_block(ctlr_info_t *h, CommandList_struct *c,
chain_sg->Len = len;
temp64.val = pci_map_single(h->pdev, chain_block, len,
PCI_DMA_TODEVICE);
if (dma_mapping_error(&h->pdev->dev, temp64.val)) {
dev_warn(&h->pdev->dev,
"%s: error mapping chain block for DMA\n",
__func__);
return -1;
}
chain_sg->Addr.lower = temp64.val32.lower;
chain_sg->Addr.upper = temp64.val32.upper;
return 0;
}
#include "cciss_scsi.c" /* For SCSI tape support */
......@@ -3369,15 +3377,31 @@ static void do_cciss_request(struct request_queue *q)
temp64.val = (__u64) pci_map_page(h->pdev, sg_page(&tmp_sg[i]),
tmp_sg[i].offset,
tmp_sg[i].length, dir);
if (dma_mapping_error(&h->pdev->dev, temp64.val)) {
dev_warn(&h->pdev->dev,
"%s: error mapping page for DMA\n", __func__);
creq->errors = make_status_bytes(SAM_STAT_GOOD,
0, DRIVER_OK,
DID_SOFT_ERROR);
cmd_free(h, c);
return;
}
curr_sg[sg_index].Addr.lower = temp64.val32.lower;
curr_sg[sg_index].Addr.upper = temp64.val32.upper;
curr_sg[sg_index].Ext = 0; /* we are not chaining */
++sg_index;
}
if (chained)
cciss_map_sg_chain_block(h, c, h->cmd_sg_list[c->cmdindex],
if (chained) {
if (cciss_map_sg_chain_block(h, c, h->cmd_sg_list[c->cmdindex],
(seg - (h->max_cmd_sgentries - 1)) *
sizeof(SGDescriptor_struct));
sizeof(SGDescriptor_struct))) {
creq->errors = make_status_bytes(SAM_STAT_GOOD,
0, DRIVER_OK,
DID_SOFT_ERROR);
cmd_free(h, c);
return;
}
}
/* track how many SG entries we are using */
if (seg > h->maxSG)
......
......@@ -1235,11 +1235,13 @@ config SCSI_QLOGICPTI
source "drivers/scsi/qla2xxx/Kconfig"
source "drivers/scsi/qla4xxx/Kconfig"
source "drivers/scsi/qedi/Kconfig"
source "drivers/scsi/qedf/Kconfig"
config SCSI_LPFC
tristate "Emulex LightPulse Fibre Channel Support"
depends on PCI && SCSI
depends on SCSI_FC_ATTRS
depends on NVME_FC && NVME_TARGET_FC
select CRC_T10DIF
help
This lpfc driver supports the Emulex LightPulse
......@@ -1478,7 +1480,7 @@ config ATARI_SCSI
config MAC_SCSI
tristate "Macintosh NCR5380 SCSI"
depends on MAC && SCSI=y
depends on MAC && SCSI
select SCSI_SPI_ATTRS
help
This is the NCR 5380 SCSI controller included on most of the 68030
......
......@@ -41,6 +41,7 @@ obj-$(CONFIG_FCOE) += fcoe/
obj-$(CONFIG_FCOE_FNIC) += fnic/
obj-$(CONFIG_SCSI_SNIC) += snic/
obj-$(CONFIG_SCSI_BNX2X_FCOE) += libfc/ fcoe/ bnx2fc/
obj-$(CONFIG_QEDF) += qedf/
obj-$(CONFIG_ISCSI_TCP) += libiscsi.o libiscsi_tcp.o iscsi_tcp.o
obj-$(CONFIG_INFINIBAND_ISER) += libiscsi.o
obj-$(CONFIG_ISCSI_BOOT_SYSFS) += iscsi_boot_sysfs.o
......
......@@ -294,6 +294,10 @@ MODULE_PARM_DESC(aif_timeout, "The duration of time in seconds to wait for"
"deregistering them. This is typically adjusted for heavily burdened"
" systems.");
int aac_fib_dump;
module_param(aac_fib_dump, int, 0644);
MODULE_PARM_DESC(aac_fib_dump, "Dump controller fibs prior to IOP_RESET 0=off, 1=on");
int numacb = -1;
module_param(numacb, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(numacb, "Request a limit to the number of adapter control"
......@@ -311,7 +315,7 @@ module_param(update_interval, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(update_interval, "Interval in seconds between time sync"
" updates issued to adapter.");
int check_interval = 24 * 60 * 60;
int check_interval = 60;
module_param(check_interval, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(check_interval, "Interval in seconds between adapter health"
" checks.");
......@@ -483,7 +487,7 @@ int aac_get_containers(struct aac_dev *dev)
if (status >= 0) {
dresp = (struct aac_get_container_count_resp *)fib_data(fibptr);
maximum_num_containers = le32_to_cpu(dresp->ContainerSwitchEntries);
if (fibptr->dev->supplement_adapter_info.SupportedOptions2 &
if (fibptr->dev->supplement_adapter_info.supported_options2 &
AAC_OPTION_SUPPORTED_240_VOLUMES) {
maximum_num_containers =
le32_to_cpu(dresp->MaxSimpleVolumes);
......@@ -639,13 +643,16 @@ static void _aac_probe_container2(void * context, struct fib * fibptr)
fsa_dev_ptr = fibptr->dev->fsa_dev;
if (fsa_dev_ptr) {
struct aac_mount * dresp = (struct aac_mount *) fib_data(fibptr);
__le32 sup_options2;
fsa_dev_ptr += scmd_id(scsicmd);
sup_options2 =
fibptr->dev->supplement_adapter_info.supported_options2;
if ((le32_to_cpu(dresp->status) == ST_OK) &&
(le32_to_cpu(dresp->mnt[0].vol) != CT_NONE) &&
(le32_to_cpu(dresp->mnt[0].state) != FSCS_HIDDEN)) {
if (!(fibptr->dev->supplement_adapter_info.SupportedOptions2 &
AAC_OPTION_VARIABLE_BLOCK_SIZE)) {
if (!(sup_options2 & AAC_OPTION_VARIABLE_BLOCK_SIZE)) {
dresp->mnt[0].fileinfo.bdevinfo.block_size = 0x200;
fsa_dev_ptr->block_size = 0x200;
} else {
......@@ -688,7 +695,7 @@ static void _aac_probe_container1(void * context, struct fib * fibptr)
int status;
dresp = (struct aac_mount *) fib_data(fibptr);
if (!(fibptr->dev->supplement_adapter_info.SupportedOptions2 &
if (!(fibptr->dev->supplement_adapter_info.supported_options2 &
AAC_OPTION_VARIABLE_BLOCK_SIZE))
dresp->mnt[0].capacityhigh = 0;
if ((le32_to_cpu(dresp->status) != ST_OK) ||
......@@ -705,7 +712,7 @@ static void _aac_probe_container1(void * context, struct fib * fibptr)
dinfo = (struct aac_query_mount *)fib_data(fibptr);
if (fibptr->dev->supplement_adapter_info.SupportedOptions2 &
if (fibptr->dev->supplement_adapter_info.supported_options2 &
AAC_OPTION_VARIABLE_BLOCK_SIZE)
dinfo->command = cpu_to_le32(VM_NameServeAllBlk);
else
......@@ -745,7 +752,7 @@ static int _aac_probe_container(struct scsi_cmnd * scsicmd, int (*callback)(stru
dinfo = (struct aac_query_mount *)fib_data(fibptr);
if (fibptr->dev->supplement_adapter_info.SupportedOptions2 &
if (fibptr->dev->supplement_adapter_info.supported_options2 &
AAC_OPTION_VARIABLE_BLOCK_SIZE)
dinfo->command = cpu_to_le32(VM_NameServeAllBlk);
else
......@@ -896,12 +903,14 @@ char * get_container_type(unsigned tindex)
static void setinqstr(struct aac_dev *dev, void *data, int tindex)
{
struct scsi_inq *str;
struct aac_supplement_adapter_info *sup_adap_info;
sup_adap_info = &dev->supplement_adapter_info;
str = (struct scsi_inq *)(data); /* cast data to scsi inq block */
memset(str, ' ', sizeof(*str));
if (dev->supplement_adapter_info.AdapterTypeText[0]) {
char * cp = dev->supplement_adapter_info.AdapterTypeText;
if (sup_adap_info->adapter_type_text[0]) {
char *cp = sup_adap_info->adapter_type_text;
int c;
if ((cp[0] == 'A') && (cp[1] == 'O') && (cp[2] == 'C'))
inqstrcpy("SMC", str->vid);
......@@ -911,8 +920,7 @@ static void setinqstr(struct aac_dev *dev, void *data, int tindex)
++cp;
c = *cp;
*cp = '\0';
inqstrcpy (dev->supplement_adapter_info.AdapterTypeText,
str->vid);
inqstrcpy(sup_adap_info->adapter_type_text, str->vid);
*cp = c;
while (*cp && *cp != ' ')
++cp;
......@@ -1675,8 +1683,8 @@ int aac_issue_bmic_identify(struct aac_dev *dev, u32 bus, u32 target)
if (!identify_resp)
goto fib_free_ptr;
vbus = (u32)le16_to_cpu(dev->supplement_adapter_info.VirtDeviceBus);
vid = (u32)le16_to_cpu(dev->supplement_adapter_info.VirtDeviceTarget);
vbus = (u32)le16_to_cpu(dev->supplement_adapter_info.virt_device_bus);
vid = (u32)le16_to_cpu(dev->supplement_adapter_info.virt_device_target);
aac_fib_init(fibptr);
......@@ -1815,9 +1823,9 @@ int aac_report_phys_luns(struct aac_dev *dev, struct fib *fibptr, int rescan)
}
vbus = (u32) le16_to_cpu(
dev->supplement_adapter_info.VirtDeviceBus);
dev->supplement_adapter_info.virt_device_bus);
vid = (u32) le16_to_cpu(
dev->supplement_adapter_info.VirtDeviceTarget);
dev->supplement_adapter_info.virt_device_target);
aac_fib_init(fibptr);
......@@ -1893,7 +1901,7 @@ int aac_get_adapter_info(struct aac_dev* dev)
}
memcpy(&dev->adapter_info, info, sizeof(*info));
dev->supplement_adapter_info.VirtDeviceBus = 0xffff;
dev->supplement_adapter_info.virt_device_bus = 0xffff;
if (dev->adapter_info.options & AAC_OPT_SUPPLEMENT_ADAPTER_INFO) {
struct aac_supplement_adapter_info * sinfo;
......@@ -1961,7 +1969,7 @@ int aac_get_adapter_info(struct aac_dev* dev)
}
if (!dev->sync_mode && dev->sa_firmware &&
dev->supplement_adapter_info.VirtDeviceBus != 0xffff) {
dev->supplement_adapter_info.virt_device_bus != 0xffff) {
/* Thor SA Firmware -> CISS_REPORT_PHYSICAL_LUNS */
rcode = aac_report_phys_luns(dev, fibptr, AAC_INIT);
}
......@@ -1976,8 +1984,8 @@ int aac_get_adapter_info(struct aac_dev* dev)
(tmp>>16)&0xff,
tmp&0xff,
le32_to_cpu(dev->adapter_info.kernelbuild),
(int)sizeof(dev->supplement_adapter_info.BuildDate),
dev->supplement_adapter_info.BuildDate);
(int)sizeof(dev->supplement_adapter_info.build_date),
dev->supplement_adapter_info.build_date);
tmp = le32_to_cpu(dev->adapter_info.monitorrev);
printk(KERN_INFO "%s%d: monitor %d.%d-%d[%d]\n",
dev->name, dev->id,
......@@ -1993,14 +2001,15 @@ int aac_get_adapter_info(struct aac_dev* dev)
shost_to_class(dev->scsi_host_ptr), buffer))
printk(KERN_INFO "%s%d: serial %s",
dev->name, dev->id, buffer);
if (dev->supplement_adapter_info.VpdInfo.Tsid[0]) {
if (dev->supplement_adapter_info.vpd_info.tsid[0]) {
printk(KERN_INFO "%s%d: TSID %.*s\n",
dev->name, dev->id,
(int)sizeof(dev->supplement_adapter_info.VpdInfo.Tsid),
dev->supplement_adapter_info.VpdInfo.Tsid);
(int)sizeof(dev->supplement_adapter_info
.vpd_info.tsid),
dev->supplement_adapter_info.vpd_info.tsid);
}
if (!aac_check_reset || ((aac_check_reset == 1) &&
(dev->supplement_adapter_info.SupportedOptions2 &
(dev->supplement_adapter_info.supported_options2 &
AAC_OPTION_IGNORE_RESET))) {
printk(KERN_INFO "%s%d: Reset Adapter Ignored\n",
dev->name, dev->id);
......@@ -2008,7 +2017,7 @@ int aac_get_adapter_info(struct aac_dev* dev)
}
dev->cache_protected = 0;
dev->jbod = ((dev->supplement_adapter_info.FeatureBits &
dev->jbod = ((dev->supplement_adapter_info.feature_bits &
AAC_FEATURE_JBOD) != 0);
dev->nondasd_support = 0;
dev->raid_scsi_mode = 0;
......@@ -2631,7 +2640,7 @@ static int aac_start_stop(struct scsi_cmnd *scsicmd)
struct scsi_device *sdev = scsicmd->device;
struct aac_dev *aac = (struct aac_dev *)sdev->host->hostdata;
if (!(aac->supplement_adapter_info.SupportedOptions2 &
if (!(aac->supplement_adapter_info.supported_options2 &
AAC_OPTION_POWER_MANAGEMENT)) {
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
SAM_STAT_GOOD;
......
......@@ -97,7 +97,7 @@ enum {
#define PMC_GLOBAL_INT_BIT0 0x00000001
#ifndef AAC_DRIVER_BUILD
# define AAC_DRIVER_BUILD 50740
# define AAC_DRIVER_BUILD 50792
# define AAC_DRIVER_BRANCH "-custom"
#endif
#define MAXIMUM_NUM_CONTAINERS 32
......@@ -1380,57 +1380,57 @@ struct aac_adapter_info
struct aac_supplement_adapter_info
{
u8 AdapterTypeText[17+1];
u8 Pad[2];
__le32 FlashMemoryByteSize;
__le32 FlashImageId;
__le32 MaxNumberPorts;
__le32 Version;
__le32 FeatureBits;
u8 SlotNumber;
u8 ReservedPad0[3];
u8 BuildDate[12];
__le32 CurrentNumberPorts;
u8 adapter_type_text[17+1];
u8 pad[2];
__le32 flash_memory_byte_size;
__le32 flash_image_id;
__le32 max_number_ports;
__le32 version;
__le32 feature_bits;
u8 slot_number;
u8 reserved_pad0[3];
u8 build_date[12];
__le32 current_number_ports;
struct {
u8 AssemblyPn[8];
u8 FruPn[8];
u8 BatteryFruPn[8];
u8 EcVersionString[8];
u8 Tsid[12];
} VpdInfo;
__le32 FlashFirmwareRevision;
__le32 FlashFirmwareBuild;
__le32 RaidTypeMorphOptions;
__le32 FlashFirmwareBootRevision;
__le32 FlashFirmwareBootBuild;
u8 MfgPcbaSerialNo[12];
u8 MfgWWNName[8];
__le32 SupportedOptions2;
__le32 StructExpansion;
u8 assembly_pn[8];
u8 fru_pn[8];
u8 battery_fru_pn[8];
u8 ec_version_string[8];
u8 tsid[12];
} vpd_info;
__le32 flash_firmware_revision;
__le32 flash_firmware_build;
__le32 raid_type_morph_options;
__le32 flash_firmware_boot_revision;
__le32 flash_firmware_boot_build;
u8 mfg_pcba_serial_no[12];
u8 mfg_wwn_name[8];
__le32 supported_options2;
__le32 struct_expansion;
/* StructExpansion == 1 */
__le32 FeatureBits3;
__le32 SupportedPerformanceModes;
u8 HostBusType; /* uses HOST_BUS_TYPE_xxx defines */
u8 HostBusWidth; /* actual width in bits or links */
u16 HostBusSpeed; /* actual bus speed/link rate in MHz */
u8 MaxRRCDrives; /* max. number of ITP-RRC drives/pool */
u8 MaxDiskXtasks; /* max. possible num of DiskX Tasks */
u8 CpldVerLoaded;
u8 CpldVerInFlash;
__le64 MaxRRCCapacity;
__le32 CompiledMaxHistLogLevel;
u8 CustomBoardName[12];
u16 SupportedCntlrMode; /* identify supported controller mode */
u16 ReservedForFuture16;
__le32 SupportedOptions3; /* reserved for future options */
__le16 VirtDeviceBus; /* virt. SCSI device for Thor */
__le16 VirtDeviceTarget;
__le16 VirtDeviceLUN;
__le16 Unused;
__le32 ReservedForFutureGrowth[68];
__le32 feature_bits3;
__le32 supported_performance_modes;
u8 host_bus_type; /* uses HOST_BUS_TYPE_xxx defines */
u8 host_bus_width; /* actual width in bits or links */
u16 host_bus_speed; /* actual bus speed/link rate in MHz */
u8 max_rrc_drives; /* max. number of ITP-RRC drives/pool */
u8 max_disk_xtasks; /* max. possible num of DiskX Tasks */
u8 cpld_ver_loaded;
u8 cpld_ver_in_flash;
__le64 max_rrc_capacity;
__le32 compiled_max_hist_log_level;
u8 custom_board_name[12];
u16 supported_cntlr_mode; /* identify supported controller mode */
u16 reserved_for_future16;
__le32 supported_options3; /* reserved for future options */
__le16 virt_device_bus; /* virt. SCSI device for Thor */
__le16 virt_device_target;
__le16 virt_device_lun;
__le16 unused;
__le32 reserved_for_future_growth[68];
};
#define AAC_FEATURE_FALCON cpu_to_le32(0x00000010)
......@@ -1444,6 +1444,10 @@ struct aac_supplement_adapter_info
#define AAC_OPTION_VARIABLE_BLOCK_SIZE cpu_to_le32(0x00040000)
/* 240 simple volume support */
#define AAC_OPTION_SUPPORTED_240_VOLUMES cpu_to_le32(0x10000000)
/*
* Supports FIB dump sync command send prior to IOP_RESET
*/
#define AAC_OPTION_SUPPORTED3_IOP_RESET_FIB_DUMP cpu_to_le32(0x00004000)
#define AAC_SIS_VERSION_V3 3
#define AAC_SIS_SLOT_UNKNOWN 0xFF
......@@ -2483,6 +2487,7 @@ struct aac_hba_info {
#define GET_DRIVER_BUFFER_PROPERTIES 0x00000023
#define RCV_TEMP_READINGS 0x00000025
#define GET_COMM_PREFERRED_SETTINGS 0x00000026
#define IOP_RESET_FW_FIB_DUMP 0x00000034
#define IOP_RESET 0x00001000
#define IOP_RESET_ALWAYS 0x00001001
#define RE_INIT_ADAPTER 0x000000ee
......@@ -2639,6 +2644,7 @@ void aac_hba_callback(void *context, struct fib *fibptr);
#define fib_data(fibctx) ((void *)(fibctx)->hw_fib_va->data)
struct aac_dev *aac_init_adapter(struct aac_dev *dev);
void aac_src_access_devreg(struct aac_dev *dev, int mode);
void aac_set_intx_mode(struct aac_dev *dev);
int aac_get_config_status(struct aac_dev *dev, int commit_flag);
int aac_get_containers(struct aac_dev *dev);
int aac_scsi_cmd(struct scsi_cmnd *cmd);
......@@ -2685,4 +2691,5 @@ extern int aac_commit;
extern int update_interval;
extern int check_interval;
extern int aac_check_reset;
extern int aac_fib_dump;
#endif
......@@ -580,7 +580,7 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
goto cleanup;
}
chn = aac_logical_to_phys(user_srbcmd->channel);
chn = user_srbcmd->channel;
if (chn < AAC_MAX_BUSES && user_srbcmd->id < AAC_MAX_TARGETS &&
dev->hba_map[chn][user_srbcmd->id].devtype ==
AAC_DEVTYPE_NATIVE_RAW) {
......
......@@ -330,7 +330,7 @@ int aac_send_shutdown(struct aac_dev * dev)
dev->pdev->device == PMC_DEVICE_S8 ||
dev->pdev->device == PMC_DEVICE_S9) &&
dev->msi_enabled)
aac_src_access_devreg(dev, AAC_ENABLE_INTX);
aac_set_intx_mode(dev);
return status;
}
......
......@@ -95,12 +95,20 @@ static int fib_map_alloc(struct aac_dev *dev)
void aac_fib_map_free(struct aac_dev *dev)
{
if (dev->hw_fib_va && dev->max_cmd_size) {
pci_free_consistent(dev->pdev,
(dev->max_cmd_size *
(dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB)),
dev->hw_fib_va, dev->hw_fib_pa);
}
size_t alloc_size;
size_t fib_size;
int num_fibs;
if(!dev->hw_fib_va || !dev->max_cmd_size)
return;
num_fibs = dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB;
fib_size = dev->max_fib_size + sizeof(struct aac_fib_xporthdr);
alloc_size = fib_size * num_fibs + ALIGN32 - 1;
pci_free_consistent(dev->pdev, alloc_size, dev->hw_fib_va,
dev->hw_fib_pa);
dev->hw_fib_va = NULL;
dev->hw_fib_pa = 0;
}
......@@ -153,22 +161,20 @@ int aac_fib_setup(struct aac_dev * dev)
if (i<0)
return -ENOMEM;
/* 32 byte alignment for PMC */
hw_fib_pa = (dev->hw_fib_pa + (ALIGN32 - 1)) & ~(ALIGN32 - 1);
dev->hw_fib_va = (struct hw_fib *)((unsigned char *)dev->hw_fib_va +
(hw_fib_pa - dev->hw_fib_pa));
dev->hw_fib_pa = hw_fib_pa;
memset(dev->hw_fib_va, 0,
(dev->max_cmd_size + sizeof(struct aac_fib_xporthdr)) *
(dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB));
/* 32 byte alignment for PMC */
hw_fib_pa = (dev->hw_fib_pa + (ALIGN32 - 1)) & ~(ALIGN32 - 1);
hw_fib = (struct hw_fib *)((unsigned char *)dev->hw_fib_va +
(hw_fib_pa - dev->hw_fib_pa));
/* add Xport header */
dev->hw_fib_va = (struct hw_fib *)((unsigned char *)dev->hw_fib_va +
hw_fib = (struct hw_fib *)((unsigned char *)hw_fib +
sizeof(struct aac_fib_xporthdr));
dev->hw_fib_pa += sizeof(struct aac_fib_xporthdr);
hw_fib_pa += sizeof(struct aac_fib_xporthdr);
hw_fib = dev->hw_fib_va;
hw_fib_pa = dev->hw_fib_pa;
/*
* Initialise the fibs
*/
......@@ -461,6 +467,35 @@ int aac_queue_get(struct aac_dev * dev, u32 * index, u32 qid, struct hw_fib * hw
return 0;
}
#ifdef CONFIG_EEH
static inline int aac_check_eeh_failure(struct aac_dev *dev)
{
/* Check for an EEH failure for the given
* device node. Function eeh_dev_check_failure()
* returns 0 if there has not been an EEH error
* otherwise returns a non-zero value.
*
* Need to be called before any PCI operation,
* i.e.,before aac_adapter_check_health()
*/
struct eeh_dev *edev = pci_dev_to_eeh_dev(dev->pdev);
if (eeh_dev_check_failure(edev)) {
/* The EEH mechanisms will handle this
* error and reset the device if
* necessary.
*/
return 1;
}
return 0;
}
#else
static inline int aac_check_eeh_failure(struct aac_dev *dev)
{
return 0;
}
#endif
/*
* Define the highest level of host to adapter communication routines.
* These routines will support host to adapter FS commuication. These
......@@ -496,9 +531,12 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size,
unsigned long mflags = 0;
unsigned long sflags = 0;
if (!(hw_fib->header.XferState & cpu_to_le32(HostOwned)))
return -EBUSY;
if (hw_fib->header.XferState & cpu_to_le32(AdapterProcessed))
return -EINVAL;
/*
* There are 5 cases with the wait and response requested flags.
* The only invalid cases are if the caller requests to wait and
......@@ -662,6 +700,10 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size,
}
return -ETIMEDOUT;
}
if (aac_check_eeh_failure(dev))
return -EFAULT;
if ((blink = aac_adapter_check_health(dev)) > 0) {
if (wait == -1) {
printk(KERN_ERR "aacraid: aac_fib_send: adapter blinkLED 0x%x.\n"
......@@ -755,7 +797,12 @@ int aac_hba_send(u8 command, struct fib *fibptr, fib_callback callback,
FIB_COUNTER_INCREMENT(aac_config.NativeSent);
if (wait) {
spin_unlock_irqrestore(&fibptr->event_lock, flags);
if (aac_check_eeh_failure(dev))
return -EFAULT;
/* Only set for first known interruptable command */
if (down_interruptible(&fibptr->event_wait)) {
fibptr->done = 2;
......@@ -1590,11 +1637,29 @@ static int _aac_reset_adapter(struct aac_dev *aac, int forced, u8 reset_type)
command->SCp.phase = AAC_OWNER_ERROR_HANDLER;
command->scsi_done(command);
}
/*
* Any Device that was already marked offline needs to be cleaned up
*/
__shost_for_each_device(dev, host) {
if (!scsi_device_online(dev)) {
sdev_printk(KERN_INFO, dev, "Removing offline device\n");
scsi_remove_device(dev);
scsi_device_put(dev);
}
}
retval = 0;
out:
aac->in_reset = 0;
scsi_unblock_requests(host);
/*
* Issue bus rescan to catch any configuration that might have
* occurred
*/
if (!retval) {
dev_info(&aac->pdev->dev, "Issuing bus rescan\n");
scsi_scan_host(host);
}
if (jafo) {
spin_lock_irq(host->host_lock);
}
......@@ -1815,7 +1880,7 @@ int aac_check_health(struct aac_dev * aac)
printk(KERN_ERR "%s: Host adapter BLINK LED 0x%x\n", aac->name, BlinkLED);
if (!aac_check_reset || ((aac_check_reset == 1) &&
(aac->supplement_adapter_info.SupportedOptions2 &
(aac->supplement_adapter_info.supported_options2 &
AAC_OPTION_IGNORE_RESET)))
goto out;
host = aac->scsi_host_ptr;
......@@ -1843,9 +1908,6 @@ static void aac_resolve_luns(struct aac_dev *dev)
for (bus = 0; bus < AAC_MAX_BUSES; bus++) {
for (target = 0; target < AAC_MAX_TARGETS; target++) {
if (aac_phys_to_logical(bus) == ENCLOSURE_CHANNEL)
continue;
if (bus == CONTAINER_CHANNEL)