mirror of
https://github.com/a52xq-dev/kernel.git
synced 2026-10-18 21:58:11 +07:00
SCSI misc on 20180131
This is mostly updates of the usual driver suspects: arcmsr, scsi_debug, mpt3sas, lpfc, cxlflash, qla2xxx, aacraid, megaraid_sas, hisi_sas. We also have a rework of the libsas hotplug handling to make it more robust, a slew of 32 bit time conversions and fixes, and a host of the usual minor updates and style changes. The biggest potential for regressions is the libsas hotplug changes, but so far they seem stable under testing. Signed-off-by: James E.J. Bottomley <jejb@linux.vnet.ibm.com> -----BEGIN PGP SIGNATURE----- iJwEABMIAEQWIQTnYEDbdso9F2cI+arnQslM7pishQUCWnH+5SYcamFtZXMuYm90 dG9tbGV5QGhhbnNlbnBhcnRuZXJzaGlwLmNvbQAKCRDnQslM7pishWxuAP0UvuJp MNR/yU/wv/emSzOc48Ldwd7I0xD2XxSnloGUgwD+IGZZT5yNUQA1THCbm+en4hkB WvyBieQs9qRit+2czd4= =gJMf -----END PGP SIGNATURE----- Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi Pull SCSI updates from James Bottomley: "This is mostly updates of the usual driver suspects: arcmsr, scsi_debug, mpt3sas, lpfc, cxlflash, qla2xxx, aacraid, megaraid_sas, hisi_sas. We also have a rework of the libsas hotplug handling to make it more robust, a slew of 32 bit time conversions and fixes, and a host of the usual minor updates and style changes. The biggest potential for regressions is the libsas hotplug changes, but so far they seem stable under testing" * tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: (313 commits) scsi: qla2xxx: Fix logo flag for qlt_free_session_done() scsi: arcmsr: avoid do_gettimeofday scsi: core: Add VENDOR_SPECIFIC sense code definitions scsi: qedi: Drop cqe response during connection recovery scsi: fas216: fix sense buffer initialization scsi: ibmvfc: Remove unneeded semicolons scsi: hisi_sas: fix a bug in hisi_sas_dev_gone() scsi: hisi_sas: directly attached disk LED feature for v2 hw scsi: hisi_sas: devicetree: bindings: add LED feature for v2 hw scsi: megaraid_sas: NVMe passthrough command support scsi: megaraid: use ktime_get_real for firmware time scsi: fnic: use 64-bit timestamps scsi: qedf: Fix error return code in __qedf_probe() scsi: devinfo: fix format of the device list scsi: qla2xxx: Update driver version to 10.00.00.05-k scsi: qla2xxx: Add XCB counters to debugfs scsi: qla2xxx: Fix queue ID for async abort with Multiqueue scsi: qla2xxx: Fix warning for code intentation in __qla24xx_handle_gpdb_event() scsi: qla2xxx: Fix warning during port_name debug print scsi: qla2xxx: Fix warning in qla2x00_async_iocb_timeout() ...
This commit is contained in:
commit
28bc6fb959
161 changed files with 8932 additions and 4525 deletions
|
|
@ -8,7 +8,10 @@ Main node required properties:
|
|||
(b) "hisilicon,hip06-sas-v2" for v2 hw in hip06 chipset
|
||||
(c) "hisilicon,hip07-sas-v2" for v2 hw in hip07 chipset
|
||||
- sas-addr : array of 8 bytes for host SAS address
|
||||
- reg : Address and length of the SAS register
|
||||
- reg : Contains two regions. The first is the address and length of the SAS
|
||||
register. The second is the address and length of CPLD register for
|
||||
SGPIO control. The second is optional, and should be set only when
|
||||
we use a CPLD for directly attached disk LED control.
|
||||
- hisilicon,sas-syscon: phandle of syscon used for sas control
|
||||
- ctrl-reset-reg : offset to controller reset register in ctrl reg
|
||||
- ctrl-reset-sts-reg : offset to controller reset status register in ctrl reg
|
||||
|
|
|
|||
|
|
@ -224,6 +224,14 @@ mid to lowlevel SCSI driver interface
|
|||
.. kernel-doc:: drivers/scsi/hosts.c
|
||||
:export:
|
||||
|
||||
drivers/scsi/scsi_common.c
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
general support functions
|
||||
|
||||
.. kernel-doc:: drivers/scsi/scsi_common.c
|
||||
:export:
|
||||
|
||||
Transport classes
|
||||
-----------------
|
||||
|
||||
|
|
@ -332,5 +340,5 @@ todo
|
|||
~~~~
|
||||
|
||||
Parallel (fast/wide/ultra) SCSI, USB, SATA, SAS, Fibre Channel,
|
||||
FireWire, ATAPI devices, Infiniband, I20, iSCSI, Parallel ports,
|
||||
FireWire, ATAPI devices, Infiniband, I2O, iSCSI, Parallel ports,
|
||||
netlink...
|
||||
|
|
|
|||
|
|
@ -958,7 +958,7 @@ mpt_put_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
|
|||
{
|
||||
u32 mf_dma_addr;
|
||||
int req_offset;
|
||||
u16 req_idx; /* Request index */
|
||||
u16 req_idx; /* Request index */
|
||||
|
||||
/* ensure values are reset properly! */
|
||||
mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx; /* byte */
|
||||
|
|
@ -994,7 +994,7 @@ mpt_put_msg_frame_hi_pri(u8 cb_idx, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
|
|||
{
|
||||
u32 mf_dma_addr;
|
||||
int req_offset;
|
||||
u16 req_idx; /* Request index */
|
||||
u16 req_idx; /* Request index */
|
||||
|
||||
/* ensure values are reset properly! */
|
||||
mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx;
|
||||
|
|
@ -1128,11 +1128,12 @@ mpt_add_sge_64bit_1078(void *pAddr, u32 flagslength, dma_addr_t dma_addr)
|
|||
static void
|
||||
mpt_add_chain(void *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
|
||||
{
|
||||
SGEChain32_t *pChain = (SGEChain32_t *) pAddr;
|
||||
pChain->Length = cpu_to_le16(length);
|
||||
pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT;
|
||||
pChain->NextChainOffset = next;
|
||||
pChain->Address = cpu_to_le32(dma_addr);
|
||||
SGEChain32_t *pChain = (SGEChain32_t *) pAddr;
|
||||
|
||||
pChain->Length = cpu_to_le16(length);
|
||||
pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT;
|
||||
pChain->NextChainOffset = next;
|
||||
pChain->Address = cpu_to_le32(dma_addr);
|
||||
}
|
||||
|
||||
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
||||
|
|
@ -1147,18 +1148,18 @@ mpt_add_chain(void *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
|
|||
static void
|
||||
mpt_add_chain_64bit(void *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
|
||||
{
|
||||
SGEChain64_t *pChain = (SGEChain64_t *) pAddr;
|
||||
u32 tmp = dma_addr & 0xFFFFFFFF;
|
||||
SGEChain64_t *pChain = (SGEChain64_t *) pAddr;
|
||||
u32 tmp = dma_addr & 0xFFFFFFFF;
|
||||
|
||||
pChain->Length = cpu_to_le16(length);
|
||||
pChain->Flags = (MPI_SGE_FLAGS_CHAIN_ELEMENT |
|
||||
MPI_SGE_FLAGS_64_BIT_ADDRESSING);
|
||||
pChain->Length = cpu_to_le16(length);
|
||||
pChain->Flags = (MPI_SGE_FLAGS_CHAIN_ELEMENT |
|
||||
MPI_SGE_FLAGS_64_BIT_ADDRESSING);
|
||||
|
||||
pChain->NextChainOffset = next;
|
||||
pChain->NextChainOffset = next;
|
||||
|
||||
pChain->Address.Low = cpu_to_le32(tmp);
|
||||
tmp = (u32)(upper_32_bits(dma_addr));
|
||||
pChain->Address.High = cpu_to_le32(tmp);
|
||||
pChain->Address.Low = cpu_to_le32(tmp);
|
||||
tmp = (u32)(upper_32_bits(dma_addr));
|
||||
pChain->Address.High = cpu_to_le32(tmp);
|
||||
}
|
||||
|
||||
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
||||
|
|
@ -1360,7 +1361,7 @@ mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init)
|
|||
ioc->add_sge(psge, flags_length, ioc->HostPageBuffer_dma);
|
||||
ioc->facts.HostPageBufferSGE = ioc_init->HostPageBufferSGE;
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
||||
|
|
@ -2152,7 +2153,7 @@ mpt_suspend(struct pci_dev *pdev, pm_message_t state)
|
|||
device_state);
|
||||
|
||||
/* put ioc into READY_STATE */
|
||||
if(SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, CAN_SLEEP)) {
|
||||
if (SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, CAN_SLEEP)) {
|
||||
printk(MYIOC_s_ERR_FMT
|
||||
"pci-suspend: IOC msg unit reset failed!\n", ioc->name);
|
||||
}
|
||||
|
|
@ -6348,7 +6349,7 @@ mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
|
|||
u8 page_type = 0, extend_page;
|
||||
unsigned long timeleft;
|
||||
unsigned long flags;
|
||||
int in_isr;
|
||||
int in_isr;
|
||||
u8 issue_hard_reset = 0;
|
||||
u8 retry_count = 0;
|
||||
|
||||
|
|
@ -7697,7 +7698,7 @@ mpt_display_event_info(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply)
|
|||
break;
|
||||
}
|
||||
if (ds)
|
||||
strncpy(evStr, ds, EVENT_DESCR_STR_SZ);
|
||||
strlcpy(evStr, ds, EVENT_DESCR_STR_SZ);
|
||||
|
||||
|
||||
devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
|
||||
|
|
@ -8092,15 +8093,15 @@ mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info)
|
|||
static void
|
||||
mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info, u8 cb_idx)
|
||||
{
|
||||
union loginfo_type {
|
||||
u32 loginfo;
|
||||
struct {
|
||||
u32 subcode:16;
|
||||
u32 code:8;
|
||||
u32 originator:4;
|
||||
u32 bus_type:4;
|
||||
}dw;
|
||||
};
|
||||
union loginfo_type {
|
||||
u32 loginfo;
|
||||
struct {
|
||||
u32 subcode:16;
|
||||
u32 code:8;
|
||||
u32 originator:4;
|
||||
u32 bus_type:4;
|
||||
} dw;
|
||||
};
|
||||
union loginfo_type sas_loginfo;
|
||||
char *originator_desc = NULL;
|
||||
char *code_desc = NULL;
|
||||
|
|
|
|||
|
|
@ -2481,24 +2481,13 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size)
|
|||
else
|
||||
karg.host_no = -1;
|
||||
|
||||
/* Reformat the fw_version into a string
|
||||
*/
|
||||
karg.fw_version[0] = ioc->facts.FWVersion.Struct.Major >= 10 ?
|
||||
((ioc->facts.FWVersion.Struct.Major / 10) + '0') : '0';
|
||||
karg.fw_version[1] = (ioc->facts.FWVersion.Struct.Major % 10 ) + '0';
|
||||
karg.fw_version[2] = '.';
|
||||
karg.fw_version[3] = ioc->facts.FWVersion.Struct.Minor >= 10 ?
|
||||
((ioc->facts.FWVersion.Struct.Minor / 10) + '0') : '0';
|
||||
karg.fw_version[4] = (ioc->facts.FWVersion.Struct.Minor % 10 ) + '0';
|
||||
karg.fw_version[5] = '.';
|
||||
karg.fw_version[6] = ioc->facts.FWVersion.Struct.Unit >= 10 ?
|
||||
((ioc->facts.FWVersion.Struct.Unit / 10) + '0') : '0';
|
||||
karg.fw_version[7] = (ioc->facts.FWVersion.Struct.Unit % 10 ) + '0';
|
||||
karg.fw_version[8] = '.';
|
||||
karg.fw_version[9] = ioc->facts.FWVersion.Struct.Dev >= 10 ?
|
||||
((ioc->facts.FWVersion.Struct.Dev / 10) + '0') : '0';
|
||||
karg.fw_version[10] = (ioc->facts.FWVersion.Struct.Dev % 10 ) + '0';
|
||||
karg.fw_version[11] = '\0';
|
||||
/* Reformat the fw_version into a string */
|
||||
snprintf(karg.fw_version, sizeof(karg.fw_version),
|
||||
"%.2hhu.%.2hhu.%.2hhu.%.2hhu",
|
||||
ioc->facts.FWVersion.Struct.Major,
|
||||
ioc->facts.FWVersion.Struct.Minor,
|
||||
ioc->facts.FWVersion.Struct.Unit,
|
||||
ioc->facts.FWVersion.Struct.Dev);
|
||||
|
||||
/* Issue a config request to get the device serial number
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1165,7 +1165,6 @@ mptsas_schedule_target_reset(void *iocp)
|
|||
* issue target reset to next device in the queue
|
||||
*/
|
||||
|
||||
head = &hd->target_reset_list;
|
||||
if (list_empty(head))
|
||||
return;
|
||||
|
||||
|
|
|
|||
|
|
@ -369,7 +369,6 @@ out:
|
|||
static void twa_aen_queue_event(TW_Device_Extension *tw_dev, TW_Command_Apache_Header *header)
|
||||
{
|
||||
u32 local_time;
|
||||
struct timeval time;
|
||||
TW_Event *event;
|
||||
unsigned short aen;
|
||||
char host[16];
|
||||
|
|
@ -392,8 +391,8 @@ static void twa_aen_queue_event(TW_Device_Extension *tw_dev, TW_Command_Apache_H
|
|||
memset(event, 0, sizeof(TW_Event));
|
||||
|
||||
event->severity = TW_SEV_OUT(header->status_block.severity__reserved);
|
||||
do_gettimeofday(&time);
|
||||
local_time = (u32)(time.tv_sec - (sys_tz.tz_minuteswest * 60));
|
||||
/* event->time_stamp_sec overflows in y2106 */
|
||||
local_time = (u32)(ktime_get_real_seconds() - (sys_tz.tz_minuteswest * 60));
|
||||
event->time_stamp_sec = local_time;
|
||||
event->aen_code = aen;
|
||||
event->retrieved = TW_AEN_NOT_RETRIEVED;
|
||||
|
|
@ -473,11 +472,10 @@ out:
|
|||
static void twa_aen_sync_time(TW_Device_Extension *tw_dev, int request_id)
|
||||
{
|
||||
u32 schedulertime;
|
||||
struct timeval utc;
|
||||
TW_Command_Full *full_command_packet;
|
||||
TW_Command *command_packet;
|
||||
TW_Param_Apache *param;
|
||||
u32 local_time;
|
||||
time64_t local_time;
|
||||
|
||||
/* Fill out the command packet */
|
||||
full_command_packet = tw_dev->command_packet_virt[request_id];
|
||||
|
|
@ -499,9 +497,8 @@ static void twa_aen_sync_time(TW_Device_Extension *tw_dev, int request_id)
|
|||
|
||||
/* Convert system time in UTC to local time seconds since last
|
||||
Sunday 12:00AM */
|
||||
do_gettimeofday(&utc);
|
||||
local_time = (u32)(utc.tv_sec - (sys_tz.tz_minuteswest * 60));
|
||||
schedulertime = local_time - (3 * 86400);
|
||||
local_time = (ktime_get_real_seconds() - (sys_tz.tz_minuteswest * 60));
|
||||
div_u64_rem(local_time - (3 * 86400), 604800, &schedulertime);
|
||||
schedulertime = cpu_to_le32(schedulertime % 604800);
|
||||
|
||||
memcpy(param->data, &schedulertime, sizeof(u32));
|
||||
|
|
@ -648,8 +645,7 @@ static long twa_chrdev_ioctl(struct file *file, unsigned int cmd, unsigned long
|
|||
TW_Command_Full *full_command_packet;
|
||||
TW_Compatibility_Info *tw_compat_info;
|
||||
TW_Event *event;
|
||||
struct timeval current_time;
|
||||
u32 current_time_ms;
|
||||
ktime_t current_time;
|
||||
TW_Device_Extension *tw_dev = twa_device_extension_list[iminor(inode)];
|
||||
int retval = TW_IOCTL_ERROR_OS_EFAULT;
|
||||
void __user *argp = (void __user *)arg;
|
||||
|
|
@ -840,17 +836,17 @@ static long twa_chrdev_ioctl(struct file *file, unsigned int cmd, unsigned long
|
|||
break;
|
||||
case TW_IOCTL_GET_LOCK:
|
||||
tw_lock = (TW_Lock *)tw_ioctl->data_buffer;
|
||||
do_gettimeofday(¤t_time);
|
||||
current_time_ms = (current_time.tv_sec * 1000) + (current_time.tv_usec / 1000);
|
||||
current_time = ktime_get();
|
||||
|
||||
if ((tw_lock->force_flag == 1) || (tw_dev->ioctl_sem_lock == 0) || (current_time_ms >= tw_dev->ioctl_msec)) {
|
||||
if ((tw_lock->force_flag == 1) || (tw_dev->ioctl_sem_lock == 0) ||
|
||||
ktime_after(current_time, tw_dev->ioctl_time)) {
|
||||
tw_dev->ioctl_sem_lock = 1;
|
||||
tw_dev->ioctl_msec = current_time_ms + tw_lock->timeout_msec;
|
||||
tw_dev->ioctl_time = ktime_add_ms(current_time, tw_lock->timeout_msec);
|
||||
tw_ioctl->driver_command.status = 0;
|
||||
tw_lock->time_remaining_msec = tw_lock->timeout_msec;
|
||||
} else {
|
||||
tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_LOCKED;
|
||||
tw_lock->time_remaining_msec = tw_dev->ioctl_msec - current_time_ms;
|
||||
tw_lock->time_remaining_msec = ktime_ms_delta(tw_dev->ioctl_time, current_time);
|
||||
}
|
||||
break;
|
||||
case TW_IOCTL_RELEASE_LOCK:
|
||||
|
|
|
|||
|
|
@ -666,7 +666,7 @@ typedef struct TAG_TW_Device_Extension {
|
|||
unsigned char event_queue_wrapped;
|
||||
unsigned int error_sequence_id;
|
||||
int ioctl_sem_lock;
|
||||
u32 ioctl_msec;
|
||||
ktime_t ioctl_time;
|
||||
int chrdev_request_id;
|
||||
wait_queue_head_t ioctl_wqueue;
|
||||
struct mutex ioctl_lock;
|
||||
|
|
|
|||
|
|
@ -221,7 +221,6 @@ out:
|
|||
static void twl_aen_queue_event(TW_Device_Extension *tw_dev, TW_Command_Apache_Header *header)
|
||||
{
|
||||
u32 local_time;
|
||||
struct timeval time;
|
||||
TW_Event *event;
|
||||
unsigned short aen;
|
||||
char host[16];
|
||||
|
|
@ -240,8 +239,8 @@ static void twl_aen_queue_event(TW_Device_Extension *tw_dev, TW_Command_Apache_H
|
|||
memset(event, 0, sizeof(TW_Event));
|
||||
|
||||
event->severity = TW_SEV_OUT(header->status_block.severity__reserved);
|
||||
do_gettimeofday(&time);
|
||||
local_time = (u32)(time.tv_sec - (sys_tz.tz_minuteswest * 60));
|
||||
/* event->time_stamp_sec overflows in y2106 */
|
||||
local_time = (u32)(ktime_get_real_seconds() - (sys_tz.tz_minuteswest * 60));
|
||||
event->time_stamp_sec = local_time;
|
||||
event->aen_code = aen;
|
||||
event->retrieved = TW_AEN_NOT_RETRIEVED;
|
||||
|
|
@ -408,11 +407,10 @@ out:
|
|||
static void twl_aen_sync_time(TW_Device_Extension *tw_dev, int request_id)
|
||||
{
|
||||
u32 schedulertime;
|
||||
struct timeval utc;
|
||||
TW_Command_Full *full_command_packet;
|
||||
TW_Command *command_packet;
|
||||
TW_Param_Apache *param;
|
||||
u32 local_time;
|
||||
time64_t local_time;
|
||||
|
||||
/* Fill out the command packet */
|
||||
full_command_packet = tw_dev->command_packet_virt[request_id];
|
||||
|
|
@ -434,10 +432,9 @@ static void twl_aen_sync_time(TW_Device_Extension *tw_dev, int request_id)
|
|||
|
||||
/* Convert system time in UTC to local time seconds since last
|
||||
Sunday 12:00AM */
|
||||
do_gettimeofday(&utc);
|
||||
local_time = (u32)(utc.tv_sec - (sys_tz.tz_minuteswest * 60));
|
||||
schedulertime = local_time - (3 * 86400);
|
||||
schedulertime = cpu_to_le32(schedulertime % 604800);
|
||||
local_time = (ktime_get_real_seconds() - (sys_tz.tz_minuteswest * 60));
|
||||
div_u64_rem(local_time - (3 * 86400), 604800, &schedulertime);
|
||||
schedulertime = cpu_to_le32(schedulertime);
|
||||
|
||||
memcpy(param->data, &schedulertime, sizeof(u32));
|
||||
|
||||
|
|
|
|||
|
|
@ -42,6 +42,8 @@
|
|||
#include <linux/highmem.h> /* For flush_kernel_dcache_page */
|
||||
#include <linux/module.h>
|
||||
|
||||
#include <asm/unaligned.h>
|
||||
|
||||
#include <scsi/scsi.h>
|
||||
#include <scsi/scsi_cmnd.h>
|
||||
#include <scsi/scsi_device.h>
|
||||
|
|
@ -913,8 +915,15 @@ static void setinqstr(struct aac_dev *dev, void *data, int tindex)
|
|||
memset(str, ' ', sizeof(*str));
|
||||
|
||||
if (sup_adap_info->adapter_type_text[0]) {
|
||||
char *cp = sup_adap_info->adapter_type_text;
|
||||
int c;
|
||||
char *cp;
|
||||
char *cname = kmemdup(sup_adap_info->adapter_type_text,
|
||||
sizeof(sup_adap_info->adapter_type_text),
|
||||
GFP_ATOMIC);
|
||||
if (!cname)
|
||||
return;
|
||||
|
||||
cp = cname;
|
||||
if ((cp[0] == 'A') && (cp[1] == 'O') && (cp[2] == 'C'))
|
||||
inqstrcpy("SMC", str->vid);
|
||||
else {
|
||||
|
|
@ -923,7 +932,7 @@ static void setinqstr(struct aac_dev *dev, void *data, int tindex)
|
|||
++cp;
|
||||
c = *cp;
|
||||
*cp = '\0';
|
||||
inqstrcpy(sup_adap_info->adapter_type_text, str->vid);
|
||||
inqstrcpy(cname, str->vid);
|
||||
*cp = c;
|
||||
while (*cp && *cp != ' ')
|
||||
++cp;
|
||||
|
|
@ -931,14 +940,11 @@ static void setinqstr(struct aac_dev *dev, void *data, int tindex)
|
|||
while (*cp == ' ')
|
||||
++cp;
|
||||
/* last six chars reserved for vol type */
|
||||
c = 0;
|
||||
if (strlen(cp) > sizeof(str->pid)) {
|
||||
c = cp[sizeof(str->pid)];
|
||||
if (strlen(cp) > sizeof(str->pid))
|
||||
cp[sizeof(str->pid)] = '\0';
|
||||
}
|
||||
inqstrcpy (cp, str->pid);
|
||||
if (c)
|
||||
cp[sizeof(str->pid)] = c;
|
||||
|
||||
kfree(cname);
|
||||
} else {
|
||||
struct aac_driver_ident *mp = aac_get_driver_ident(dev->cardtype);
|
||||
|
||||
|
|
@ -1660,87 +1666,309 @@ static int aac_adapter_hba(struct fib *fib, struct scsi_cmnd *cmd)
|
|||
(void *) cmd);
|
||||
}
|
||||
|
||||
int aac_issue_bmic_identify(struct aac_dev *dev, u32 bus, u32 target)
|
||||
static int aac_send_safw_bmic_cmd(struct aac_dev *dev,
|
||||
struct aac_srb_unit *srbu, void *xfer_buf, int xfer_len)
|
||||
{
|
||||
struct fib *fibptr;
|
||||
struct aac_srb *srbcmd;
|
||||
struct sgmap64 *sg64;
|
||||
struct aac_ciss_identify_pd *identify_resp;
|
||||
dma_addr_t addr;
|
||||
u32 vbus, vid;
|
||||
u16 fibsize, datasize;
|
||||
int rcode = -ENOMEM;
|
||||
struct fib *fibptr;
|
||||
dma_addr_t addr;
|
||||
int rcode;
|
||||
int fibsize;
|
||||
struct aac_srb *srb;
|
||||
struct aac_srb_reply *srb_reply;
|
||||
struct sgmap64 *sg64;
|
||||
u32 vbus;
|
||||
u32 vid;
|
||||
|
||||
if (!dev->sa_firmware)
|
||||
return 0;
|
||||
|
||||
/* allocate FIB */
|
||||
fibptr = aac_fib_alloc(dev);
|
||||
if (!fibptr)
|
||||
goto out;
|
||||
|
||||
fibsize = sizeof(struct aac_srb) -
|
||||
sizeof(struct sgentry) + sizeof(struct sgentry64);
|
||||
datasize = sizeof(struct aac_ciss_identify_pd);
|
||||
|
||||
identify_resp = dma_alloc_coherent(&dev->pdev->dev, datasize, &addr,
|
||||
GFP_KERNEL);
|
||||
if (!identify_resp)
|
||||
goto fib_free_ptr;
|
||||
|
||||
vbus = (u32)le16_to_cpu(dev->supplement_adapter_info.virt_device_bus);
|
||||
vid = (u32)le16_to_cpu(dev->supplement_adapter_info.virt_device_target);
|
||||
return -ENOMEM;
|
||||
|
||||
aac_fib_init(fibptr);
|
||||
fibptr->hw_fib_va->header.XferState &=
|
||||
~cpu_to_le32(FastResponseCapable);
|
||||
|
||||
srbcmd = (struct aac_srb *) fib_data(fibptr);
|
||||
srbcmd->function = cpu_to_le32(SRBF_ExecuteScsi);
|
||||
srbcmd->channel = cpu_to_le32(vbus);
|
||||
srbcmd->id = cpu_to_le32(vid);
|
||||
srbcmd->lun = 0;
|
||||
srbcmd->flags = cpu_to_le32(SRB_DataIn);
|
||||
srbcmd->timeout = cpu_to_le32(10);
|
||||
srbcmd->retry_limit = 0;
|
||||
srbcmd->cdb_size = cpu_to_le32(12);
|
||||
srbcmd->count = cpu_to_le32(datasize);
|
||||
fibsize = sizeof(struct aac_srb) - sizeof(struct sgentry) +
|
||||
sizeof(struct sgentry64);
|
||||
|
||||
memset(srbcmd->cdb, 0, sizeof(srbcmd->cdb));
|
||||
srbcmd->cdb[0] = 0x26;
|
||||
srbcmd->cdb[2] = (u8)((AAC_MAX_LUN + target) & 0x00FF);
|
||||
srbcmd->cdb[6] = CISS_IDENTIFY_PHYSICAL_DEVICE;
|
||||
/* allocate DMA buffer for response */
|
||||
addr = dma_map_single(&dev->pdev->dev, xfer_buf, xfer_len,
|
||||
DMA_BIDIRECTIONAL);
|
||||
if (dma_mapping_error(&dev->pdev->dev, addr)) {
|
||||
rcode = -ENOMEM;
|
||||
goto fib_error;
|
||||
}
|
||||
|
||||
sg64 = (struct sgmap64 *)&srbcmd->sg;
|
||||
sg64->count = cpu_to_le32(1);
|
||||
sg64->sg[0].addr[1] = cpu_to_le32((u32)(((addr) >> 16) >> 16));
|
||||
sg64->sg[0].addr[0] = cpu_to_le32((u32)(addr & 0xffffffff));
|
||||
sg64->sg[0].count = cpu_to_le32(datasize);
|
||||
srb = fib_data(fibptr);
|
||||
memcpy(srb, &srbu->srb, sizeof(struct aac_srb));
|
||||
|
||||
rcode = aac_fib_send(ScsiPortCommand64,
|
||||
fibptr, fibsize, FsaNormal, 1, 1, NULL, NULL);
|
||||
vbus = (u32)le16_to_cpu(
|
||||
dev->supplement_adapter_info.virt_device_bus);
|
||||
vid = (u32)le16_to_cpu(
|
||||
dev->supplement_adapter_info.virt_device_target);
|
||||
|
||||
/* set the common request fields */
|
||||
srb->channel = cpu_to_le32(vbus);
|
||||
srb->id = cpu_to_le32(vid);
|
||||
srb->lun = 0;
|
||||
srb->function = cpu_to_le32(SRBF_ExecuteScsi);
|
||||
srb->timeout = 0;
|
||||
srb->retry_limit = 0;
|
||||
srb->cdb_size = cpu_to_le32(16);
|
||||
srb->count = cpu_to_le32(xfer_len);
|
||||
|
||||
sg64 = (struct sgmap64 *)&srb->sg;
|
||||
sg64->count = cpu_to_le32(1);
|
||||
sg64->sg[0].addr[1] = cpu_to_le32(upper_32_bits(addr));
|
||||
sg64->sg[0].addr[0] = cpu_to_le32(lower_32_bits(addr));
|
||||
sg64->sg[0].count = cpu_to_le32(xfer_len);
|
||||
|
||||
/*
|
||||
* Copy the updated data for other dumping or other usage if needed
|
||||
*/
|
||||
memcpy(&srbu->srb, srb, sizeof(struct aac_srb));
|
||||
|
||||
/* issue request to the controller */
|
||||
rcode = aac_fib_send(ScsiPortCommand64, fibptr, fibsize, FsaNormal,
|
||||
1, 1, NULL, NULL);
|
||||
|
||||
if (rcode == -ERESTARTSYS)
|
||||
rcode = -ERESTART;
|
||||
|
||||
if (unlikely(rcode < 0))
|
||||
goto bmic_error;
|
||||
|
||||
srb_reply = (struct aac_srb_reply *)fib_data(fibptr);
|
||||
memcpy(&srbu->srb_reply, srb_reply, sizeof(struct aac_srb_reply));
|
||||
|
||||
bmic_error:
|
||||
dma_unmap_single(&dev->pdev->dev, addr, xfer_len, DMA_BIDIRECTIONAL);
|
||||
fib_error:
|
||||
aac_fib_complete(fibptr);
|
||||
aac_fib_free(fibptr);
|
||||
return rcode;
|
||||
}
|
||||
|
||||
static void aac_set_safw_target_qd(struct aac_dev *dev, int bus, int target)
|
||||
{
|
||||
|
||||
struct aac_ciss_identify_pd *identify_resp;
|
||||
|
||||
if (dev->hba_map[bus][target].devtype != AAC_DEVTYPE_NATIVE_RAW)
|
||||
return;
|
||||
|
||||
identify_resp = dev->hba_map[bus][target].safw_identify_resp;
|
||||
if (identify_resp == NULL) {
|
||||
dev->hba_map[bus][target].qd_limit = 32;
|
||||
return;
|
||||
}
|
||||
|
||||
if (identify_resp->current_queue_depth_limit <= 0 ||
|
||||
identify_resp->current_queue_depth_limit > 32)
|
||||
identify_resp->current_queue_depth_limit > 255)
|
||||
dev->hba_map[bus][target].qd_limit = 32;
|
||||
else
|
||||
dev->hba_map[bus][target].qd_limit =
|
||||
identify_resp->current_queue_depth_limit;
|
||||
}
|
||||
|
||||
dma_free_coherent(&dev->pdev->dev, datasize, identify_resp, addr);
|
||||
static int aac_issue_safw_bmic_identify(struct aac_dev *dev,
|
||||
struct aac_ciss_identify_pd **identify_resp, u32 bus, u32 target)
|
||||
{
|
||||
int rcode = -ENOMEM;
|
||||
int datasize;
|
||||
struct aac_srb_unit srbu;
|
||||
struct aac_srb *srbcmd;
|
||||
struct aac_ciss_identify_pd *identify_reply;
|
||||
|
||||
aac_fib_complete(fibptr);
|
||||
datasize = sizeof(struct aac_ciss_identify_pd);
|
||||
identify_reply = kmalloc(datasize, GFP_KERNEL);
|
||||
if (!identify_reply)
|
||||
goto out;
|
||||
|
||||
memset(&srbu, 0, sizeof(struct aac_srb_unit));
|
||||
|
||||
srbcmd = &srbu.srb;
|
||||
srbcmd->flags = cpu_to_le32(SRB_DataIn);
|
||||
srbcmd->cdb[0] = 0x26;
|
||||
srbcmd->cdb[2] = (u8)((AAC_MAX_LUN + target) & 0x00FF);
|
||||
srbcmd->cdb[6] = CISS_IDENTIFY_PHYSICAL_DEVICE;
|
||||
|
||||
rcode = aac_send_safw_bmic_cmd(dev, &srbu, identify_reply, datasize);
|
||||
if (unlikely(rcode < 0))
|
||||
goto mem_free_all;
|
||||
|
||||
*identify_resp = identify_reply;
|
||||
|
||||
fib_free_ptr:
|
||||
aac_fib_free(fibptr);
|
||||
out:
|
||||
return rcode;
|
||||
mem_free_all:
|
||||
kfree(identify_reply);
|
||||
goto out;
|
||||
}
|
||||
|
||||
static inline void aac_free_safw_ciss_luns(struct aac_dev *dev)
|
||||
{
|
||||
kfree(dev->safw_phys_luns);
|
||||
dev->safw_phys_luns = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* aac_update hba_map()- update current hba map with data from FW
|
||||
* aac_get_safw_ciss_luns() Process topology change
|
||||
* @dev: aac_dev structure
|
||||
*
|
||||
* Execute a CISS REPORT PHYS LUNS and process the results into
|
||||
* the current hba_map.
|
||||
*/
|
||||
static int aac_get_safw_ciss_luns(struct aac_dev *dev)
|
||||
{
|
||||
int rcode = -ENOMEM;
|
||||
int datasize;
|
||||
struct aac_srb *srbcmd;
|
||||
struct aac_srb_unit srbu;
|
||||
struct aac_ciss_phys_luns_resp *phys_luns;
|
||||
|
||||
datasize = sizeof(struct aac_ciss_phys_luns_resp) +
|
||||
(AAC_MAX_TARGETS - 1) * sizeof(struct _ciss_lun);
|
||||
phys_luns = kmalloc(datasize, GFP_KERNEL);
|
||||
if (phys_luns == NULL)
|
||||
goto out;
|
||||
|
||||
memset(&srbu, 0, sizeof(struct aac_srb_unit));
|
||||
|
||||
srbcmd = &srbu.srb;
|
||||
srbcmd->flags = cpu_to_le32(SRB_DataIn);
|
||||
srbcmd->cdb[0] = CISS_REPORT_PHYSICAL_LUNS;
|
||||
srbcmd->cdb[1] = 2; /* extended reporting */
|
||||
srbcmd->cdb[8] = (u8)(datasize >> 8);
|
||||
srbcmd->cdb[9] = (u8)(datasize);
|
||||
|
||||
rcode = aac_send_safw_bmic_cmd(dev, &srbu, phys_luns, datasize);
|
||||
if (unlikely(rcode < 0))
|
||||
goto mem_free_all;
|
||||
|
||||
if (phys_luns->resp_flag != 2) {
|
||||
rcode = -ENOMSG;
|
||||
goto mem_free_all;
|
||||
}
|
||||
|
||||
dev->safw_phys_luns = phys_luns;
|
||||
|
||||
out:
|
||||
return rcode;
|
||||
mem_free_all:
|
||||
kfree(phys_luns);
|
||||
goto out;
|
||||
}
|
||||
|
||||
static inline u32 aac_get_safw_phys_lun_count(struct aac_dev *dev)
|
||||
{
|
||||
return get_unaligned_be32(&dev->safw_phys_luns->list_length[0])/24;
|
||||
}
|
||||
|
||||
static inline u32 aac_get_safw_phys_bus(struct aac_dev *dev, int lun)
|
||||
{
|
||||
return dev->safw_phys_luns->lun[lun].level2[1] & 0x3f;
|
||||
}
|
||||
|
||||
static inline u32 aac_get_safw_phys_target(struct aac_dev *dev, int lun)
|
||||
{
|
||||
return dev->safw_phys_luns->lun[lun].level2[0];
|
||||
}
|
||||
|
||||
static inline u32 aac_get_safw_phys_expose_flag(struct aac_dev *dev, int lun)
|
||||
{
|
||||
return dev->safw_phys_luns->lun[lun].bus >> 6;
|
||||
}
|
||||
|
||||
static inline u32 aac_get_safw_phys_attribs(struct aac_dev *dev, int lun)
|
||||
{
|
||||
return dev->safw_phys_luns->lun[lun].node_ident[9];
|
||||
}
|
||||
|
||||
static inline u32 aac_get_safw_phys_nexus(struct aac_dev *dev, int lun)
|
||||
{
|
||||
return *((u32 *)&dev->safw_phys_luns->lun[lun].node_ident[12]);
|
||||
}
|
||||
|
||||
static inline u32 aac_get_safw_phys_device_type(struct aac_dev *dev, int lun)
|
||||
{
|
||||
return dev->safw_phys_luns->lun[lun].node_ident[8];
|
||||
}
|
||||
|
||||
static inline void aac_free_safw_identify_resp(struct aac_dev *dev,
|
||||
int bus, int target)
|
||||
{
|
||||
kfree(dev->hba_map[bus][target].safw_identify_resp);
|
||||
dev->hba_map[bus][target].safw_identify_resp = NULL;
|
||||
}
|
||||
|
||||
static inline void aac_free_safw_all_identify_resp(struct aac_dev *dev,
|
||||
int lun_count)
|
||||
{
|
||||
int luns;
|
||||
int i;
|
||||
u32 bus;
|
||||
u32 target;
|
||||
|
||||
luns = aac_get_safw_phys_lun_count(dev);
|
||||
|
||||
if (luns < lun_count)
|
||||
lun_count = luns;
|
||||
else if (lun_count < 0)
|
||||
lun_count = luns;
|
||||
|
||||
for (i = 0; i < lun_count; i++) {
|
||||
bus = aac_get_safw_phys_bus(dev, i);
|
||||
target = aac_get_safw_phys_target(dev, i);
|
||||
|
||||
aac_free_safw_identify_resp(dev, bus, target);
|
||||
}
|
||||
}
|
||||
|
||||
static int aac_get_safw_attr_all_targets(struct aac_dev *dev)
|
||||
{
|
||||
int i;
|
||||
int rcode = 0;
|
||||
u32 lun_count;
|
||||
u32 bus;
|
||||
u32 target;
|
||||
struct aac_ciss_identify_pd *identify_resp = NULL;
|
||||
|
||||
lun_count = aac_get_safw_phys_lun_count(dev);
|
||||
|
||||
for (i = 0; i < lun_count; ++i) {
|
||||
|
||||
bus = aac_get_safw_phys_bus(dev, i);
|
||||
target = aac_get_safw_phys_target(dev, i);
|
||||
|
||||
rcode = aac_issue_safw_bmic_identify(dev,
|
||||
&identify_resp, bus, target);
|
||||
|
||||
if (unlikely(rcode < 0))
|
||||
goto free_identify_resp;
|
||||
|
||||
dev->hba_map[bus][target].safw_identify_resp = identify_resp;
|
||||
}
|
||||
|
||||
out:
|
||||
return rcode;
|
||||
free_identify_resp:
|
||||
aac_free_safw_all_identify_resp(dev, i);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/**
|
||||
* aac_set_safw_attr_all_targets- update current hba map with data from FW
|
||||
* @dev: aac_dev structure
|
||||
* @phys_luns: FW information from report phys luns
|
||||
* @rescan: Indicates scan type
|
||||
*
|
||||
* Update our hba map with the information gathered from the FW
|
||||
*/
|
||||
void aac_update_hba_map(struct aac_dev *dev,
|
||||
struct aac_ciss_phys_luns_resp *phys_luns, int rescan)
|
||||
static void aac_set_safw_attr_all_targets(struct aac_dev *dev)
|
||||
{
|
||||
/* ok and extended reporting */
|
||||
u32 lun_count, nexus;
|
||||
|
|
@ -1748,24 +1976,21 @@ void aac_update_hba_map(struct aac_dev *dev,
|
|||
u8 expose_flag, attribs;
|
||||
u8 devtype;
|
||||
|
||||
lun_count = ((phys_luns->list_length[0] << 24)
|
||||
+ (phys_luns->list_length[1] << 16)
|
||||
+ (phys_luns->list_length[2] << 8)
|
||||
+ (phys_luns->list_length[3])) / 24;
|
||||
lun_count = aac_get_safw_phys_lun_count(dev);
|
||||
|
||||
dev->scan_counter++;
|
||||
|
||||
for (i = 0; i < lun_count; ++i) {
|
||||
|
||||
bus = phys_luns->lun[i].level2[1] & 0x3f;
|
||||
target = phys_luns->lun[i].level2[0];
|
||||
expose_flag = phys_luns->lun[i].bus >> 6;
|
||||
attribs = phys_luns->lun[i].node_ident[9];
|
||||
nexus = *((u32 *) &phys_luns->lun[i].node_ident[12]);
|
||||
bus = aac_get_safw_phys_bus(dev, i);
|
||||
target = aac_get_safw_phys_target(dev, i);
|
||||
expose_flag = aac_get_safw_phys_expose_flag(dev, i);
|
||||
attribs = aac_get_safw_phys_attribs(dev, i);
|
||||
nexus = aac_get_safw_phys_nexus(dev, i);
|
||||
|
||||
if (bus >= AAC_MAX_BUSES || target >= AAC_MAX_TARGETS)
|
||||
continue;
|
||||
|
||||
dev->hba_map[bus][target].expose = expose_flag;
|
||||
|
||||
if (expose_flag != 0) {
|
||||
devtype = AAC_DEVTYPE_RAID_MEMBER;
|
||||
goto update_devtype;
|
||||
|
|
@ -1778,95 +2003,45 @@ void aac_update_hba_map(struct aac_dev *dev,
|
|||
} else
|
||||
devtype = AAC_DEVTYPE_ARC_RAW;
|
||||
|
||||
if (devtype != AAC_DEVTYPE_NATIVE_RAW)
|
||||
goto update_devtype;
|
||||
dev->hba_map[bus][target].scan_counter = dev->scan_counter;
|
||||
|
||||
if (aac_issue_bmic_identify(dev, bus, target) < 0)
|
||||
dev->hba_map[bus][target].qd_limit = 32;
|
||||
aac_set_safw_target_qd(dev, bus, target);
|
||||
|
||||
update_devtype:
|
||||
if (rescan == AAC_INIT)
|
||||
dev->hba_map[bus][target].devtype = devtype;
|
||||
else
|
||||
dev->hba_map[bus][target].new_devtype = devtype;
|
||||
dev->hba_map[bus][target].devtype = devtype;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* aac_report_phys_luns() Process topology change
|
||||
* @dev: aac_dev structure
|
||||
* @fibptr: fib pointer
|
||||
*
|
||||
* Execute a CISS REPORT PHYS LUNS and process the results into
|
||||
* the current hba_map.
|
||||
*/
|
||||
int aac_report_phys_luns(struct aac_dev *dev, struct fib *fibptr, int rescan)
|
||||
static int aac_setup_safw_targets(struct aac_dev *dev)
|
||||
{
|
||||
int fibsize, datasize;
|
||||
struct aac_ciss_phys_luns_resp *phys_luns;
|
||||
struct aac_srb *srbcmd;
|
||||
struct sgmap64 *sg64;
|
||||
dma_addr_t addr;
|
||||
u32 vbus, vid;
|
||||
int rcode = 0;
|
||||
|
||||
/* Thor SA Firmware -> CISS_REPORT_PHYSICAL_LUNS */
|
||||
fibsize = sizeof(struct aac_srb) - sizeof(struct sgentry)
|
||||
+ sizeof(struct sgentry64);
|
||||
datasize = sizeof(struct aac_ciss_phys_luns_resp)
|
||||
+ (AAC_MAX_TARGETS - 1) * sizeof(struct _ciss_lun);
|
||||
rcode = aac_get_containers(dev);
|
||||
if (unlikely(rcode < 0))
|
||||
goto out;
|
||||
|
||||
phys_luns = dma_alloc_coherent(&dev->pdev->dev, datasize, &addr,
|
||||
GFP_KERNEL);
|
||||
if (phys_luns == NULL) {
|
||||
rcode = -ENOMEM;
|
||||
goto err_out;
|
||||
}
|
||||
rcode = aac_get_safw_ciss_luns(dev);
|
||||
if (unlikely(rcode < 0))
|
||||
goto out;
|
||||
|
||||
vbus = (u32) le16_to_cpu(
|
||||
dev->supplement_adapter_info.virt_device_bus);
|
||||
vid = (u32) le16_to_cpu(
|
||||
dev->supplement_adapter_info.virt_device_target);
|
||||
rcode = aac_get_safw_attr_all_targets(dev);
|
||||
if (unlikely(rcode < 0))
|
||||
goto free_ciss_luns;
|
||||
|
||||
aac_fib_init(fibptr);
|
||||
aac_set_safw_attr_all_targets(dev);
|
||||
|
||||
srbcmd = (struct aac_srb *) fib_data(fibptr);
|
||||
srbcmd->function = cpu_to_le32(SRBF_ExecuteScsi);
|
||||
srbcmd->channel = cpu_to_le32(vbus);
|
||||
srbcmd->id = cpu_to_le32(vid);
|
||||
srbcmd->lun = 0;
|
||||
srbcmd->flags = cpu_to_le32(SRB_DataIn);
|
||||
srbcmd->timeout = cpu_to_le32(10);
|
||||
srbcmd->retry_limit = 0;
|
||||
srbcmd->cdb_size = cpu_to_le32(12);
|
||||
srbcmd->count = cpu_to_le32(datasize);
|
||||
|
||||
memset(srbcmd->cdb, 0, sizeof(srbcmd->cdb));
|
||||
srbcmd->cdb[0] = CISS_REPORT_PHYSICAL_LUNS;
|
||||
srbcmd->cdb[1] = 2; /* extended reporting */
|
||||
srbcmd->cdb[8] = (u8)(datasize >> 8);
|
||||
srbcmd->cdb[9] = (u8)(datasize);
|
||||
|
||||
sg64 = (struct sgmap64 *) &srbcmd->sg;
|
||||
sg64->count = cpu_to_le32(1);
|
||||
sg64->sg[0].addr[1] = cpu_to_le32(upper_32_bits(addr));
|
||||
sg64->sg[0].addr[0] = cpu_to_le32(lower_32_bits(addr));
|
||||
sg64->sg[0].count = cpu_to_le32(datasize);
|
||||
|
||||
rcode = aac_fib_send(ScsiPortCommand64, fibptr, fibsize,
|
||||
FsaNormal, 1, 1, NULL, NULL);
|
||||
|
||||
/* analyse data */
|
||||
if (rcode >= 0 && phys_luns->resp_flag == 2) {
|
||||
/* ok and extended reporting */
|
||||
aac_update_hba_map(dev, phys_luns, rescan);
|
||||
}
|
||||
|
||||
dma_free_coherent(&dev->pdev->dev, datasize, phys_luns, addr);
|
||||
err_out:
|
||||
aac_free_safw_all_identify_resp(dev, -1);
|
||||
free_ciss_luns:
|
||||
aac_free_safw_ciss_luns(dev);
|
||||
out:
|
||||
return rcode;
|
||||
}
|
||||
|
||||
int aac_setup_safw_adapter(struct aac_dev *dev)
|
||||
{
|
||||
return aac_setup_safw_targets(dev);
|
||||
}
|
||||
|
||||
int aac_get_adapter_info(struct aac_dev* dev)
|
||||
{
|
||||
struct fib* fibptr;
|
||||
|
|
@ -1969,12 +2144,6 @@ int aac_get_adapter_info(struct aac_dev* dev)
|
|||
dev->maximum_num_channels = le32_to_cpu(bus_info->BusCount);
|
||||
}
|
||||
|
||||
if (!dev->sync_mode && dev->sa_firmware &&
|
||||
dev->supplement_adapter_info.virt_device_bus != 0xffff) {
|
||||
/* Thor SA Firmware -> CISS_REPORT_PHYSICAL_LUNS */
|
||||
rcode = aac_report_phys_luns(dev, fibptr, AAC_INIT);
|
||||
}
|
||||
|
||||
if (!dev->in_reset) {
|
||||
char buffer[16];
|
||||
tmp = le32_to_cpu(dev->adapter_info.kernelrev);
|
||||
|
|
@ -2739,14 +2908,6 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
|
|||
}
|
||||
} else { /* check for physical non-dasd devices */
|
||||
bus = aac_logical_to_phys(scmd_channel(scsicmd));
|
||||
if (bus < AAC_MAX_BUSES && cid < AAC_MAX_TARGETS &&
|
||||
(dev->hba_map[bus][cid].expose
|
||||
== AAC_HIDE_DISK)){
|
||||
if (scsicmd->cmnd[0] == INQUIRY) {
|
||||
scsicmd->result = DID_NO_CONNECT << 16;
|
||||
goto scsi_done_ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (bus < AAC_MAX_BUSES && cid < AAC_MAX_TARGETS &&
|
||||
dev->hba_map[bus][cid].devtype
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@
|
|||
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/pci.h>
|
||||
#include <scsi/scsi_host.h>
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* D E F I N E S
|
||||
|
|
@ -97,7 +98,7 @@ enum {
|
|||
#define PMC_GLOBAL_INT_BIT0 0x00000001
|
||||
|
||||
#ifndef AAC_DRIVER_BUILD
|
||||
# define AAC_DRIVER_BUILD 50834
|
||||
# define AAC_DRIVER_BUILD 50877
|
||||
# define AAC_DRIVER_BRANCH "-custom"
|
||||
#endif
|
||||
#define MAXIMUM_NUM_CONTAINERS 32
|
||||
|
|
@ -117,9 +118,13 @@ enum {
|
|||
/* Thor: 5 phys. buses: #0: empty, 1-4: 256 targets each */
|
||||
#define AAC_MAX_BUSES 5
|
||||
#define AAC_MAX_TARGETS 256
|
||||
#define AAC_BUS_TARGET_LOOP (AAC_MAX_BUSES * AAC_MAX_TARGETS)
|
||||
#define AAC_MAX_NATIVE_SIZE 2048
|
||||
#define FW_ERROR_BUFFER_SIZE 512
|
||||
|
||||
#define get_bus_number(x) (x/AAC_MAX_TARGETS)
|
||||
#define get_target_number(x) (x%AAC_MAX_TARGETS)
|
||||
|
||||
/* Thor AIF events */
|
||||
#define SA_AIF_HOTPLUG (1<<1)
|
||||
#define SA_AIF_HARDWARE (1<<2)
|
||||
|
|
@ -1334,17 +1339,17 @@ struct fib {
|
|||
#define AAC_DEVTYPE_RAID_MEMBER 1
|
||||
#define AAC_DEVTYPE_ARC_RAW 2
|
||||
#define AAC_DEVTYPE_NATIVE_RAW 3
|
||||
#define AAC_EXPOSE_DISK 0
|
||||
#define AAC_HIDE_DISK 3
|
||||
|
||||
#define AAC_SAFW_RESCAN_DELAY (10 * HZ)
|
||||
|
||||
struct aac_hba_map_info {
|
||||
__le32 rmw_nexus; /* nexus for native HBA devices */
|
||||
u8 devtype; /* device type */
|
||||
u8 new_devtype;
|
||||
u8 reset_state; /* 0 - no reset, 1..x - */
|
||||
/* after xth TM LUN reset */
|
||||
u16 qd_limit;
|
||||
u8 expose; /*checks if to expose or not*/
|
||||
u32 scan_counter;
|
||||
struct aac_ciss_identify_pd *safw_identify_resp;
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
@ -1560,6 +1565,7 @@ struct aac_dev
|
|||
spinlock_t fib_lock;
|
||||
|
||||
struct mutex ioctl_mutex;
|
||||
struct mutex scan_mutex;
|
||||
struct aac_queue_block *queues;
|
||||
/*
|
||||
* The user API will use an IOCTL to register itself to receive
|
||||
|
|
@ -1605,6 +1611,7 @@ struct aac_dev
|
|||
int maximum_num_channels;
|
||||
struct fsa_dev_info *fsa_dev;
|
||||
struct task_struct *thread;
|
||||
struct delayed_work safw_rescan_work;
|
||||
int cardtype;
|
||||
/*
|
||||
*This lock will protect the two 32-bit
|
||||
|
|
@ -1668,9 +1675,11 @@ struct aac_dev
|
|||
u32 vector_cap; /* MSI-X vector capab.*/
|
||||
int msi_enabled; /* MSI/MSI-X enabled */
|
||||
atomic_t msix_counter;
|
||||
u32 scan_counter;
|
||||
struct msix_entry msixentry[AAC_MAX_MSIX];
|
||||
struct aac_msix_ctx aac_msix[AAC_MAX_MSIX]; /* context */
|
||||
struct aac_hba_map_info hba_map[AAC_MAX_BUSES][AAC_MAX_TARGETS];
|
||||
struct aac_ciss_phys_luns_resp *safw_phys_luns;
|
||||
u8 adapter_shutdown;
|
||||
u32 handle_pci_error;
|
||||
bool init_reset;
|
||||
|
|
@ -2023,6 +2032,12 @@ struct aac_srb_reply
|
|||
__le32 sense_data_size;
|
||||
u8 sense_data[AAC_SENSE_BUFFERSIZE]; // Can this be SCSI_SENSE_BUFFERSIZE
|
||||
};
|
||||
|
||||
struct aac_srb_unit {
|
||||
struct aac_srb srb;
|
||||
struct aac_srb_reply srb_reply;
|
||||
};
|
||||
|
||||
/*
|
||||
* SRB Flags
|
||||
*/
|
||||
|
|
@ -2627,16 +2642,41 @@ static inline int aac_adapter_check_health(struct aac_dev *dev)
|
|||
return (dev)->a_ops.adapter_check_health(dev);
|
||||
}
|
||||
|
||||
|
||||
int aac_scan_host(struct aac_dev *dev);
|
||||
|
||||
static inline void aac_schedule_safw_scan_worker(struct aac_dev *dev)
|
||||
{
|
||||
schedule_delayed_work(&dev->safw_rescan_work, AAC_SAFW_RESCAN_DELAY);
|
||||
}
|
||||
|
||||
static inline void aac_safw_rescan_worker(struct work_struct *work)
|
||||
{
|
||||
struct aac_dev *dev = container_of(to_delayed_work(work),
|
||||
struct aac_dev, safw_rescan_work);
|
||||
|
||||
wait_event(dev->scsi_host_ptr->host_wait,
|
||||
!scsi_host_in_recovery(dev->scsi_host_ptr));
|
||||
|
||||
aac_scan_host(dev);
|
||||
}
|
||||
|
||||
static inline void aac_cancel_safw_rescan_worker(struct aac_dev *dev)
|
||||
{
|
||||
if (dev->sa_firmware)
|
||||
cancel_delayed_work_sync(&dev->safw_rescan_work);
|
||||
}
|
||||
|
||||
/* SCp.phase values */
|
||||
#define AAC_OWNER_MIDLEVEL 0x101
|
||||
#define AAC_OWNER_LOWLEVEL 0x102
|
||||
#define AAC_OWNER_ERROR_HANDLER 0x103
|
||||
#define AAC_OWNER_FIRMWARE 0x106
|
||||
|
||||
void aac_safw_rescan_worker(struct work_struct *work);
|
||||
int aac_acquire_irq(struct aac_dev *dev);
|
||||
void aac_free_irq(struct aac_dev *dev);
|
||||
int aac_report_phys_luns(struct aac_dev *dev, struct fib *fibptr, int rescan);
|
||||
int aac_issue_bmic_identify(struct aac_dev *dev, u32 bus, u32 target);
|
||||
int aac_setup_safw_adapter(struct aac_dev *dev);
|
||||
const char *aac_driverinfo(struct Scsi_Host *);
|
||||
void aac_fib_vector_assign(struct aac_dev *dev);
|
||||
struct fib *aac_fib_alloc(struct aac_dev *dev);
|
||||
|
|
|
|||
|
|
@ -1052,9 +1052,13 @@ static int aac_send_reset_adapter(struct aac_dev *dev, void __user *arg)
|
|||
if (copy_from_user((void *)&reset, arg, sizeof(struct aac_reset_iop)))
|
||||
return -EFAULT;
|
||||
|
||||
retval = aac_reset_adapter(dev, 0, reset.reset_type);
|
||||
return retval;
|
||||
dev->adapter_shutdown = 1;
|
||||
|
||||
mutex_unlock(&dev->ioctl_mutex);
|
||||
retval = aac_reset_adapter(dev, 0, reset.reset_type);
|
||||
mutex_lock(&dev->ioctl_mutex);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
int aac_do_ioctl(struct aac_dev * dev, int cmd, void __user *arg)
|
||||
|
|
|
|||
|
|
@ -42,6 +42,8 @@
|
|||
#include <linux/completion.h>
|
||||
#include <linux/mm.h>
|
||||
#include <scsi/scsi_host.h>
|
||||
#include <scsi/scsi_device.h>
|
||||
#include <scsi/scsi_cmnd.h>
|
||||
|
||||
#include "aacraid.h"
|
||||
|
||||
|
|
@ -284,6 +286,38 @@ static void aac_queue_init(struct aac_dev * dev, struct aac_queue * q, u32 *mem,
|
|||
q->entries = qsize;
|
||||
}
|
||||
|
||||
static void aac_wait_for_io_completion(struct aac_dev *aac)
|
||||
{
|
||||
unsigned long flagv = 0;
|
||||
int i = 0;
|
||||
|
||||
for (i = 60; i; --i) {
|
||||
struct scsi_device *dev;
|
||||
struct scsi_cmnd *command;
|
||||
int active = 0;
|
||||
|
||||
__shost_for_each_device(dev, aac->scsi_host_ptr) {
|
||||
spin_lock_irqsave(&dev->list_lock, flagv);
|
||||
list_for_each_entry(command, &dev->cmd_list, list) {
|
||||
if (command->SCp.phase == AAC_OWNER_FIRMWARE) {
|
||||
active++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
spin_unlock_irqrestore(&dev->list_lock, flagv);
|
||||
if (active)
|
||||
break;
|
||||
|
||||
}
|
||||
/*
|
||||
* We can exit If all the commands are complete
|
||||
*/
|
||||
if (active == 0)
|
||||
break;
|
||||
ssleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* aac_send_shutdown - shutdown an adapter
|
||||
* @dev: Adapter to shutdown
|
||||
|
|
@ -295,12 +329,10 @@ int aac_send_shutdown(struct aac_dev * dev)
|
|||
{
|
||||
struct fib * fibctx;
|
||||
struct aac_close *cmd;
|
||||
int status;
|
||||
int status = 0;
|
||||
|
||||
fibctx = aac_fib_alloc(dev);
|
||||
if (!fibctx)
|
||||
return -ENOMEM;
|
||||
aac_fib_init(fibctx);
|
||||
if (aac_adapter_check_health(dev))
|
||||
return status;
|
||||
|
||||
if (!dev->adapter_shutdown) {
|
||||
mutex_lock(&dev->ioctl_mutex);
|
||||
|
|
@ -308,6 +340,13 @@ int aac_send_shutdown(struct aac_dev * dev)
|
|||
mutex_unlock(&dev->ioctl_mutex);
|
||||
}
|
||||
|
||||
aac_wait_for_io_completion(dev);
|
||||
|
||||
fibctx = aac_fib_alloc(dev);
|
||||
if (!fibctx)
|
||||
return -ENOMEM;
|
||||
aac_fib_init(fibctx);
|
||||
|
||||
cmd = (struct aac_close *) fib_data(fibctx);
|
||||
cmd->command = cpu_to_le32(VM_CloseAll);
|
||||
cmd->cid = cpu_to_le32(0xfffffffe);
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/crash_dump.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/pci.h>
|
||||
|
|
@ -1629,28 +1630,28 @@ static int _aac_reset_adapter(struct aac_dev *aac, int forced, u8 reset_type)
|
|||
command->scsi_done(command);
|
||||
}
|
||||
/*
|
||||
* Any Device that was already marked offline needs to be cleaned up
|
||||
* Any Device that was already marked offline needs to be marked
|
||||
* running
|
||||
*/
|
||||
__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);
|
||||
}
|
||||
if (!scsi_device_online(dev))
|
||||
scsi_device_set_state(dev, SDEV_RUNNING);
|
||||
}
|
||||
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 (!retval && !is_kdump_kernel()) {
|
||||
dev_info(&aac->pdev->dev, "Scheduling bus rescan\n");
|
||||
aac_schedule_safw_scan_worker(aac);
|
||||
}
|
||||
|
||||
if (jafo) {
|
||||
spin_lock_irq(host->host_lock);
|
||||
}
|
||||
|
|
@ -1681,31 +1682,6 @@ int aac_reset_adapter(struct aac_dev *aac, int forced, u8 reset_type)
|
|||
*/
|
||||
host = aac->scsi_host_ptr;
|
||||
scsi_block_requests(host);
|
||||
if (forced < 2) for (retval = 60; retval; --retval) {
|
||||
struct scsi_device * dev;
|
||||
struct scsi_cmnd * command;
|
||||
int active = 0;
|
||||
|
||||
__shost_for_each_device(dev, host) {
|
||||
spin_lock_irqsave(&dev->list_lock, flagv);
|
||||
list_for_each_entry(command, &dev->cmd_list, list) {
|
||||
if (command->SCp.phase == AAC_OWNER_FIRMWARE) {
|
||||
active++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
spin_unlock_irqrestore(&dev->list_lock, flagv);
|
||||
if (active)
|
||||
break;
|
||||
|
||||
}
|
||||
/*
|
||||
* We can exit If all the commands are complete
|
||||
*/
|
||||
if (active == 0)
|
||||
break;
|
||||
ssleep(1);
|
||||
}
|
||||
|
||||
/* Quiesce build, flush cache, write through mode */
|
||||
if (forced < 2)
|
||||
|
|
@ -1874,42 +1850,124 @@ out:
|
|||
return BlinkLED;
|
||||
}
|
||||
|
||||
static inline int is_safw_raid_volume(struct aac_dev *aac, int bus, int target)
|
||||
{
|
||||
return bus == CONTAINER_CHANNEL && target < aac->maximum_num_containers;
|
||||
}
|
||||
|
||||
static void aac_resolve_luns(struct aac_dev *dev)
|
||||
static struct scsi_device *aac_lookup_safw_scsi_device(struct aac_dev *dev,
|
||||
int bus,
|
||||
int target)
|
||||
{
|
||||
if (bus != CONTAINER_CHANNEL)
|
||||
bus = aac_phys_to_logical(bus);
|
||||
|
||||
return scsi_device_lookup(dev->scsi_host_ptr, bus, target, 0);
|
||||
}
|
||||
|
||||
static int aac_add_safw_device(struct aac_dev *dev, int bus, int target)
|
||||
{
|
||||
if (bus != CONTAINER_CHANNEL)
|
||||
bus = aac_phys_to_logical(bus);
|
||||
|
||||
return scsi_add_device(dev->scsi_host_ptr, bus, target, 0);
|
||||
}
|
||||
|
||||
static void aac_put_safw_scsi_device(struct scsi_device *sdev)
|
||||
{
|
||||
if (sdev)
|
||||
scsi_device_put(sdev);
|
||||
}
|
||||
|
||||
static void aac_remove_safw_device(struct aac_dev *dev, int bus, int target)
|
||||
{
|
||||
int bus, target, channel;
|
||||
struct scsi_device *sdev;
|
||||
u8 devtype;
|
||||
u8 new_devtype;
|
||||
|
||||
for (bus = 0; bus < AAC_MAX_BUSES; bus++) {
|
||||
for (target = 0; target < AAC_MAX_TARGETS; target++) {
|
||||
sdev = aac_lookup_safw_scsi_device(dev, bus, target);
|
||||
scsi_remove_device(sdev);
|
||||
aac_put_safw_scsi_device(sdev);
|
||||
}
|
||||
|
||||
if (bus == CONTAINER_CHANNEL)
|
||||
channel = CONTAINER_CHANNEL;
|
||||
else
|
||||
channel = aac_phys_to_logical(bus);
|
||||
static inline int aac_is_safw_scan_count_equal(struct aac_dev *dev,
|
||||
int bus, int target)
|
||||
{
|
||||
return dev->hba_map[bus][target].scan_counter == dev->scan_counter;
|
||||
}
|
||||
|
||||
devtype = dev->hba_map[bus][target].devtype;
|
||||
new_devtype = dev->hba_map[bus][target].new_devtype;
|
||||
static int aac_is_safw_target_valid(struct aac_dev *dev, int bus, int target)
|
||||
{
|
||||
if (is_safw_raid_volume(dev, bus, target))
|
||||
return dev->fsa_dev[target].valid;
|
||||
else
|
||||
return aac_is_safw_scan_count_equal(dev, bus, target);
|
||||
}
|
||||
|
||||
sdev = scsi_device_lookup(dev->scsi_host_ptr, channel,
|
||||
target, 0);
|
||||
static int aac_is_safw_device_exposed(struct aac_dev *dev, int bus, int target)
|
||||
{
|
||||
int is_exposed = 0;
|
||||
struct scsi_device *sdev;
|
||||
|
||||
if (!sdev && new_devtype)
|
||||
scsi_add_device(dev->scsi_host_ptr, channel,
|
||||
target, 0);
|
||||
else if (sdev && new_devtype != devtype)
|
||||
scsi_remove_device(sdev);
|
||||
else if (sdev && new_devtype == devtype)
|
||||
scsi_rescan_device(&sdev->sdev_gendev);
|
||||
sdev = aac_lookup_safw_scsi_device(dev, bus, target);
|
||||
if (sdev)
|
||||
is_exposed = 1;
|
||||
aac_put_safw_scsi_device(sdev);
|
||||
|
||||
if (sdev)
|
||||
scsi_device_put(sdev);
|
||||
return is_exposed;
|
||||
}
|
||||
|
||||
dev->hba_map[bus][target].devtype = new_devtype;
|
||||
}
|
||||
static int aac_update_safw_host_devices(struct aac_dev *dev)
|
||||
{
|
||||
int i;
|
||||
int bus;
|
||||
int target;
|
||||
int is_exposed = 0;
|
||||
int rcode = 0;
|
||||
|
||||
rcode = aac_setup_safw_adapter(dev);
|
||||
if (unlikely(rcode < 0)) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (i = 0; i < AAC_BUS_TARGET_LOOP; i++) {
|
||||
|
||||
bus = get_bus_number(i);
|
||||
target = get_target_number(i);
|
||||
|
||||
is_exposed = aac_is_safw_device_exposed(dev, bus, target);
|
||||
|
||||
if (aac_is_safw_target_valid(dev, bus, target) && !is_exposed)
|
||||
aac_add_safw_device(dev, bus, target);
|
||||
else if (!aac_is_safw_target_valid(dev, bus, target) &&
|
||||
is_exposed)
|
||||
aac_remove_safw_device(dev, bus, target);
|
||||
}
|
||||
out:
|
||||
return rcode;
|
||||
}
|
||||
|
||||
static int aac_scan_safw_host(struct aac_dev *dev)
|
||||
{
|
||||
int rcode = 0;
|
||||
|
||||
rcode = aac_update_safw_host_devices(dev);
|
||||
if (rcode)
|
||||
aac_schedule_safw_scan_worker(dev);
|
||||
|
||||
return rcode;
|
||||
}
|
||||
|
||||
int aac_scan_host(struct aac_dev *dev)
|
||||
{
|
||||
int rcode = 0;
|
||||
|
||||
mutex_lock(&dev->scan_mutex);
|
||||
if (dev->sa_firmware)
|
||||
rcode = aac_scan_safw_host(dev);
|
||||
else
|
||||
scsi_scan_host(dev->scsi_host_ptr);
|
||||
mutex_unlock(&dev->scan_mutex);
|
||||
|
||||
return rcode;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1922,10 +1980,8 @@ static void aac_resolve_luns(struct aac_dev *dev)
|
|||
*/
|
||||
static void aac_handle_sa_aif(struct aac_dev *dev, struct fib *fibptr)
|
||||
{
|
||||
int i, bus, target, container, rcode = 0;
|
||||
int i;
|
||||
u32 events = 0;
|
||||
struct fib *fib;
|
||||
struct scsi_device *sdev;
|
||||
|
||||
if (fibptr->hbacmd_size & SA_AIF_HOTPLUG)
|
||||
events = SA_AIF_HOTPLUG;
|
||||
|
|
@ -1947,44 +2003,8 @@ static void aac_handle_sa_aif(struct aac_dev *dev, struct fib *fibptr)
|
|||
case SA_AIF_LDEV_CHANGE:
|
||||
case SA_AIF_BPCFG_CHANGE:
|
||||
|
||||
fib = aac_fib_alloc(dev);
|
||||
if (!fib) {
|
||||
pr_err("aac_handle_sa_aif: out of memory\n");
|
||||
return;
|
||||
}
|
||||
for (bus = 0; bus < AAC_MAX_BUSES; bus++)
|
||||
for (target = 0; target < AAC_MAX_TARGETS; target++)
|
||||
dev->hba_map[bus][target].new_devtype = 0;
|
||||
aac_scan_host(dev);
|
||||
|
||||
rcode = aac_report_phys_luns(dev, fib, AAC_RESCAN);
|
||||
|
||||
if (rcode != -ERESTARTSYS)
|
||||
aac_fib_free(fib);
|
||||
|
||||
aac_resolve_luns(dev);
|
||||
|
||||
if (events == SA_AIF_LDEV_CHANGE ||
|
||||
events == SA_AIF_BPCFG_CHANGE) {
|
||||
aac_get_containers(dev);
|
||||
for (container = 0; container <
|
||||
dev->maximum_num_containers; ++container) {
|
||||
sdev = scsi_device_lookup(dev->scsi_host_ptr,
|
||||
CONTAINER_CHANNEL,
|
||||
container, 0);
|
||||
if (dev->fsa_dev[container].valid && !sdev) {
|
||||
scsi_add_device(dev->scsi_host_ptr,
|
||||
CONTAINER_CHANNEL,
|
||||
container, 0);
|
||||
} else if (!dev->fsa_dev[container].valid &&
|
||||
sdev) {
|
||||
scsi_remove_device(sdev);
|
||||
scsi_device_put(sdev);
|
||||
} else if (sdev) {
|
||||
scsi_rescan_device(&sdev->sdev_gendev);
|
||||
scsi_device_put(sdev);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SA_AIF_BPSTAT_CHANGE:
|
||||
|
|
|
|||
|
|
@ -683,6 +683,9 @@ static int aac_eh_abort(struct scsi_cmnd* cmd)
|
|||
u32 bus, cid;
|
||||
int ret = FAILED;
|
||||
|
||||
if (aac_adapter_check_health(aac))
|
||||
return ret;
|
||||
|
||||
bus = aac_logical_to_phys(scmd_channel(cmd));
|
||||
cid = scmd_id(cmd);
|
||||
if (aac->hba_map[bus][cid].devtype == AAC_DEVTYPE_NATIVE_RAW) {
|
||||
|
|
@ -690,7 +693,6 @@ static int aac_eh_abort(struct scsi_cmnd* cmd)
|
|||
struct aac_hba_tm_req *tmf;
|
||||
int status;
|
||||
u64 address;
|
||||
__le32 managed_request_id;
|
||||
|
||||
pr_err("%s: Host adapter abort request (%d,%d,%d,%d)\n",
|
||||
AAC_DRIVERNAME,
|
||||
|
|
@ -703,8 +705,6 @@ static int aac_eh_abort(struct scsi_cmnd* cmd)
|
|||
(fib->flags & FIB_CONTEXT_FLAG_NATIVE_HBA) &&
|
||||
(fib->callback_data == cmd)) {
|
||||
found = 1;
|
||||
managed_request_id = ((struct aac_hba_cmd_req *)
|
||||
fib->hw_fib_va)->request_id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -1375,18 +1375,15 @@ static ssize_t aac_store_reset_adapter(struct device *device,
|
|||
const char *buf, size_t count)
|
||||
{
|
||||
int retval = -EACCES;
|
||||
int bled = 0;
|
||||
struct aac_dev *aac;
|
||||
|
||||
|
||||
if (!capable(CAP_SYS_ADMIN))
|
||||
return retval;
|
||||
|
||||
aac = (struct aac_dev *)class_to_shost(device)->hostdata;
|
||||
bled = buf[0] == '!' ? 1:0;
|
||||
retval = aac_reset_adapter(aac, bled, IOP_HWSOFT_RESET);
|
||||
retval = aac_reset_adapter(shost_priv(class_to_shost(device)),
|
||||
buf[0] == '!', IOP_HWSOFT_RESET);
|
||||
if (retval >= 0)
|
||||
retval = count;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
@ -1689,6 +1686,9 @@ static int aac_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
|||
spin_lock_init(&aac->fib_lock);
|
||||
|
||||
mutex_init(&aac->ioctl_mutex);
|
||||
mutex_init(&aac->scan_mutex);
|
||||
|
||||
INIT_DELAYED_WORK(&aac->safw_rescan_work, aac_safw_rescan_worker);
|
||||
/*
|
||||
* Map in the registers from the adapter.
|
||||
*/
|
||||
|
|
@ -1792,7 +1792,8 @@ static int aac_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
|||
error = scsi_add_host(shost, &pdev->dev);
|
||||
if (error)
|
||||
goto out_deinit;
|
||||
scsi_scan_host(shost);
|
||||
|
||||
aac_scan_host(aac);
|
||||
|
||||
pci_enable_pcie_error_reporting(pdev);
|
||||
pci_save_state(pdev);
|
||||
|
|
@ -1877,6 +1878,7 @@ static int aac_suspend(struct pci_dev *pdev, pm_message_t state)
|
|||
struct aac_dev *aac = (struct aac_dev *)shost->hostdata;
|
||||
|
||||
scsi_block_requests(shost);
|
||||
aac_cancel_safw_rescan_worker(aac);
|
||||
aac_send_shutdown(aac);
|
||||
|
||||
aac_release_resources(aac);
|
||||
|
|
@ -1935,6 +1937,7 @@ static void aac_remove_one(struct pci_dev *pdev)
|
|||
struct Scsi_Host *shost = pci_get_drvdata(pdev);
|
||||
struct aac_dev *aac = (struct aac_dev *)shost->hostdata;
|
||||
|
||||
aac_cancel_safw_rescan_worker(aac);
|
||||
scsi_remove_host(shost);
|
||||
|
||||
__aac_shutdown(aac);
|
||||
|
|
@ -1992,6 +1995,7 @@ static pci_ers_result_t aac_pci_error_detected(struct pci_dev *pdev,
|
|||
aac->handle_pci_error = 1;
|
||||
|
||||
scsi_block_requests(aac->scsi_host_ptr);
|
||||
aac_cancel_safw_rescan_worker(aac);
|
||||
aac_flush_ios(aac);
|
||||
aac_release_resources(aac);
|
||||
|
||||
|
|
@ -2076,7 +2080,7 @@ static void aac_pci_resume(struct pci_dev *pdev)
|
|||
if (sdev->sdev_state == SDEV_OFFLINE)
|
||||
sdev->sdev_state = SDEV_RUNNING;
|
||||
scsi_unblock_requests(aac->scsi_host_ptr);
|
||||
scsi_scan_host(aac->scsi_host_ptr);
|
||||
aac_scan_host(aac);
|
||||
pci_save_state(pdev);
|
||||
|
||||
dev_err(&pdev->dev, "aacraid: PCI error - resume\n");
|
||||
|
|
|
|||
|
|
@ -329,6 +329,22 @@ int aac_sa_init(struct aac_dev *dev)
|
|||
instance = dev->id;
|
||||
name = dev->name;
|
||||
|
||||
/*
|
||||
* Fill in the function dispatch table.
|
||||
*/
|
||||
|
||||
dev->a_ops.adapter_interrupt = aac_sa_interrupt_adapter;
|
||||
dev->a_ops.adapter_disable_int = aac_sa_disable_interrupt;
|
||||
dev->a_ops.adapter_enable_int = aac_sa_enable_interrupt;
|
||||
dev->a_ops.adapter_notify = aac_sa_notify_adapter;
|
||||
dev->a_ops.adapter_sync_cmd = sa_sync_cmd;
|
||||
dev->a_ops.adapter_check_health = aac_sa_check_health;
|
||||
dev->a_ops.adapter_restart = aac_sa_restart_adapter;
|
||||
dev->a_ops.adapter_start = aac_sa_start_adapter;
|
||||
dev->a_ops.adapter_intr = aac_sa_intr;
|
||||
dev->a_ops.adapter_deliver = aac_rx_deliver_producer;
|
||||
dev->a_ops.adapter_ioremap = aac_sa_ioremap;
|
||||
|
||||
if (aac_sa_ioremap(dev, dev->base_size)) {
|
||||
printk(KERN_WARNING "%s: unable to map adapter.\n", name);
|
||||
goto error_iounmap;
|
||||
|
|
@ -362,22 +378,6 @@ int aac_sa_init(struct aac_dev *dev)
|
|||
msleep(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Fill in the function dispatch table.
|
||||
*/
|
||||
|
||||
dev->a_ops.adapter_interrupt = aac_sa_interrupt_adapter;
|
||||
dev->a_ops.adapter_disable_int = aac_sa_disable_interrupt;
|
||||
dev->a_ops.adapter_enable_int = aac_sa_enable_interrupt;
|
||||
dev->a_ops.adapter_notify = aac_sa_notify_adapter;
|
||||
dev->a_ops.adapter_sync_cmd = sa_sync_cmd;
|
||||
dev->a_ops.adapter_check_health = aac_sa_check_health;
|
||||
dev->a_ops.adapter_restart = aac_sa_restart_adapter;
|
||||
dev->a_ops.adapter_start = aac_sa_start_adapter;
|
||||
dev->a_ops.adapter_intr = aac_sa_intr;
|
||||
dev->a_ops.adapter_deliver = aac_rx_deliver_producer;
|
||||
dev->a_ops.adapter_ioremap = aac_sa_ioremap;
|
||||
|
||||
/*
|
||||
* First clear out all interrupts. Then enable the one's that
|
||||
* we can handle.
|
||||
|
|
|
|||
|
|
@ -45,52 +45,57 @@
|
|||
#include <linux/interrupt.h>
|
||||
struct device_attribute;
|
||||
/*The limit of outstanding scsi command that firmware can handle*/
|
||||
#ifdef CONFIG_XEN
|
||||
#define ARCMSR_MAX_FREECCB_NUM 160
|
||||
#define ARCMSR_MAX_OUTSTANDING_CMD 155
|
||||
#else
|
||||
#define ARCMSR_MAX_FREECCB_NUM 320
|
||||
#define ARCMSR_MAX_OUTSTANDING_CMD 255
|
||||
#endif
|
||||
#define ARCMSR_DRIVER_VERSION "v1.30.00.22-20151126"
|
||||
#define ARCMSR_SCSI_INITIATOR_ID 255
|
||||
#define ARCMSR_MAX_XFER_SECTORS 512
|
||||
#define ARCMSR_MAX_XFER_SECTORS_B 4096
|
||||
#define ARCMSR_MAX_XFER_SECTORS_C 304
|
||||
#define ARCMSR_MAX_TARGETID 17
|
||||
#define ARCMSR_MAX_TARGETLUN 8
|
||||
#define ARCMSR_MAX_CMD_PERLUN ARCMSR_MAX_OUTSTANDING_CMD
|
||||
#define ARCMSR_MAX_QBUFFER 4096
|
||||
#define ARCMSR_DEFAULT_SG_ENTRIES 38
|
||||
#define ARCMSR_MAX_HBB_POSTQUEUE 264
|
||||
#define ARCMSR_MAX_FREECCB_NUM 1024
|
||||
#define ARCMSR_MAX_OUTSTANDING_CMD 1024
|
||||
#define ARCMSR_DEFAULT_OUTSTANDING_CMD 128
|
||||
#define ARCMSR_MIN_OUTSTANDING_CMD 32
|
||||
#define ARCMSR_DRIVER_VERSION "v1.40.00.04-20171130"
|
||||
#define ARCMSR_SCSI_INITIATOR_ID 255
|
||||
#define ARCMSR_MAX_XFER_SECTORS 512
|
||||
#define ARCMSR_MAX_XFER_SECTORS_B 4096
|
||||
#define ARCMSR_MAX_XFER_SECTORS_C 304
|
||||
#define ARCMSR_MAX_TARGETID 17
|
||||
#define ARCMSR_MAX_TARGETLUN 8
|
||||
#define ARCMSR_MAX_CMD_PERLUN 128
|
||||
#define ARCMSR_DEFAULT_CMD_PERLUN 32
|
||||
#define ARCMSR_MIN_CMD_PERLUN 1
|
||||
#define ARCMSR_MAX_QBUFFER 4096
|
||||
#define ARCMSR_DEFAULT_SG_ENTRIES 38
|
||||
#define ARCMSR_MAX_HBB_POSTQUEUE 264
|
||||
#define ARCMSR_MAX_ARC1214_POSTQUEUE 256
|
||||
#define ARCMSR_MAX_ARC1214_DONEQUEUE 257
|
||||
#define ARCMSR_MAX_XFER_LEN 0x26000 /* 152K */
|
||||
#define ARCMSR_CDB_SG_PAGE_LENGTH 256
|
||||
#define ARCMSR_MAX_HBE_DONEQUEUE 512
|
||||
#define ARCMSR_MAX_XFER_LEN 0x26000 /* 152K */
|
||||
#define ARCMSR_CDB_SG_PAGE_LENGTH 256
|
||||
#define ARCMST_NUM_MSIX_VECTORS 4
|
||||
#ifndef PCI_DEVICE_ID_ARECA_1880
|
||||
#define PCI_DEVICE_ID_ARECA_1880 0x1880
|
||||
#endif
|
||||
#define PCI_DEVICE_ID_ARECA_1880 0x1880
|
||||
#endif
|
||||
#ifndef PCI_DEVICE_ID_ARECA_1214
|
||||
#define PCI_DEVICE_ID_ARECA_1214 0x1214
|
||||
#define PCI_DEVICE_ID_ARECA_1214 0x1214
|
||||
#endif
|
||||
#ifndef PCI_DEVICE_ID_ARECA_1203
|
||||
#define PCI_DEVICE_ID_ARECA_1203 0x1203
|
||||
#define PCI_DEVICE_ID_ARECA_1203 0x1203
|
||||
#endif
|
||||
#ifndef PCI_DEVICE_ID_ARECA_1884
|
||||
#define PCI_DEVICE_ID_ARECA_1884 0x1884
|
||||
#endif
|
||||
#define ARCMSR_HOURS (1000 * 60 * 60 * 4)
|
||||
#define ARCMSR_MINUTES (1000 * 60 * 60)
|
||||
/*
|
||||
**********************************************************************************
|
||||
**
|
||||
**********************************************************************************
|
||||
*/
|
||||
#define ARC_SUCCESS 0
|
||||
#define ARC_FAILURE 1
|
||||
#define ARC_SUCCESS 0
|
||||
#define ARC_FAILURE 1
|
||||
/*
|
||||
*******************************************************************************
|
||||
** split 64bits dma addressing
|
||||
*******************************************************************************
|
||||
*/
|
||||
#define dma_addr_hi32(addr) (uint32_t) ((addr>>16)>>16)
|
||||
#define dma_addr_lo32(addr) (uint32_t) (addr & 0xffffffff)
|
||||
#define dma_addr_hi32(addr) (uint32_t) ((addr>>16)>>16)
|
||||
#define dma_addr_lo32(addr) (uint32_t) (addr & 0xffffffff)
|
||||
/*
|
||||
*******************************************************************************
|
||||
** MESSAGE CONTROL CODE
|
||||
|
|
@ -130,7 +135,7 @@ struct CMD_MESSAGE_FIELD
|
|||
#define FUNCTION_SAY_HELLO 0x0807
|
||||
#define FUNCTION_SAY_GOODBYE 0x0808
|
||||
#define FUNCTION_FLUSH_ADAPTER_CACHE 0x0809
|
||||
#define FUNCTION_GET_FIRMWARE_STATUS 0x080A
|
||||
#define FUNCTION_GET_FIRMWARE_STATUS 0x080A
|
||||
#define FUNCTION_HARDWARE_RESET 0x080B
|
||||
/* ARECA IO CONTROL CODE*/
|
||||
#define ARCMSR_MESSAGE_READ_RQBUFFER \
|
||||
|
|
@ -161,18 +166,18 @@ struct CMD_MESSAGE_FIELD
|
|||
** structure for holding DMA address data
|
||||
*************************************************************
|
||||
*/
|
||||
#define IS_DMA64 (sizeof(dma_addr_t) == 8)
|
||||
#define IS_SG64_ADDR 0x01000000 /* bit24 */
|
||||
#define IS_DMA64 (sizeof(dma_addr_t) == 8)
|
||||
#define IS_SG64_ADDR 0x01000000 /* bit24 */
|
||||
struct SG32ENTRY
|
||||
{
|
||||
__le32 length;
|
||||
__le32 address;
|
||||
__le32 length;
|
||||
__le32 address;
|
||||
}__attribute__ ((packed));
|
||||
struct SG64ENTRY
|
||||
{
|
||||
__le32 length;
|
||||
__le32 address;
|
||||
__le32 addresshigh;
|
||||
__le32 length;
|
||||
__le32 address;
|
||||
__le32 addresshigh;
|
||||
}__attribute__ ((packed));
|
||||
/*
|
||||
********************************************************************
|
||||
|
|
@ -191,50 +196,50 @@ struct QBUFFER
|
|||
*/
|
||||
struct FIRMWARE_INFO
|
||||
{
|
||||
uint32_t signature; /*0, 00-03*/
|
||||
uint32_t request_len; /*1, 04-07*/
|
||||
uint32_t numbers_queue; /*2, 08-11*/
|
||||
uint32_t sdram_size; /*3, 12-15*/
|
||||
uint32_t ide_channels; /*4, 16-19*/
|
||||
char vendor[40]; /*5, 20-59*/
|
||||
char model[8]; /*15, 60-67*/
|
||||
char firmware_ver[16]; /*17, 68-83*/
|
||||
char device_map[16]; /*21, 84-99*/
|
||||
uint32_t cfgVersion; /*25,100-103 Added for checking of new firmware capability*/
|
||||
uint8_t cfgSerial[16]; /*26,104-119*/
|
||||
uint32_t cfgPicStatus; /*30,120-123*/
|
||||
uint32_t signature; /*0, 00-03*/
|
||||
uint32_t request_len; /*1, 04-07*/
|
||||
uint32_t numbers_queue; /*2, 08-11*/
|
||||
uint32_t sdram_size; /*3, 12-15*/
|
||||
uint32_t ide_channels; /*4, 16-19*/
|
||||
char vendor[40]; /*5, 20-59*/
|
||||
char model[8]; /*15, 60-67*/
|
||||
char firmware_ver[16]; /*17, 68-83*/
|
||||
char device_map[16]; /*21, 84-99*/
|
||||
uint32_t cfgVersion; /*25,100-103 Added for checking of new firmware capability*/
|
||||
uint8_t cfgSerial[16]; /*26,104-119*/
|
||||
uint32_t cfgPicStatus; /*30,120-123*/
|
||||
};
|
||||
/* signature of set and get firmware config */
|
||||
#define ARCMSR_SIGNATURE_GET_CONFIG 0x87974060
|
||||
#define ARCMSR_SIGNATURE_SET_CONFIG 0x87974063
|
||||
#define ARCMSR_SIGNATURE_GET_CONFIG 0x87974060
|
||||
#define ARCMSR_SIGNATURE_SET_CONFIG 0x87974063
|
||||
/* message code of inbound message register */
|
||||
#define ARCMSR_INBOUND_MESG0_NOP 0x00000000
|
||||
#define ARCMSR_INBOUND_MESG0_GET_CONFIG 0x00000001
|
||||
#define ARCMSR_INBOUND_MESG0_SET_CONFIG 0x00000002
|
||||
#define ARCMSR_INBOUND_MESG0_ABORT_CMD 0x00000003
|
||||
#define ARCMSR_INBOUND_MESG0_STOP_BGRB 0x00000004
|
||||
#define ARCMSR_INBOUND_MESG0_FLUSH_CACHE 0x00000005
|
||||
#define ARCMSR_INBOUND_MESG0_START_BGRB 0x00000006
|
||||
#define ARCMSR_INBOUND_MESG0_CHK331PENDING 0x00000007
|
||||
#define ARCMSR_INBOUND_MESG0_SYNC_TIMER 0x00000008
|
||||
#define ARCMSR_INBOUND_MESG0_NOP 0x00000000
|
||||
#define ARCMSR_INBOUND_MESG0_GET_CONFIG 0x00000001
|
||||
#define ARCMSR_INBOUND_MESG0_SET_CONFIG 0x00000002
|
||||
#define ARCMSR_INBOUND_MESG0_ABORT_CMD 0x00000003
|
||||
#define ARCMSR_INBOUND_MESG0_STOP_BGRB 0x00000004
|
||||
#define ARCMSR_INBOUND_MESG0_FLUSH_CACHE 0x00000005
|
||||
#define ARCMSR_INBOUND_MESG0_START_BGRB 0x00000006
|
||||
#define ARCMSR_INBOUND_MESG0_CHK331PENDING 0x00000007
|
||||
#define ARCMSR_INBOUND_MESG0_SYNC_TIMER 0x00000008
|
||||
/* doorbell interrupt generator */
|
||||
#define ARCMSR_INBOUND_DRIVER_DATA_WRITE_OK 0x00000001
|
||||
#define ARCMSR_INBOUND_DRIVER_DATA_READ_OK 0x00000002
|
||||
#define ARCMSR_OUTBOUND_IOP331_DATA_WRITE_OK 0x00000001
|
||||
#define ARCMSR_OUTBOUND_IOP331_DATA_READ_OK 0x00000002
|
||||
#define ARCMSR_INBOUND_DRIVER_DATA_WRITE_OK 0x00000001
|
||||
#define ARCMSR_INBOUND_DRIVER_DATA_READ_OK 0x00000002
|
||||
#define ARCMSR_OUTBOUND_IOP331_DATA_WRITE_OK 0x00000001
|
||||
#define ARCMSR_OUTBOUND_IOP331_DATA_READ_OK 0x00000002
|
||||
/* ccb areca cdb flag */
|
||||
#define ARCMSR_CCBPOST_FLAG_SGL_BSIZE 0x80000000
|
||||
#define ARCMSR_CCBPOST_FLAG_IAM_BIOS 0x40000000
|
||||
#define ARCMSR_CCBREPLY_FLAG_IAM_BIOS 0x40000000
|
||||
#define ARCMSR_CCBREPLY_FLAG_ERROR_MODE0 0x10000000
|
||||
#define ARCMSR_CCBREPLY_FLAG_ERROR_MODE1 0x00000001
|
||||
#define ARCMSR_CCBPOST_FLAG_SGL_BSIZE 0x80000000
|
||||
#define ARCMSR_CCBPOST_FLAG_IAM_BIOS 0x40000000
|
||||
#define ARCMSR_CCBREPLY_FLAG_IAM_BIOS 0x40000000
|
||||
#define ARCMSR_CCBREPLY_FLAG_ERROR_MODE0 0x10000000
|
||||
#define ARCMSR_CCBREPLY_FLAG_ERROR_MODE1 0x00000001
|
||||
/* outbound firmware ok */
|
||||
#define ARCMSR_OUTBOUND_MESG1_FIRMWARE_OK 0x80000000
|
||||
#define ARCMSR_OUTBOUND_MESG1_FIRMWARE_OK 0x80000000
|
||||
/* ARC-1680 Bus Reset*/
|
||||
#define ARCMSR_ARC1680_BUS_RESET 0x00000003
|
||||
#define ARCMSR_ARC1680_BUS_RESET 0x00000003
|
||||
/* ARC-1880 Bus Reset*/
|
||||
#define ARCMSR_ARC1880_RESET_ADAPTER 0x00000024
|
||||
#define ARCMSR_ARC1880_DiagWrite_ENABLE 0x00000080
|
||||
#define ARCMSR_ARC1880_RESET_ADAPTER 0x00000024
|
||||
#define ARCMSR_ARC1880_DiagWrite_ENABLE 0x00000080
|
||||
|
||||
/*
|
||||
************************************************************************
|
||||
|
|
@ -277,9 +282,10 @@ struct FIRMWARE_INFO
|
|||
#define ARCMSR_MESSAGE_FLUSH_CACHE 0x00050008
|
||||
/* (ARCMSR_INBOUND_MESG0_START_BGRB<<16)|ARCMSR_DRV2IOP_MESSAGE_CMD_POSTED) */
|
||||
#define ARCMSR_MESSAGE_START_BGRB 0x00060008
|
||||
#define ARCMSR_MESSAGE_SYNC_TIMER 0x00080008
|
||||
#define ARCMSR_MESSAGE_START_DRIVER_MODE 0x000E0008
|
||||
#define ARCMSR_MESSAGE_SET_POST_WINDOW 0x000F0008
|
||||
#define ARCMSR_MESSAGE_ACTIVE_EOI_MODE 0x00100008
|
||||
#define ARCMSR_MESSAGE_ACTIVE_EOI_MODE 0x00100008
|
||||
/* ARCMSR_OUTBOUND_MESG1_FIRMWARE_OK */
|
||||
#define ARCMSR_MESSAGE_FIRMWARE_OK 0x80000000
|
||||
/* ioctl transfer */
|
||||
|
|
@ -288,7 +294,7 @@ struct FIRMWARE_INFO
|
|||
#define ARCMSR_DRV2IOP_DATA_READ_OK 0x00000002
|
||||
#define ARCMSR_DRV2IOP_CDB_POSTED 0x00000004
|
||||
#define ARCMSR_DRV2IOP_MESSAGE_CMD_POSTED 0x00000008
|
||||
#define ARCMSR_DRV2IOP_END_OF_INTERRUPT 0x00000010
|
||||
#define ARCMSR_DRV2IOP_END_OF_INTERRUPT 0x00000010
|
||||
|
||||
/* data tunnel buffer between user space program and its firmware */
|
||||
/* user space data to iop 128bytes */
|
||||
|
|
@ -313,12 +319,12 @@ struct FIRMWARE_INFO
|
|||
#define ARCMSR_HBCMU_OUTBOUND_POSTQUEUE_ISR_MASK 0x00000008 /* When clear, the Outbound Post List FIFO Not Empty interrupt routes to the host.*/
|
||||
#define ARCMSR_HBCMU_ALL_INTMASKENABLE 0x0000000D /* disable all ISR */
|
||||
/* Host Interrupt Status */
|
||||
#define ARCMSR_HBCMU_UTILITY_A_ISR 0x00000001
|
||||
#define ARCMSR_HBCMU_UTILITY_A_ISR 0x00000001
|
||||
/*
|
||||
** Set when the Utility_A Interrupt bit is set in the Outbound Doorbell Register.
|
||||
** It clears by writing a 1 to the Utility_A bit in the Outbound Doorbell Clear Register or through automatic clearing (if enabled).
|
||||
*/
|
||||
#define ARCMSR_HBCMU_OUTBOUND_DOORBELL_ISR 0x00000004
|
||||
#define ARCMSR_HBCMU_OUTBOUND_DOORBELL_ISR 0x00000004
|
||||
/*
|
||||
** Set if Outbound Doorbell register bits 30:1 have a non-zero
|
||||
** value. This bit clears only when Outbound Doorbell bits
|
||||
|
|
@ -331,7 +337,7 @@ struct FIRMWARE_INFO
|
|||
** Register (FIFO) is not empty. It clears when the Outbound
|
||||
** Post List FIFO is empty.
|
||||
*/
|
||||
#define ARCMSR_HBCMU_SAS_ALL_INT 0x00000010
|
||||
#define ARCMSR_HBCMU_SAS_ALL_INT 0x00000010
|
||||
/*
|
||||
** This bit indicates a SAS interrupt from a source external to
|
||||
** the PCIe core. This bit is not maskable.
|
||||
|
|
@ -340,17 +346,17 @@ struct FIRMWARE_INFO
|
|||
#define ARCMSR_HBCMU_DRV2IOP_DATA_WRITE_OK 0x00000002
|
||||
#define ARCMSR_HBCMU_DRV2IOP_DATA_READ_OK 0x00000004
|
||||
/*inbound message 0 ready*/
|
||||
#define ARCMSR_HBCMU_DRV2IOP_MESSAGE_CMD_DONE 0x00000008
|
||||
#define ARCMSR_HBCMU_DRV2IOP_MESSAGE_CMD_DONE 0x00000008
|
||||
/*more than 12 request completed in a time*/
|
||||
#define ARCMSR_HBCMU_DRV2IOP_POSTQUEUE_THROTTLING 0x00000010
|
||||
#define ARCMSR_HBCMU_IOP2DRV_DATA_WRITE_OK 0x00000002
|
||||
/*outbound DATA WRITE isr door bell clear*/
|
||||
#define ARCMSR_HBCMU_IOP2DRV_DATA_WRITE_DOORBELL_CLEAR 0x00000002
|
||||
#define ARCMSR_HBCMU_IOP2DRV_DATA_WRITE_DOORBELL_CLEAR 0x00000002
|
||||
#define ARCMSR_HBCMU_IOP2DRV_DATA_READ_OK 0x00000004
|
||||
/*outbound DATA READ isr door bell clear*/
|
||||
#define ARCMSR_HBCMU_IOP2DRV_DATA_READ_DOORBELL_CLEAR 0x00000004
|
||||
#define ARCMSR_HBCMU_IOP2DRV_DATA_READ_DOORBELL_CLEAR 0x00000004
|
||||
/*outbound message 0 ready*/
|
||||
#define ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE 0x00000008
|
||||
#define ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE 0x00000008
|
||||
/*outbound message cmd isr door bell clear*/
|
||||
#define ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE_DOORBELL_CLEAR 0x00000008
|
||||
/*ARCMSR_HBAMU_MESSAGE_FIRMWARE_OK*/
|
||||
|
|
@ -407,18 +413,43 @@ struct FIRMWARE_INFO
|
|||
#define ARCMSR_ARC1214_OUTBOUND_LIST_INTERRUPT_CLEAR 0x00000001
|
||||
/*
|
||||
*******************************************************************************
|
||||
** SPEC. for Areca Type E adapter
|
||||
*******************************************************************************
|
||||
*/
|
||||
#define ARCMSR_SIGNATURE_1884 0x188417D3
|
||||
|
||||
#define ARCMSR_HBEMU_DRV2IOP_DATA_WRITE_OK 0x00000002
|
||||
#define ARCMSR_HBEMU_DRV2IOP_DATA_READ_OK 0x00000004
|
||||
#define ARCMSR_HBEMU_DRV2IOP_MESSAGE_CMD_DONE 0x00000008
|
||||
|
||||
#define ARCMSR_HBEMU_IOP2DRV_DATA_WRITE_OK 0x00000002
|
||||
#define ARCMSR_HBEMU_IOP2DRV_DATA_READ_OK 0x00000004
|
||||
#define ARCMSR_HBEMU_IOP2DRV_MESSAGE_CMD_DONE 0x00000008
|
||||
|
||||
#define ARCMSR_HBEMU_MESSAGE_FIRMWARE_OK 0x80000000
|
||||
|
||||
#define ARCMSR_HBEMU_OUTBOUND_DOORBELL_ISR 0x00000001
|
||||
#define ARCMSR_HBEMU_OUTBOUND_POSTQUEUE_ISR 0x00000008
|
||||
#define ARCMSR_HBEMU_ALL_INTMASKENABLE 0x00000009
|
||||
|
||||
/* ARC-1884 doorbell sync */
|
||||
#define ARCMSR_HBEMU_DOORBELL_SYNC 0x100
|
||||
#define ARCMSR_ARC188X_RESET_ADAPTER 0x00000004
|
||||
#define ARCMSR_ARC1884_DiagWrite_ENABLE 0x00000080
|
||||
/*
|
||||
*******************************************************************************
|
||||
** ARECA SCSI COMMAND DESCRIPTOR BLOCK size 0x1F8 (504)
|
||||
*******************************************************************************
|
||||
*/
|
||||
struct ARCMSR_CDB
|
||||
{
|
||||
uint8_t Bus;
|
||||
uint8_t TargetID;
|
||||
uint8_t LUN;
|
||||
uint8_t Function;
|
||||
uint8_t CdbLength;
|
||||
uint8_t sgcount;
|
||||
uint8_t Flags;
|
||||
uint8_t Bus;
|
||||
uint8_t TargetID;
|
||||
uint8_t LUN;
|
||||
uint8_t Function;
|
||||
uint8_t CdbLength;
|
||||
uint8_t sgcount;
|
||||
uint8_t Flags;
|
||||
#define ARCMSR_CDB_FLAG_SGL_BSIZE 0x01
|
||||
#define ARCMSR_CDB_FLAG_BIOS 0x02
|
||||
#define ARCMSR_CDB_FLAG_WRITE 0x04
|
||||
|
|
@ -426,21 +457,21 @@ struct ARCMSR_CDB
|
|||
#define ARCMSR_CDB_FLAG_HEADQ 0x08
|
||||
#define ARCMSR_CDB_FLAG_ORDEREDQ 0x10
|
||||
|
||||
uint8_t msgPages;
|
||||
uint32_t msgContext;
|
||||
uint32_t DataLength;
|
||||
uint8_t Cdb[16];
|
||||
uint8_t DeviceStatus;
|
||||
uint8_t msgPages;
|
||||
uint32_t msgContext;
|
||||
uint32_t DataLength;
|
||||
uint8_t Cdb[16];
|
||||
uint8_t DeviceStatus;
|
||||
#define ARCMSR_DEV_CHECK_CONDITION 0x02
|
||||
#define ARCMSR_DEV_SELECT_TIMEOUT 0xF0
|
||||
#define ARCMSR_DEV_ABORTED 0xF1
|
||||
#define ARCMSR_DEV_INIT_FAIL 0xF2
|
||||
|
||||
uint8_t SenseData[15];
|
||||
uint8_t SenseData[15];
|
||||
union
|
||||
{
|
||||
struct SG32ENTRY sg32entry[1];
|
||||
struct SG64ENTRY sg64entry[1];
|
||||
struct SG32ENTRY sg32entry[1];
|
||||
struct SG64ENTRY sg64entry[1];
|
||||
} u;
|
||||
};
|
||||
/*
|
||||
|
|
@ -480,13 +511,13 @@ struct MessageUnit_B
|
|||
uint32_t done_qbuffer[ARCMSR_MAX_HBB_POSTQUEUE];
|
||||
uint32_t postq_index;
|
||||
uint32_t doneq_index;
|
||||
uint32_t __iomem *drv2iop_doorbell;
|
||||
uint32_t __iomem *drv2iop_doorbell_mask;
|
||||
uint32_t __iomem *iop2drv_doorbell;
|
||||
uint32_t __iomem *iop2drv_doorbell_mask;
|
||||
uint32_t __iomem *message_rwbuffer;
|
||||
uint32_t __iomem *message_wbuffer;
|
||||
uint32_t __iomem *message_rbuffer;
|
||||
uint32_t __iomem *drv2iop_doorbell;
|
||||
uint32_t __iomem *drv2iop_doorbell_mask;
|
||||
uint32_t __iomem *iop2drv_doorbell;
|
||||
uint32_t __iomem *iop2drv_doorbell_mask;
|
||||
uint32_t __iomem *message_rwbuffer;
|
||||
uint32_t __iomem *message_wbuffer;
|
||||
uint32_t __iomem *message_rbuffer;
|
||||
};
|
||||
/*
|
||||
*********************************************************************
|
||||
|
|
@ -506,7 +537,7 @@ struct MessageUnit_C{
|
|||
uint32_t diagnostic_rw_data; /*0024 0027*/
|
||||
uint32_t diagnostic_rw_address_low; /*0028 002B*/
|
||||
uint32_t diagnostic_rw_address_high; /*002C 002F*/
|
||||
uint32_t host_int_status; /*0030 0033*/
|
||||
uint32_t host_int_status; /*0030 0033*/
|
||||
uint32_t host_int_mask; /*0034 0037*/
|
||||
uint32_t dcr_data; /*0038 003B*/
|
||||
uint32_t dcr_address; /*003C 003F*/
|
||||
|
|
@ -518,12 +549,12 @@ struct MessageUnit_C{
|
|||
uint32_t iop_int_mask; /*0054 0057*/
|
||||
uint32_t iop_inbound_queue_port; /*0058 005B*/
|
||||
uint32_t iop_outbound_queue_port; /*005C 005F*/
|
||||
uint32_t inbound_free_list_index; /*0060 0063*/
|
||||
uint32_t inbound_post_list_index; /*0064 0067*/
|
||||
uint32_t outbound_free_list_index; /*0068 006B*/
|
||||
uint32_t outbound_post_list_index; /*006C 006F*/
|
||||
uint32_t inbound_free_list_index; /*0060 0063*/
|
||||
uint32_t inbound_post_list_index; /*0064 0067*/
|
||||
uint32_t outbound_free_list_index; /*0068 006B*/
|
||||
uint32_t outbound_post_list_index; /*006C 006F*/
|
||||
uint32_t inbound_doorbell_clear; /*0070 0073*/
|
||||
uint32_t i2o_message_unit_control; /*0074 0077*/
|
||||
uint32_t i2o_message_unit_control; /*0074 0077*/
|
||||
uint32_t last_used_message_source_address_low; /*0078 007B*/
|
||||
uint32_t last_used_message_source_address_high; /*007C 007F*/
|
||||
uint32_t pull_mode_data_byte_count[4]; /*0080 008F*/
|
||||
|
|
@ -531,7 +562,7 @@ struct MessageUnit_C{
|
|||
uint32_t done_queue_not_empty_int_counter_timer; /*0094 0097*/
|
||||
uint32_t utility_A_int_counter_timer; /*0098 009B*/
|
||||
uint32_t outbound_doorbell; /*009C 009F*/
|
||||
uint32_t outbound_doorbell_clear; /*00A0 00A3*/
|
||||
uint32_t outbound_doorbell_clear; /*00A0 00A3*/
|
||||
uint32_t message_source_address_index; /*00A4 00A7*/
|
||||
uint32_t message_done_queue_index; /*00A8 00AB*/
|
||||
uint32_t reserved0; /*00AC 00AF*/
|
||||
|
|
@ -553,10 +584,10 @@ struct MessageUnit_C{
|
|||
uint32_t last_used_message_dest_address_high; /*00EC 00EF*/
|
||||
uint32_t message_done_queue_base_address_low; /*00F0 00F3*/
|
||||
uint32_t message_done_queue_base_address_high; /*00F4 00F7*/
|
||||
uint32_t host_diagnostic; /*00F8 00FB*/
|
||||
uint32_t host_diagnostic; /*00F8 00FB*/
|
||||
uint32_t write_sequence; /*00FC 00FF*/
|
||||
uint32_t reserved1[34]; /*0100 0187*/
|
||||
uint32_t reserved2[1950]; /*0188 1FFF*/
|
||||
uint32_t reserved2[1950]; /*0188 1FFF*/
|
||||
uint32_t message_wbuffer[32]; /*2000 207F*/
|
||||
uint32_t reserved3[32]; /*2080 20FF*/
|
||||
uint32_t message_rbuffer[32]; /*2100 217F*/
|
||||
|
|
@ -614,115 +645,208 @@ struct MessageUnit_D {
|
|||
u32 __iomem *msgcode_rwbuffer; /* 0x2200 */
|
||||
};
|
||||
/*
|
||||
*********************************************************************
|
||||
** Messaging Unit (MU) of Type E processor(LSI)
|
||||
*********************************************************************
|
||||
*/
|
||||
struct MessageUnit_E{
|
||||
uint32_t iobound_doorbell; /*0000 0003*/
|
||||
uint32_t write_sequence_3xxx; /*0004 0007*/
|
||||
uint32_t host_diagnostic_3xxx; /*0008 000B*/
|
||||
uint32_t posted_outbound_doorbell; /*000C 000F*/
|
||||
uint32_t master_error_attribute; /*0010 0013*/
|
||||
uint32_t master_error_address_low; /*0014 0017*/
|
||||
uint32_t master_error_address_high; /*0018 001B*/
|
||||
uint32_t hcb_size; /*001C 001F*/
|
||||
uint32_t inbound_doorbell; /*0020 0023*/
|
||||
uint32_t diagnostic_rw_data; /*0024 0027*/
|
||||
uint32_t diagnostic_rw_address_low; /*0028 002B*/
|
||||
uint32_t diagnostic_rw_address_high; /*002C 002F*/
|
||||
uint32_t host_int_status; /*0030 0033*/
|
||||
uint32_t host_int_mask; /*0034 0037*/
|
||||
uint32_t dcr_data; /*0038 003B*/
|
||||
uint32_t dcr_address; /*003C 003F*/
|
||||
uint32_t inbound_queueport; /*0040 0043*/
|
||||
uint32_t outbound_queueport; /*0044 0047*/
|
||||
uint32_t hcb_pci_address_low; /*0048 004B*/
|
||||
uint32_t hcb_pci_address_high; /*004C 004F*/
|
||||
uint32_t iop_int_status; /*0050 0053*/
|
||||
uint32_t iop_int_mask; /*0054 0057*/
|
||||
uint32_t iop_inbound_queue_port; /*0058 005B*/
|
||||
uint32_t iop_outbound_queue_port; /*005C 005F*/
|
||||
uint32_t inbound_free_list_index; /*0060 0063*/
|
||||
uint32_t inbound_post_list_index; /*0064 0067*/
|
||||
uint32_t reply_post_producer_index; /*0068 006B*/
|
||||
uint32_t reply_post_consumer_index; /*006C 006F*/
|
||||
uint32_t inbound_doorbell_clear; /*0070 0073*/
|
||||
uint32_t i2o_message_unit_control; /*0074 0077*/
|
||||
uint32_t last_used_message_source_address_low; /*0078 007B*/
|
||||
uint32_t last_used_message_source_address_high; /*007C 007F*/
|
||||
uint32_t pull_mode_data_byte_count[4]; /*0080 008F*/
|
||||
uint32_t message_dest_address_index; /*0090 0093*/
|
||||
uint32_t done_queue_not_empty_int_counter_timer; /*0094 0097*/
|
||||
uint32_t utility_A_int_counter_timer; /*0098 009B*/
|
||||
uint32_t outbound_doorbell; /*009C 009F*/
|
||||
uint32_t outbound_doorbell_clear; /*00A0 00A3*/
|
||||
uint32_t message_source_address_index; /*00A4 00A7*/
|
||||
uint32_t message_done_queue_index; /*00A8 00AB*/
|
||||
uint32_t reserved0; /*00AC 00AF*/
|
||||
uint32_t inbound_msgaddr0; /*00B0 00B3*/
|
||||
uint32_t inbound_msgaddr1; /*00B4 00B7*/
|
||||
uint32_t outbound_msgaddr0; /*00B8 00BB*/
|
||||
uint32_t outbound_msgaddr1; /*00BC 00BF*/
|
||||
uint32_t inbound_queueport_low; /*00C0 00C3*/
|
||||
uint32_t inbound_queueport_high; /*00C4 00C7*/
|
||||
uint32_t outbound_queueport_low; /*00C8 00CB*/
|
||||
uint32_t outbound_queueport_high; /*00CC 00CF*/
|
||||
uint32_t iop_inbound_queue_port_low; /*00D0 00D3*/
|
||||
uint32_t iop_inbound_queue_port_high; /*00D4 00D7*/
|
||||
uint32_t iop_outbound_queue_port_low; /*00D8 00DB*/
|
||||
uint32_t iop_outbound_queue_port_high; /*00DC 00DF*/
|
||||
uint32_t message_dest_queue_port_low; /*00E0 00E3*/
|
||||
uint32_t message_dest_queue_port_high; /*00E4 00E7*/
|
||||
uint32_t last_used_message_dest_address_low; /*00E8 00EB*/
|
||||
uint32_t last_used_message_dest_address_high; /*00EC 00EF*/
|
||||
uint32_t message_done_queue_base_address_low; /*00F0 00F3*/
|
||||
uint32_t message_done_queue_base_address_high; /*00F4 00F7*/
|
||||
uint32_t host_diagnostic; /*00F8 00FB*/
|
||||
uint32_t write_sequence; /*00FC 00FF*/
|
||||
uint32_t reserved1[34]; /*0100 0187*/
|
||||
uint32_t reserved2[1950]; /*0188 1FFF*/
|
||||
uint32_t message_wbuffer[32]; /*2000 207F*/
|
||||
uint32_t reserved3[32]; /*2080 20FF*/
|
||||
uint32_t message_rbuffer[32]; /*2100 217F*/
|
||||
uint32_t reserved4[32]; /*2180 21FF*/
|
||||
uint32_t msgcode_rwbuffer[256]; /*2200 23FF*/
|
||||
};
|
||||
|
||||
typedef struct deliver_completeQ {
|
||||
uint16_t cmdFlag;
|
||||
uint16_t cmdSMID;
|
||||
uint16_t cmdLMID; // reserved (0)
|
||||
uint16_t cmdFlag2; // reserved (0)
|
||||
} DeliverQ, CompletionQ, *pDeliver_Q, *pCompletion_Q;
|
||||
/*
|
||||
*******************************************************************************
|
||||
** Adapter Control Block
|
||||
*******************************************************************************
|
||||
*/
|
||||
struct AdapterControlBlock
|
||||
{
|
||||
uint32_t adapter_type; /* adapter A,B..... */
|
||||
#define ACB_ADAPTER_TYPE_A 0x00000001 /* hba I IOP */
|
||||
#define ACB_ADAPTER_TYPE_B 0x00000002 /* hbb M IOP */
|
||||
#define ACB_ADAPTER_TYPE_C 0x00000004 /* hbc P IOP */
|
||||
#define ACB_ADAPTER_TYPE_D 0x00000008 /* hbd A IOP */
|
||||
u32 roundup_ccbsize;
|
||||
struct pci_dev * pdev;
|
||||
struct Scsi_Host * host;
|
||||
unsigned long vir2phy_offset;
|
||||
uint32_t adapter_type; /* adapter A,B..... */
|
||||
#define ACB_ADAPTER_TYPE_A 0x00000000 /* hba I IOP */
|
||||
#define ACB_ADAPTER_TYPE_B 0x00000001 /* hbb M IOP */
|
||||
#define ACB_ADAPTER_TYPE_C 0x00000002 /* hbc L IOP */
|
||||
#define ACB_ADAPTER_TYPE_D 0x00000003 /* hbd M IOP */
|
||||
#define ACB_ADAPTER_TYPE_E 0x00000004 /* hba L IOP */
|
||||
u32 roundup_ccbsize;
|
||||
struct pci_dev * pdev;
|
||||
struct Scsi_Host * host;
|
||||
unsigned long vir2phy_offset;
|
||||
/* Offset is used in making arc cdb physical to virtual calculations */
|
||||
uint32_t outbound_int_enable;
|
||||
uint32_t cdb_phyaddr_hi32;
|
||||
uint32_t reg_mu_acc_handle0;
|
||||
spinlock_t eh_lock;
|
||||
spinlock_t ccblist_lock;
|
||||
spinlock_t postq_lock;
|
||||
spinlock_t doneq_lock;
|
||||
spinlock_t rqbuffer_lock;
|
||||
spinlock_t wqbuffer_lock;
|
||||
uint32_t outbound_int_enable;
|
||||
uint32_t cdb_phyaddr_hi32;
|
||||
uint32_t reg_mu_acc_handle0;
|
||||
spinlock_t eh_lock;
|
||||
spinlock_t ccblist_lock;
|
||||
spinlock_t postq_lock;
|
||||
spinlock_t doneq_lock;
|
||||
spinlock_t rqbuffer_lock;
|
||||
spinlock_t wqbuffer_lock;
|
||||
union {
|
||||
struct MessageUnit_A __iomem *pmuA;
|
||||
struct MessageUnit_B *pmuB;
|
||||
struct MessageUnit_C __iomem *pmuC;
|
||||
struct MessageUnit_D *pmuD;
|
||||
struct MessageUnit_E __iomem *pmuE;
|
||||
};
|
||||
/* message unit ATU inbound base address0 */
|
||||
void __iomem *mem_base0;
|
||||
void __iomem *mem_base1;
|
||||
uint32_t acb_flags;
|
||||
void __iomem *mem_base0;
|
||||
void __iomem *mem_base1;
|
||||
uint32_t acb_flags;
|
||||
u16 dev_id;
|
||||
uint8_t adapter_index;
|
||||
#define ACB_F_SCSISTOPADAPTER 0x0001
|
||||
#define ACB_F_MSG_STOP_BGRB 0x0002
|
||||
/* stop RAID background rebuild */
|
||||
#define ACB_F_MSG_START_BGRB 0x0004
|
||||
/* stop RAID background rebuild */
|
||||
#define ACB_F_IOPDATA_OVERFLOW 0x0008
|
||||
/* iop message data rqbuffer overflow */
|
||||
#define ACB_F_MESSAGE_WQBUFFER_CLEARED 0x0010
|
||||
/* message clear wqbuffer */
|
||||
#define ACB_F_MESSAGE_RQBUFFER_CLEARED 0x0020
|
||||
/* message clear rqbuffer */
|
||||
#define ACB_F_MESSAGE_WQBUFFER_READED 0x0040
|
||||
#define ACB_F_BUS_RESET 0x0080
|
||||
#define ACB_F_BUS_HANG_ON 0x0800/* need hardware reset bus */
|
||||
uint8_t adapter_index;
|
||||
#define ACB_F_SCSISTOPADAPTER 0x0001
|
||||
#define ACB_F_MSG_STOP_BGRB 0x0002
|
||||
/* stop RAID background rebuild */
|
||||
#define ACB_F_MSG_START_BGRB 0x0004
|
||||
/* stop RAID background rebuild */
|
||||
#define ACB_F_IOPDATA_OVERFLOW 0x0008
|
||||
/* iop message data rqbuffer overflow */
|
||||
#define ACB_F_MESSAGE_WQBUFFER_CLEARED 0x0010
|
||||
/* message clear wqbuffer */
|
||||
#define ACB_F_MESSAGE_RQBUFFER_CLEARED 0x0020
|
||||
/* message clear rqbuffer */
|
||||
#define ACB_F_MESSAGE_WQBUFFER_READED 0x0040
|
||||
#define ACB_F_BUS_RESET 0x0080
|
||||
#define ACB_F_BUS_HANG_ON 0x0800/* need hardware reset bus */
|
||||
|
||||
#define ACB_F_IOP_INITED 0x0100
|
||||
/* iop init */
|
||||
#define ACB_F_ABORT 0x0200
|
||||
#define ACB_F_FIRMWARE_TRAP 0x0400
|
||||
struct CommandControlBlock * pccb_pool[ARCMSR_MAX_FREECCB_NUM];
|
||||
#define ACB_F_IOP_INITED 0x0100
|
||||
/* iop init */
|
||||
#define ACB_F_ABORT 0x0200
|
||||
#define ACB_F_FIRMWARE_TRAP 0x0400
|
||||
#define ACB_F_MSG_GET_CONFIG 0x1000
|
||||
struct CommandControlBlock * pccb_pool[ARCMSR_MAX_FREECCB_NUM];
|
||||
/* used for memory free */
|
||||
struct list_head ccb_free_list;
|
||||
struct list_head ccb_free_list;
|
||||
/* head of free ccb list */
|
||||
|
||||
atomic_t ccboutstandingcount;
|
||||
atomic_t ccboutstandingcount;
|
||||
/*The present outstanding command number that in the IOP that
|
||||
waiting for being handled by FW*/
|
||||
|
||||
void * dma_coherent;
|
||||
void * dma_coherent;
|
||||
/* dma_coherent used for memory free */
|
||||
dma_addr_t dma_coherent_handle;
|
||||
dma_addr_t dma_coherent_handle;
|
||||
/* dma_coherent_handle used for memory free */
|
||||
dma_addr_t dma_coherent_handle2;
|
||||
void *dma_coherent2;
|
||||
unsigned int uncache_size;
|
||||
uint8_t rqbuffer[ARCMSR_MAX_QBUFFER];
|
||||
dma_addr_t dma_coherent_handle2;
|
||||
void *dma_coherent2;
|
||||
unsigned int uncache_size;
|
||||
uint8_t rqbuffer[ARCMSR_MAX_QBUFFER];
|
||||
/* data collection buffer for read from 80331 */
|
||||
int32_t rqbuf_getIndex;
|
||||
int32_t rqbuf_getIndex;
|
||||
/* first of read buffer */
|
||||
int32_t rqbuf_putIndex;
|
||||
int32_t rqbuf_putIndex;
|
||||
/* last of read buffer */
|
||||
uint8_t wqbuffer[ARCMSR_MAX_QBUFFER];
|
||||
uint8_t wqbuffer[ARCMSR_MAX_QBUFFER];
|
||||
/* data collection buffer for write to 80331 */
|
||||
int32_t wqbuf_getIndex;
|
||||
int32_t wqbuf_getIndex;
|
||||
/* first of write buffer */
|
||||
int32_t wqbuf_putIndex;
|
||||
int32_t wqbuf_putIndex;
|
||||
/* last of write buffer */
|
||||
uint8_t devstate[ARCMSR_MAX_TARGETID][ARCMSR_MAX_TARGETLUN];
|
||||
uint8_t devstate[ARCMSR_MAX_TARGETID][ARCMSR_MAX_TARGETLUN];
|
||||
/* id0 ..... id15, lun0...lun7 */
|
||||
#define ARECA_RAID_GONE 0x55
|
||||
#define ARECA_RAID_GOOD 0xaa
|
||||
uint32_t num_resets;
|
||||
uint32_t num_aborts;
|
||||
uint32_t signature;
|
||||
uint32_t firm_request_len;
|
||||
uint32_t firm_numbers_queue;
|
||||
uint32_t firm_sdram_size;
|
||||
uint32_t firm_hd_channels;
|
||||
uint32_t firm_cfg_version;
|
||||
#define ARECA_RAID_GONE 0x55
|
||||
#define ARECA_RAID_GOOD 0xaa
|
||||
uint32_t num_resets;
|
||||
uint32_t num_aborts;
|
||||
uint32_t signature;
|
||||
uint32_t firm_request_len;
|
||||
uint32_t firm_numbers_queue;
|
||||
uint32_t firm_sdram_size;
|
||||
uint32_t firm_hd_channels;
|
||||
uint32_t firm_cfg_version;
|
||||
char firm_model[12];
|
||||
char firm_version[20];
|
||||
char device_map[20]; /*21,84-99*/
|
||||
struct work_struct arcmsr_do_message_isr_bh;
|
||||
struct timer_list eternal_timer;
|
||||
struct work_struct arcmsr_do_message_isr_bh;
|
||||
struct timer_list eternal_timer;
|
||||
unsigned short fw_flag;
|
||||
#define FW_NORMAL 0x0000
|
||||
#define FW_BOG 0x0001
|
||||
#define FW_DEADLOCK 0x0010
|
||||
atomic_t rq_map_token;
|
||||
atomic_t ante_token_value;
|
||||
uint32_t maxOutstanding;
|
||||
int vector_count;
|
||||
#define FW_NORMAL 0x0000
|
||||
#define FW_BOG 0x0001
|
||||
#define FW_DEADLOCK 0x0010
|
||||
atomic_t rq_map_token;
|
||||
atomic_t ante_token_value;
|
||||
uint32_t maxOutstanding;
|
||||
int vector_count;
|
||||
uint32_t maxFreeCCB;
|
||||
struct timer_list refresh_timer;
|
||||
uint32_t doneq_index;
|
||||
uint32_t ccbsize;
|
||||
uint32_t in_doorbell;
|
||||
uint32_t out_doorbell;
|
||||
uint32_t completionQ_entry;
|
||||
pCompletion_Q pCompletionQ;
|
||||
};/* HW_DEVICE_EXTENSION */
|
||||
/*
|
||||
*******************************************************************************
|
||||
|
|
@ -732,29 +856,30 @@ struct AdapterControlBlock
|
|||
*/
|
||||
struct CommandControlBlock{
|
||||
/*x32:sizeof struct_CCB=(32+60)byte, x64:sizeof struct_CCB=(64+60)byte*/
|
||||
struct list_head list; /*x32: 8byte, x64: 16byte*/
|
||||
struct scsi_cmnd *pcmd; /*8 bytes pointer of linux scsi command */
|
||||
struct AdapterControlBlock *acb; /*x32: 4byte, x64: 8byte*/
|
||||
uint32_t cdb_phyaddr; /*x32: 4byte, x64: 4byte*/
|
||||
uint32_t arc_cdb_size; /*x32:4byte,x64:4byte*/
|
||||
uint16_t ccb_flags; /*x32: 2byte, x64: 2byte*/
|
||||
#define CCB_FLAG_READ 0x0000
|
||||
#define CCB_FLAG_WRITE 0x0001
|
||||
#define CCB_FLAG_ERROR 0x0002
|
||||
#define CCB_FLAG_FLUSHCACHE 0x0004
|
||||
#define CCB_FLAG_MASTER_ABORTED 0x0008
|
||||
uint16_t startdone; /*x32:2byte,x32:2byte*/
|
||||
#define ARCMSR_CCB_DONE 0x0000
|
||||
#define ARCMSR_CCB_START 0x55AA
|
||||
#define ARCMSR_CCB_ABORTED 0xAA55
|
||||
#define ARCMSR_CCB_ILLEGAL 0xFFFF
|
||||
#if BITS_PER_LONG == 64
|
||||
struct list_head list; /*x32: 8byte, x64: 16byte*/
|
||||
struct scsi_cmnd *pcmd; /*8 bytes pointer of linux scsi command */
|
||||
struct AdapterControlBlock *acb; /*x32: 4byte, x64: 8byte*/
|
||||
uint32_t cdb_phyaddr; /*x32: 4byte, x64: 4byte*/
|
||||
uint32_t arc_cdb_size; /*x32:4byte,x64:4byte*/
|
||||
uint16_t ccb_flags; /*x32: 2byte, x64: 2byte*/
|
||||
#define CCB_FLAG_READ 0x0000
|
||||
#define CCB_FLAG_WRITE 0x0001
|
||||
#define CCB_FLAG_ERROR 0x0002
|
||||
#define CCB_FLAG_FLUSHCACHE 0x0004
|
||||
#define CCB_FLAG_MASTER_ABORTED 0x0008
|
||||
uint16_t startdone; /*x32:2byte,x32:2byte*/
|
||||
#define ARCMSR_CCB_DONE 0x0000
|
||||
#define ARCMSR_CCB_START 0x55AA
|
||||
#define ARCMSR_CCB_ABORTED 0xAA55
|
||||
#define ARCMSR_CCB_ILLEGAL 0xFFFF
|
||||
uint32_t smid;
|
||||
#if BITS_PER_LONG == 64
|
||||
/* ======================512+64 bytes======================== */
|
||||
uint32_t reserved[5]; /*24 byte*/
|
||||
#else
|
||||
uint32_t reserved[4]; /*16 byte*/
|
||||
#else
|
||||
/* ======================512+32 bytes======================== */
|
||||
uint32_t reserved; /*8 byte*/
|
||||
#endif
|
||||
// uint32_t reserved; /*4 byte*/
|
||||
#endif
|
||||
/* ======================================================= */
|
||||
struct ARCMSR_CDB arcmsr_cdb;
|
||||
};
|
||||
|
|
@ -788,13 +913,13 @@ struct SENSE_DATA
|
|||
** Outbound Interrupt Status Register - OISR
|
||||
*******************************************************************************
|
||||
*/
|
||||
#define ARCMSR_MU_OUTBOUND_INTERRUPT_STATUS_REG 0x30
|
||||
#define ARCMSR_MU_OUTBOUND_PCI_INT 0x10
|
||||
#define ARCMSR_MU_OUTBOUND_POSTQUEUE_INT 0x08
|
||||
#define ARCMSR_MU_OUTBOUND_DOORBELL_INT 0x04
|
||||
#define ARCMSR_MU_OUTBOUND_MESSAGE1_INT 0x02
|
||||
#define ARCMSR_MU_OUTBOUND_MESSAGE0_INT 0x01
|
||||
#define ARCMSR_MU_OUTBOUND_HANDLE_INT \
|
||||
#define ARCMSR_MU_OUTBOUND_INTERRUPT_STATUS_REG 0x30
|
||||
#define ARCMSR_MU_OUTBOUND_PCI_INT 0x10
|
||||
#define ARCMSR_MU_OUTBOUND_POSTQUEUE_INT 0x08
|
||||
#define ARCMSR_MU_OUTBOUND_DOORBELL_INT 0x04
|
||||
#define ARCMSR_MU_OUTBOUND_MESSAGE1_INT 0x02
|
||||
#define ARCMSR_MU_OUTBOUND_MESSAGE0_INT 0x01
|
||||
#define ARCMSR_MU_OUTBOUND_HANDLE_INT \
|
||||
(ARCMSR_MU_OUTBOUND_MESSAGE0_INT \
|
||||
|ARCMSR_MU_OUTBOUND_MESSAGE1_INT \
|
||||
|ARCMSR_MU_OUTBOUND_DOORBELL_INT \
|
||||
|
|
@ -805,13 +930,13 @@ struct SENSE_DATA
|
|||
** Outbound Interrupt Mask Register - OIMR
|
||||
*******************************************************************************
|
||||
*/
|
||||
#define ARCMSR_MU_OUTBOUND_INTERRUPT_MASK_REG 0x34
|
||||
#define ARCMSR_MU_OUTBOUND_PCI_INTMASKENABLE 0x10
|
||||
#define ARCMSR_MU_OUTBOUND_POSTQUEUE_INTMASKENABLE 0x08
|
||||
#define ARCMSR_MU_OUTBOUND_DOORBELL_INTMASKENABLE 0x04
|
||||
#define ARCMSR_MU_OUTBOUND_MESSAGE1_INTMASKENABLE 0x02
|
||||
#define ARCMSR_MU_OUTBOUND_MESSAGE0_INTMASKENABLE 0x01
|
||||
#define ARCMSR_MU_OUTBOUND_ALL_INTMASKENABLE 0x1F
|
||||
#define ARCMSR_MU_OUTBOUND_INTERRUPT_MASK_REG 0x34
|
||||
#define ARCMSR_MU_OUTBOUND_PCI_INTMASKENABLE 0x10
|
||||
#define ARCMSR_MU_OUTBOUND_POSTQUEUE_INTMASKENABLE 0x08
|
||||
#define ARCMSR_MU_OUTBOUND_DOORBELL_INTMASKENABLE 0x04
|
||||
#define ARCMSR_MU_OUTBOUND_MESSAGE1_INTMASKENABLE 0x02
|
||||
#define ARCMSR_MU_OUTBOUND_MESSAGE0_INTMASKENABLE 0x01
|
||||
#define ARCMSR_MU_OUTBOUND_ALL_INTMASKENABLE 0x1F
|
||||
|
||||
extern void arcmsr_write_ioctldata2iop(struct AdapterControlBlock *);
|
||||
extern uint32_t arcmsr_Read_iop_rqbuffer_data(struct AdapterControlBlock *,
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -2011,7 +2011,7 @@ static void fas216_rq_sns_done(FAS216_Info *info, struct scsi_cmnd *SCpnt,
|
|||
* have valid data in the sense buffer that could
|
||||
* confuse the higher levels.
|
||||
*/
|
||||
memset(SCpnt->sense_buffer, 0, sizeof(SCpnt->sense_buffer));
|
||||
memset(SCpnt->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
|
||||
//printk("scsi%d.%c: sense buffer: ", info->host->host_no, '0' + SCpnt->device->id);
|
||||
//{ int i; for (i = 0; i < 32; i++) printk("%02x ", SCpnt->sense_buffer[i]); printk("\n"); }
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -1957,7 +1957,7 @@ bfa_get_pciids(struct bfa_pciid_s **pciids, int *npciids)
|
|||
{BFA_PCI_VENDOR_ID_BROCADE, BFA_PCI_DEVICE_ID_CT_FC},
|
||||
};
|
||||
|
||||
*npciids = sizeof(__pciids) / sizeof(__pciids[0]);
|
||||
*npciids = ARRAY_SIZE(__pciids);
|
||||
*pciids = __pciids;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -35,10 +35,10 @@
|
|||
|
||||
#define BFA_TRC_TS(_trcm) \
|
||||
({ \
|
||||
struct timeval tv; \
|
||||
struct timespec64 ts; \
|
||||
\
|
||||
do_gettimeofday(&tv); \
|
||||
(tv.tv_sec*1000000+tv.tv_usec); \
|
||||
ktime_get_ts64(&ts); \
|
||||
(ts.tv_sec*1000000+ts.tv_nsec / 1000); \
|
||||
})
|
||||
|
||||
#ifndef BFA_TRC_TS
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue