mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2024-12-28 16:53:49 +00:00
SCSI misc on 20210219
This series consists of the usual driver updates (ufs, ibmvfc, qla2xxx, hisi_sas, pm80xx) plus the removal of the gdth driver (which is bound to cause conflicts with a trivial change somewhere). The only big major rework of note is the one from Hannes trying to clean up our result handling code in the drivers to make it consistent. Signed-off-by: James E.J. Bottomley <jejb@linux.ibm.com> -----BEGIN PGP SIGNATURE----- iJwEABMIAEQWIQTnYEDbdso9F2cI+arnQslM7pishQUCYDAdliYcamFtZXMuYm90 dG9tbGV5QGhhbnNlbnBhcnRuZXJzaGlwLmNvbQAKCRDnQslM7pishTblAQCk6wD8 fcb4TItSRp0DpRzs37zhppEbrBgveuAFHhr5swEA0gL2mHcq0vnyNBinCLnERrE7 TPYJqUKJNktnjVG7ZWc= =wW6p -----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 series consists of the usual driver updates (ufs, ibmvfc, qla2xxx, hisi_sas, pm80xx) plus the removal of the gdth driver (which is bound to cause conflicts with a trivial change somewhere). The only big major rework of note is the one from Hannes trying to clean up our result handling code in the drivers to make it consistent" * tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: (194 commits) scsi: MAINTAINERS: Adjust to reflect gdth scsi driver removal scsi: ufs: Give clk scaling min gear a value scsi: lpfc: Fix 'physical' typos scsi: megaraid_mbox: Fix spelling of 'allocated' scsi: qla2xxx: Simplify the calculation of variables scsi: message: fusion: Fix 'physical' typos scsi: target: core: Change ASCQ for residual write scsi: target: core: Signal WRITE residuals scsi: target: core: Set residuals for 4Kn devices scsi: hisi_sas: Add trace FIFO debugfs support scsi: hisi_sas: Flush workqueue in hisi_sas_v3_remove() scsi: hisi_sas: Enable debugfs support by default scsi: hisi_sas: Don't check .nr_hw_queues in hisi_sas_task_prep() scsi: hisi_sas: Remove deferred probe check in hisi_sas_v2_probe() scsi: lpfc: Add auto select on IRQ_POLL scsi: ncr53c8xx: Fix typos scsi: lpfc: Fix ancient double free scsi: qla2xxx: Fix some memory corruption scsi: qla2xxx: Remove redundant NULL check scsi: megaraid: Fix ifnullfree.cocci warnings ...
This commit is contained in:
commit
bdb39c9509
@ -1161,3 +1161,14 @@ Description: This entry shows the configured size of WriteBooster buffer.
|
||||
0400h corresponds to 4GB.
|
||||
|
||||
The file is read only.
|
||||
|
||||
What: /sys/bus/platform/drivers/ufshcd/*/wb_on
|
||||
Date: January 2021
|
||||
Contact: Bean Huo <beanhuo@micron.com>
|
||||
Description: This node is used to set or display whether UFS WriteBooster is
|
||||
enabled. Echo 0 to this file to disable UFS WriteBooster or 1 to
|
||||
enable it. The WriteBooster is enabled after power-on/reset,
|
||||
however, it will be disabled/enable while CLK scaling down/up
|
||||
(if the platform supports UFSHCD_CAP_CLK_SCALING). For a
|
||||
platform that doesn't support UFSHCD_CAP_CLK_SCALING, we can
|
||||
disable/enable WriteBooster through this sysfs node.
|
||||
|
@ -461,10 +461,8 @@ more details, with real examples.
|
||||
|
||||
# drivers/scsi/Makefile
|
||||
CFLAGS_aha152x.o = -DAHA152X_STAT -DAUTOCONF
|
||||
CFLAGS_gdth.o = # -DDEBUG_GDTH=2 -D__SERIAL__ -D__COM2__ \
|
||||
-DGDTH_STATISTICS
|
||||
|
||||
These two lines specify compilation flags for aha152x.o and gdth.o.
|
||||
This line specify compilation flags for aha152x.o.
|
||||
|
||||
$(AFLAGS_$@) is a similar feature for source files in assembly
|
||||
languages.
|
||||
|
@ -99,7 +99,6 @@ USB_SERIAL_PORT_MAGIC 0x7301 usb_serial_port ``drivers/usb/se
|
||||
CG_MAGIC 0x00090255 ufs_cylinder_group ``include/linux/ufs_fs.h``
|
||||
RPORT_MAGIC 0x00525001 r_port ``drivers/char/rocket_int.h``
|
||||
LSEMAGIC 0x05091998 lse ``drivers/fc4/fc.c``
|
||||
GDTIOCTL_MAGIC 0x06030f07 gdth_iowr_str ``drivers/scsi/gdth_ioctl.h``
|
||||
RIEBL_MAGIC 0x09051990 ``drivers/net/atarilance.c``
|
||||
NBD_REQUEST_MAGIC 0x12560953 nbd_request ``include/linux/nbd.h``
|
||||
RED_MAGIC2 0x170fc2a5 (any) ``mm/slab.c``
|
||||
@ -142,7 +141,6 @@ PWC_MAGIC 0x89DC10AB pwc_device ``drivers/usb/me
|
||||
NBD_REPLY_MAGIC 0x96744668 nbd_reply ``include/linux/nbd.h``
|
||||
ENI155_MAGIC 0xa54b872d midway_eprom ``drivers/atm/eni.h``
|
||||
CODA_MAGIC 0xC0DAC0DA coda_file_info ``fs/coda/coda_fs_i.h``
|
||||
DPMEM_MAGIC 0xc0ffee11 gdt_pci_sram ``drivers/scsi/gdth.h``
|
||||
YAM_MAGIC 0xF10A7654 yam_port ``drivers/net/hamradio/yam.c``
|
||||
CCB_MAGIC 0xf2691ad2 ccb ``drivers/scsi/ncr53c8xx.c``
|
||||
QUEUE_MAGIC_FREE 0xf7e1c9a3 queue_entry ``drivers/scsi/arm/queue.c``
|
||||
|
@ -189,13 +189,8 @@ num_phys
|
||||
The event interface::
|
||||
|
||||
/* LLDD calls these to notify the class of an event. */
|
||||
void (*notify_ha_event)(struct sas_ha_struct *, enum ha_event);
|
||||
void (*notify_port_event)(struct sas_phy *, enum port_event);
|
||||
void (*notify_phy_event)(struct sas_phy *, enum phy_event);
|
||||
|
||||
When sas_register_ha() returns, those are set and can be
|
||||
called by the LLDD to notify the SAS layer of such events
|
||||
the SAS layer.
|
||||
void sas_notify_port_event(struct sas_phy *, enum port_event, gfp_t);
|
||||
void sas_notify_phy_event(struct sas_phy *, enum phy_event, gfp_t);
|
||||
|
||||
The port notification::
|
||||
|
||||
|
@ -38,9 +38,6 @@ parameters may be changed at runtime by the command
|
||||
See drivers/scsi/BusLogic.c, comment before function
|
||||
BusLogic_ParseDriverOptions().
|
||||
|
||||
gdth= [HW,SCSI]
|
||||
See header of drivers/scsi/gdth.c.
|
||||
|
||||
gvp11= [HW,SCSI]
|
||||
|
||||
ips= [HW,SCSI] Adaptec / IBM ServeRAID controller
|
||||
|
@ -157,7 +157,6 @@ Code Seq# Include File Comments
|
||||
'I' all linux/isdn.h conflict!
|
||||
'I' 00-0F drivers/isdn/divert/isdn_divert.h conflict!
|
||||
'I' 40-4F linux/mISDNif.h conflict!
|
||||
'J' 00-1F drivers/scsi/gdth_ioctl.h
|
||||
'K' all linux/kd.h
|
||||
'L' 00-1F linux/loop.h conflict!
|
||||
'L' 10-1F drivers/scsi/mpt3sas/mpt3sas_ctl.h conflict!
|
||||
|
@ -7363,13 +7363,6 @@ M: Kieran Bingham <kbingham@kernel.org>
|
||||
S: Supported
|
||||
F: scripts/gdb/
|
||||
|
||||
GDT SCSI DISK ARRAY CONTROLLER DRIVER
|
||||
M: Achim Leubner <achim_leubner@adaptec.com>
|
||||
L: linux-scsi@vger.kernel.org
|
||||
S: Supported
|
||||
W: http://www.icp-vortex.com/
|
||||
F: drivers/scsi/gdt*
|
||||
|
||||
GEMTEK FM RADIO RECEIVER DRIVER
|
||||
M: Hans Verkuil <hverkuil@xs4all.nl>
|
||||
L: linux-media@vger.kernel.org
|
||||
@ -8864,7 +8857,6 @@ F: drivers/mfd/intel_pmc_bxt.c
|
||||
F: include/linux/mfd/intel_pmc_bxt.h
|
||||
|
||||
INTEL C600 SERIES SAS CONTROLLER DRIVER
|
||||
M: Intel SCU Linux support <intel-linux-scu@intel.com>
|
||||
M: Artur Paszkiewicz <artur.paszkiewicz@intel.com>
|
||||
L: linux-scsi@vger.kernel.org
|
||||
S: Supported
|
||||
|
@ -313,7 +313,7 @@
|
||||
* define.
|
||||
* Added BIOS Page 4 structure.
|
||||
* Added MPI_RAID_PHYS_DISK1_PATH_MAX define for RAID
|
||||
* Physcial Disk Page 1.
|
||||
* Physical Disk Page 1.
|
||||
* 01-15-07 01.05.17 Added additional bit defines for ExtFlags field of
|
||||
* Manufacturing Page 4.
|
||||
* Added Solid State Drives Supported bit to IOC Page 6
|
||||
|
@ -513,7 +513,7 @@ mpi_cnfg.h
|
||||
* define.
|
||||
* Added BIOS Page 4 structure.
|
||||
* Added MPI_RAID_PHYS_DISK1_PATH_MAX define for RAID
|
||||
* Physcial Disk Page 1.
|
||||
* Physical Disk Page 1.
|
||||
* 01-15-07 01.05.17 Added additional bit defines for ExtFlags field of
|
||||
* Manufacturing Page 4.
|
||||
* Added Solid State Drives Supported bit to IOC Page 6
|
||||
|
@ -275,7 +275,6 @@ void zfcp_fc_eval_fcp_rsp(struct fcp_resp_with_ext *fcp_rsp,
|
||||
u32 sense_len, resid;
|
||||
u8 rsp_flags;
|
||||
|
||||
set_msg_byte(scsi, COMMAND_COMPLETE);
|
||||
scsi->result |= fcp_rsp->resp.fr_status;
|
||||
|
||||
rsp_flags = fcp_rsp->resp.fr_flags;
|
||||
|
@ -128,14 +128,14 @@ static int twa_fill_sense(TW_Device_Extension *tw_dev, int request_id, int copy_
|
||||
static void twa_free_request_id(TW_Device_Extension *tw_dev,int request_id);
|
||||
static void twa_get_request_id(TW_Device_Extension *tw_dev, int *request_id);
|
||||
static int twa_initconnection(TW_Device_Extension *tw_dev, int message_credits,
|
||||
u32 set_features, unsigned short current_fw_srl,
|
||||
unsigned short current_fw_arch_id,
|
||||
unsigned short current_fw_branch,
|
||||
unsigned short current_fw_build,
|
||||
unsigned short *fw_on_ctlr_srl,
|
||||
unsigned short *fw_on_ctlr_arch_id,
|
||||
unsigned short *fw_on_ctlr_branch,
|
||||
unsigned short *fw_on_ctlr_build,
|
||||
u32 set_features, unsigned short current_fw_srl,
|
||||
unsigned short current_fw_arch_id,
|
||||
unsigned short current_fw_branch,
|
||||
unsigned short current_fw_build,
|
||||
unsigned short *fw_on_ctlr_srl,
|
||||
unsigned short *fw_on_ctlr_arch_id,
|
||||
unsigned short *fw_on_ctlr_branch,
|
||||
unsigned short *fw_on_ctlr_build,
|
||||
u32 *init_connect_result);
|
||||
static void twa_load_sgl(TW_Device_Extension *tw_dev, TW_Command_Full *full_command_packet, int request_id, dma_addr_t dma_handle, int length);
|
||||
static int twa_poll_response(TW_Device_Extension *tw_dev, int request_id, int seconds);
|
||||
@ -171,7 +171,7 @@ static ssize_t twa_show_stats(struct device *dev,
|
||||
"Last sector count: %4d\n"
|
||||
"Max sector count: %4d\n"
|
||||
"SCSI Host Resets: %4d\n"
|
||||
"AEN's: %4d\n",
|
||||
"AEN's: %4d\n",
|
||||
TW_DRIVER_VERSION,
|
||||
tw_dev->posted_request_count,
|
||||
tw_dev->max_posted_request_count,
|
||||
@ -190,7 +190,7 @@ static ssize_t twa_show_stats(struct device *dev,
|
||||
/* Create sysfs 'stats' entry */
|
||||
static struct device_attribute twa_host_stats_attr = {
|
||||
.attr = {
|
||||
.name = "stats",
|
||||
.name = "stats",
|
||||
.mode = S_IRUGO,
|
||||
},
|
||||
.show = twa_show_stats
|
||||
@ -242,7 +242,7 @@ static int twa_aen_complete(TW_Device_Extension *tw_dev, int request_id)
|
||||
/* Keep reading the queue in case there are more aen's */
|
||||
if (twa_aen_read_queue(tw_dev, request_id))
|
||||
goto out2;
|
||||
else {
|
||||
else {
|
||||
retval = 0;
|
||||
goto out;
|
||||
}
|
||||
@ -497,7 +497,7 @@ static void twa_aen_sync_time(TW_Device_Extension *tw_dev, int request_id)
|
||||
param->parameter_id = cpu_to_le16(0x3); /* SchedulerTime */
|
||||
param->parameter_size_bytes = cpu_to_le16(4);
|
||||
|
||||
/* Convert system time in UTC to local time seconds since last
|
||||
/* Convert system time in UTC to local time seconds since last
|
||||
Sunday 12:00AM */
|
||||
local_time = (ktime_get_real_seconds() - (sys_tz.tz_minuteswest * 60));
|
||||
div_u64_rem(local_time - (3 * 86400), 604800, &schedulertime);
|
||||
@ -729,7 +729,7 @@ static long twa_chrdev_ioctl(struct file *file, unsigned int cmd, unsigned long
|
||||
|
||||
/* Now copy in the command packet response */
|
||||
memcpy(&(tw_ioctl->firmware_command), tw_dev->command_packet_virt[request_id], sizeof(TW_Command_Full));
|
||||
|
||||
|
||||
/* Now complete the io */
|
||||
spin_lock_irqsave(tw_dev->host->host_lock, flags);
|
||||
tw_dev->posted_request_count--;
|
||||
@ -766,7 +766,7 @@ static long twa_chrdev_ioctl(struct file *file, unsigned int cmd, unsigned long
|
||||
if (tw_dev->aen_clobber) {
|
||||
tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_AEN_CLOBBER;
|
||||
tw_dev->aen_clobber = 0;
|
||||
} else
|
||||
} else
|
||||
tw_ioctl->driver_command.status = 0;
|
||||
event_index = tw_dev->error_index;
|
||||
} else {
|
||||
@ -1067,8 +1067,8 @@ static void *twa_get_param(TW_Device_Extension *tw_dev, int request_id, int tabl
|
||||
command_packet = &full_command_packet->command.oldcommand;
|
||||
|
||||
command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_GET_PARAM);
|
||||
command_packet->size = TW_COMMAND_SIZE;
|
||||
command_packet->request_id = request_id;
|
||||
command_packet->size = TW_COMMAND_SIZE;
|
||||
command_packet->request_id = request_id;
|
||||
command_packet->byte6_offset.block_count = cpu_to_le16(1);
|
||||
|
||||
/* Now setup the param */
|
||||
@ -1106,14 +1106,14 @@ static void twa_get_request_id(TW_Device_Extension *tw_dev, int *request_id)
|
||||
|
||||
/* This function will send an initconnection command to controller */
|
||||
static int twa_initconnection(TW_Device_Extension *tw_dev, int message_credits,
|
||||
u32 set_features, unsigned short current_fw_srl,
|
||||
unsigned short current_fw_arch_id,
|
||||
unsigned short current_fw_branch,
|
||||
unsigned short current_fw_build,
|
||||
unsigned short *fw_on_ctlr_srl,
|
||||
unsigned short *fw_on_ctlr_arch_id,
|
||||
unsigned short *fw_on_ctlr_branch,
|
||||
unsigned short *fw_on_ctlr_build,
|
||||
u32 set_features, unsigned short current_fw_srl,
|
||||
unsigned short current_fw_arch_id,
|
||||
unsigned short current_fw_branch,
|
||||
unsigned short current_fw_build,
|
||||
unsigned short *fw_on_ctlr_srl,
|
||||
unsigned short *fw_on_ctlr_arch_id,
|
||||
unsigned short *fw_on_ctlr_branch,
|
||||
unsigned short *fw_on_ctlr_build,
|
||||
u32 *init_connect_result)
|
||||
{
|
||||
TW_Command_Full *full_command_packet;
|
||||
@ -1124,7 +1124,7 @@ static int twa_initconnection(TW_Device_Extension *tw_dev, int message_credits,
|
||||
full_command_packet = tw_dev->command_packet_virt[request_id];
|
||||
memset(full_command_packet, 0, sizeof(TW_Command_Full));
|
||||
full_command_packet->header.header_desc.size_header = 128;
|
||||
|
||||
|
||||
tw_initconnect = (TW_Initconnect *)&full_command_packet->command.oldcommand;
|
||||
tw_initconnect->opcode__reserved = TW_OPRES_IN(0, TW_OP_INIT_CONNECTION);
|
||||
tw_initconnect->request_id = request_id;
|
||||
@ -1142,7 +1142,7 @@ static int twa_initconnection(TW_Device_Extension *tw_dev, int message_credits,
|
||||
tw_initconnect->fw_arch_id = cpu_to_le16(current_fw_arch_id);
|
||||
tw_initconnect->fw_branch = cpu_to_le16(current_fw_branch);
|
||||
tw_initconnect->fw_build = cpu_to_le16(current_fw_build);
|
||||
} else
|
||||
} else
|
||||
tw_initconnect->size = TW_INIT_COMMAND_PACKET_SIZE;
|
||||
|
||||
/* Send command packet to the board */
|
||||
@ -1455,7 +1455,7 @@ static int twa_poll_response(TW_Device_Extension *tw_dev, int request_id, int se
|
||||
/* This function will poll the status register for a flag */
|
||||
static int twa_poll_status(TW_Device_Extension *tw_dev, u32 flag, int seconds)
|
||||
{
|
||||
u32 status_reg_value;
|
||||
u32 status_reg_value;
|
||||
unsigned long before;
|
||||
int retval = 1;
|
||||
|
||||
@ -1770,7 +1770,7 @@ static int twa_scsi_queue_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_
|
||||
|
||||
/* Save done function into scsi_cmnd struct */
|
||||
SCpnt->scsi_done = done;
|
||||
|
||||
|
||||
/* Get a free request id */
|
||||
twa_get_request_id(tw_dev, &request_id);
|
||||
|
||||
|
@ -49,8 +49,8 @@
|
||||
|
||||
/* AEN string type */
|
||||
typedef struct TAG_twa_message_type {
|
||||
unsigned int code;
|
||||
char* text;
|
||||
unsigned int code;
|
||||
char* text;
|
||||
} twa_message_type;
|
||||
|
||||
/* AEN strings */
|
||||
@ -263,9 +263,9 @@ static twa_message_type twa_error_table[] = {
|
||||
#define TW_CONTROL_ENABLE_INTERRUPTS 0x00000080
|
||||
#define TW_CONTROL_DISABLE_INTERRUPTS 0x00000040
|
||||
#define TW_CONTROL_ISSUE_HOST_INTERRUPT 0x00000020
|
||||
#define TW_CONTROL_CLEAR_PARITY_ERROR 0x00800000
|
||||
#define TW_CONTROL_CLEAR_QUEUE_ERROR 0x00400000
|
||||
#define TW_CONTROL_CLEAR_PCI_ABORT 0x00100000
|
||||
#define TW_CONTROL_CLEAR_PARITY_ERROR 0x00800000
|
||||
#define TW_CONTROL_CLEAR_QUEUE_ERROR 0x00400000
|
||||
#define TW_CONTROL_CLEAR_PCI_ABORT 0x00100000
|
||||
|
||||
/* Status register bit definitions */
|
||||
#define TW_STATUS_MAJOR_VERSION_MASK 0xF0000000
|
||||
@ -284,25 +284,25 @@ static twa_message_type twa_error_table[] = {
|
||||
#define TW_STATUS_COMMAND_QUEUE_EMPTY 0x00001000
|
||||
#define TW_STATUS_EXPECTED_BITS 0x00002000
|
||||
#define TW_STATUS_UNEXPECTED_BITS 0x00F00000
|
||||
#define TW_STATUS_VALID_INTERRUPT 0x00DF0000
|
||||
#define TW_STATUS_VALID_INTERRUPT 0x00DF0000
|
||||
|
||||
/* PCI related defines */
|
||||
#define TW_PCI_CLEAR_PARITY_ERRORS 0xc100
|
||||
#define TW_PCI_CLEAR_PCI_ABORT 0x2000
|
||||
|
||||
/* Command packet opcodes used by the driver */
|
||||
#define TW_OP_INIT_CONNECTION 0x1
|
||||
#define TW_OP_GET_PARAM 0x12
|
||||
#define TW_OP_SET_PARAM 0x13
|
||||
#define TW_OP_EXECUTE_SCSI 0x10
|
||||
#define TW_OP_INIT_CONNECTION 0x1
|
||||
#define TW_OP_GET_PARAM 0x12
|
||||
#define TW_OP_SET_PARAM 0x13
|
||||
#define TW_OP_EXECUTE_SCSI 0x10
|
||||
#define TW_OP_DOWNLOAD_FIRMWARE 0x16
|
||||
#define TW_OP_RESET 0x1C
|
||||
#define TW_OP_RESET 0x1C
|
||||
|
||||
/* Asynchronous Event Notification (AEN) codes used by the driver */
|
||||
#define TW_AEN_QUEUE_EMPTY 0x0000
|
||||
#define TW_AEN_SOFT_RESET 0x0001
|
||||
#define TW_AEN_QUEUE_EMPTY 0x0000
|
||||
#define TW_AEN_SOFT_RESET 0x0001
|
||||
#define TW_AEN_SYNC_TIME_WITH_HOST 0x031
|
||||
#define TW_AEN_SEVERITY_ERROR 0x1
|
||||
#define TW_AEN_SEVERITY_ERROR 0x1
|
||||
#define TW_AEN_SEVERITY_DEBUG 0x4
|
||||
#define TW_AEN_NOT_RETRIEVED 0x1
|
||||
#define TW_AEN_RETRIEVED 0x2
|
||||
@ -323,9 +323,9 @@ static twa_message_type twa_error_table[] = {
|
||||
|
||||
/* Misc defines */
|
||||
#define TW_9550SX_DRAIN_COMPLETED 0xFFFF
|
||||
#define TW_SECTOR_SIZE 512
|
||||
#define TW_ALIGNMENT_9000 4 /* 4 bytes */
|
||||
#define TW_ALIGNMENT_9000_SGL 0x3
|
||||
#define TW_SECTOR_SIZE 512
|
||||
#define TW_ALIGNMENT_9000 4 /* 4 bytes */
|
||||
#define TW_ALIGNMENT_9000_SGL 0x3
|
||||
#define TW_MAX_UNITS 16
|
||||
#define TW_MAX_UNITS_9650SE 32
|
||||
#define TW_INIT_MESSAGE_CREDITS 0x100
|
||||
@ -338,7 +338,7 @@ static twa_message_type twa_error_table[] = {
|
||||
#define TW_BASE_FW_SRL 24
|
||||
#define TW_BASE_FW_BRANCH 0
|
||||
#define TW_BASE_FW_BUILD 1
|
||||
#define TW_FW_SRL_LUNS_SUPPORTED 28
|
||||
#define TW_FW_SRL_LUNS_SUPPORTED 28
|
||||
#define TW_Q_LENGTH 256
|
||||
#define TW_Q_START 0
|
||||
#define TW_MAX_SLOT 32
|
||||
@ -346,19 +346,19 @@ static twa_message_type twa_error_table[] = {
|
||||
#define TW_MAX_CMDS_PER_LUN 254
|
||||
#define TW_MAX_RESPONSE_DRAIN 256
|
||||
#define TW_MAX_AEN_DRAIN 255
|
||||
#define TW_IN_RESET 2
|
||||
#define TW_IN_RESET 2
|
||||
#define TW_USING_MSI 3
|
||||
#define TW_IN_ATTENTION_LOOP 4
|
||||
#define TW_MAX_SECTORS 256
|
||||
#define TW_AEN_WAIT_TIME 1000
|
||||
#define TW_IOCTL_WAIT_TIME (1 * HZ) /* 1 second */
|
||||
#define TW_MAX_CDB_LEN 16
|
||||
#define TW_ISR_DONT_COMPLETE 2
|
||||
#define TW_ISR_DONT_RESULT 3
|
||||
#define TW_IOCTL_CHRDEV_TIMEOUT 60 /* 60 seconds */
|
||||
#define TW_IOCTL_CHRDEV_FREE -1
|
||||
#define TW_COMMAND_OFFSET 128 /* 128 bytes */
|
||||
#define TW_VERSION_TABLE 0x0402
|
||||
#define TW_MAX_SECTORS 256
|
||||
#define TW_AEN_WAIT_TIME 1000
|
||||
#define TW_IOCTL_WAIT_TIME (1 * HZ) /* 1 second */
|
||||
#define TW_MAX_CDB_LEN 16
|
||||
#define TW_ISR_DONT_COMPLETE 2
|
||||
#define TW_ISR_DONT_RESULT 3
|
||||
#define TW_IOCTL_CHRDEV_TIMEOUT 60 /* 60 seconds */
|
||||
#define TW_IOCTL_CHRDEV_FREE -1
|
||||
#define TW_COMMAND_OFFSET 128 /* 128 bytes */
|
||||
#define TW_VERSION_TABLE 0x0402
|
||||
#define TW_TIMEKEEP_TABLE 0x040A
|
||||
#define TW_INFORMATION_TABLE 0x0403
|
||||
#define TW_PARAM_FWVER 3
|
||||
@ -367,22 +367,22 @@ static twa_message_type twa_error_table[] = {
|
||||
#define TW_PARAM_BIOSVER_LENGTH 16
|
||||
#define TW_PARAM_PORTCOUNT 3
|
||||
#define TW_PARAM_PORTCOUNT_LENGTH 1
|
||||
#define TW_MIN_SGL_LENGTH 0x200 /* 512 bytes */
|
||||
#define TW_MAX_SENSE_LENGTH 256
|
||||
#define TW_EVENT_SOURCE_AEN 0x1000
|
||||
#define TW_EVENT_SOURCE_COMMAND 0x1001
|
||||
#define TW_EVENT_SOURCE_PCHIP 0x1002
|
||||
#define TW_EVENT_SOURCE_DRIVER 0x1003
|
||||
#define TW_MIN_SGL_LENGTH 0x200 /* 512 bytes */
|
||||
#define TW_MAX_SENSE_LENGTH 256
|
||||
#define TW_EVENT_SOURCE_AEN 0x1000
|
||||
#define TW_EVENT_SOURCE_COMMAND 0x1001
|
||||
#define TW_EVENT_SOURCE_PCHIP 0x1002
|
||||
#define TW_EVENT_SOURCE_DRIVER 0x1003
|
||||
#define TW_IOCTL_GET_COMPATIBILITY_INFO 0x101
|
||||
#define TW_IOCTL_GET_LAST_EVENT 0x102
|
||||
#define TW_IOCTL_GET_FIRST_EVENT 0x103
|
||||
#define TW_IOCTL_GET_NEXT_EVENT 0x104
|
||||
#define TW_IOCTL_GET_PREVIOUS_EVENT 0x105
|
||||
#define TW_IOCTL_GET_LOCK 0x106
|
||||
#define TW_IOCTL_RELEASE_LOCK 0x107
|
||||
#define TW_IOCTL_FIRMWARE_PASS_THROUGH 0x108
|
||||
#define TW_IOCTL_GET_LAST_EVENT 0x102
|
||||
#define TW_IOCTL_GET_FIRST_EVENT 0x103
|
||||
#define TW_IOCTL_GET_NEXT_EVENT 0x104
|
||||
#define TW_IOCTL_GET_PREVIOUS_EVENT 0x105
|
||||
#define TW_IOCTL_GET_LOCK 0x106
|
||||
#define TW_IOCTL_RELEASE_LOCK 0x107
|
||||
#define TW_IOCTL_FIRMWARE_PASS_THROUGH 0x108
|
||||
#define TW_IOCTL_ERROR_STATUS_NOT_LOCKED 0x1001 // Not locked
|
||||
#define TW_IOCTL_ERROR_STATUS_LOCKED 0x1002 // Already locked
|
||||
#define TW_IOCTL_ERROR_STATUS_LOCKED 0x1002 // Already locked
|
||||
#define TW_IOCTL_ERROR_STATUS_NO_MORE_EVENTS 0x1003 // No more events
|
||||
#define TW_IOCTL_ERROR_STATUS_AEN_CLOBBER 0x1004 // AEN clobber occurred
|
||||
#define TW_IOCTL_ERROR_OS_EFAULT -EFAULT // Bad address
|
||||
@ -397,12 +397,12 @@ static twa_message_type twa_error_table[] = {
|
||||
#define TW_SENSE_DATA_LENGTH 18
|
||||
#define TW_STATUS_CHECK_CONDITION 2
|
||||
#define TW_ERROR_LOGICAL_UNIT_NOT_SUPPORTED 0x10a
|
||||
#define TW_ERROR_UNIT_OFFLINE 0x128
|
||||
#define TW_ERROR_UNIT_OFFLINE 0x128
|
||||
#define TW_MESSAGE_SOURCE_CONTROLLER_ERROR 3
|
||||
#define TW_MESSAGE_SOURCE_CONTROLLER_EVENT 4
|
||||
#define TW_MESSAGE_SOURCE_LINUX_DRIVER 6
|
||||
#define TW_MESSAGE_SOURCE_LINUX_DRIVER 6
|
||||
#define TW_DRIVER TW_MESSAGE_SOURCE_LINUX_DRIVER
|
||||
#define TW_MESSAGE_SOURCE_LINUX_OS 9
|
||||
#define TW_MESSAGE_SOURCE_LINUX_OS 9
|
||||
#define TW_OS TW_MESSAGE_SOURCE_LINUX_OS
|
||||
#ifndef PCI_DEVICE_ID_3WARE_9000
|
||||
#define PCI_DEVICE_ID_3WARE_9000 0x1002
|
||||
@ -434,24 +434,38 @@ static twa_message_type twa_error_table[] = {
|
||||
#define TW_RESID_OUT(x) ((x >> 4) & 0xff)
|
||||
|
||||
/* request_id: 12, lun: 4 */
|
||||
#define TW_REQ_LUN_IN(lun, request_id) (((lun << 12) & 0xf000) | (request_id & 0xfff))
|
||||
#define TW_REQ_LUN_IN(lun, request_id) \
|
||||
(((lun << 12) & 0xf000) | (request_id & 0xfff))
|
||||
#define TW_LUN_OUT(lun) ((lun >> 12) & 0xf)
|
||||
|
||||
/* Macros */
|
||||
#define TW_CONTROL_REG_ADDR(x) (x->base_addr)
|
||||
#define TW_STATUS_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + 0x4)
|
||||
#define TW_COMMAND_QUEUE_REG_ADDR(x) (sizeof(dma_addr_t) > 4 ? ((unsigned char __iomem *)x->base_addr + 0x20) : ((unsigned char __iomem *)x->base_addr + 0x8))
|
||||
#define TW_COMMAND_QUEUE_REG_ADDR_LARGE(x) ((unsigned char __iomem *)x->base_addr + 0x20)
|
||||
#define TW_RESPONSE_QUEUE_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + 0xC)
|
||||
#define TW_RESPONSE_QUEUE_REG_ADDR_LARGE(x) ((unsigned char __iomem *)x->base_addr + 0x30)
|
||||
#define TW_CLEAR_ALL_INTERRUPTS(x) (writel(TW_STATUS_VALID_INTERRUPT, TW_CONTROL_REG_ADDR(x)))
|
||||
#define TW_CLEAR_ATTENTION_INTERRUPT(x) (writel(TW_CONTROL_CLEAR_ATTENTION_INTERRUPT, TW_CONTROL_REG_ADDR(x)))
|
||||
#define TW_CLEAR_HOST_INTERRUPT(x) (writel(TW_CONTROL_CLEAR_HOST_INTERRUPT, TW_CONTROL_REG_ADDR(x)))
|
||||
#define TW_DISABLE_INTERRUPTS(x) (writel(TW_CONTROL_DISABLE_INTERRUPTS, TW_CONTROL_REG_ADDR(x)))
|
||||
#define TW_ENABLE_AND_CLEAR_INTERRUPTS(x) (writel(TW_CONTROL_CLEAR_ATTENTION_INTERRUPT | TW_CONTROL_UNMASK_RESPONSE_INTERRUPT | TW_CONTROL_ENABLE_INTERRUPTS, TW_CONTROL_REG_ADDR(x)))
|
||||
#define TW_MASK_COMMAND_INTERRUPT(x) (writel(TW_CONTROL_MASK_COMMAND_INTERRUPT, TW_CONTROL_REG_ADDR(x)))
|
||||
#define TW_UNMASK_COMMAND_INTERRUPT(x) (writel(TW_CONTROL_UNMASK_COMMAND_INTERRUPT, TW_CONTROL_REG_ADDR(x)))
|
||||
#define TW_SOFT_RESET(x) (writel(TW_CONTROL_ISSUE_SOFT_RESET | \
|
||||
#define TW_COMMAND_QUEUE_REG_ADDR(x) \
|
||||
(sizeof(dma_addr_t) > 4 ? ((unsigned char __iomem *)x->base_addr + 0x20) : ((unsigned char __iomem *)x->base_addr + 0x8))
|
||||
#define TW_COMMAND_QUEUE_REG_ADDR_LARGE(x) \
|
||||
((unsigned char __iomem *)x->base_addr + 0x20)
|
||||
#define TW_RESPONSE_QUEUE_REG_ADDR(x) \
|
||||
((unsigned char __iomem *)x->base_addr + 0xC)
|
||||
#define TW_RESPONSE_QUEUE_REG_ADDR_LARGE(x) \
|
||||
((unsigned char __iomem *)x->base_addr + 0x30)
|
||||
#define TW_CLEAR_ALL_INTERRUPTS(x) \
|
||||
(writel(TW_STATUS_VALID_INTERRUPT, TW_CONTROL_REG_ADDR(x)))
|
||||
#define TW_CLEAR_ATTENTION_INTERRUPT(x) \
|
||||
(writel(TW_CONTROL_CLEAR_ATTENTION_INTERRUPT, TW_CONTROL_REG_ADDR(x)))
|
||||
#define TW_CLEAR_HOST_INTERRUPT(x) \
|
||||
(writel(TW_CONTROL_CLEAR_HOST_INTERRUPT, TW_CONTROL_REG_ADDR(x)))
|
||||
#define TW_DISABLE_INTERRUPTS(x) \
|
||||
(writel(TW_CONTROL_DISABLE_INTERRUPTS, TW_CONTROL_REG_ADDR(x)))
|
||||
#define TW_ENABLE_AND_CLEAR_INTERRUPTS(x) \
|
||||
(writel(TW_CONTROL_CLEAR_ATTENTION_INTERRUPT | \
|
||||
TW_CONTROL_UNMASK_RESPONSE_INTERRUPT | \
|
||||
TW_CONTROL_ENABLE_INTERRUPTS, TW_CONTROL_REG_ADDR(x)))
|
||||
#define TW_MASK_COMMAND_INTERRUPT(x) \
|
||||
(writel(TW_CONTROL_MASK_COMMAND_INTERRUPT, TW_CONTROL_REG_ADDR(x)))
|
||||
#define TW_UNMASK_COMMAND_INTERRUPT(x) \
|
||||
(writel(TW_CONTROL_UNMASK_COMMAND_INTERRUPT, TW_CONTROL_REG_ADDR(x)))
|
||||
#define TW_SOFT_RESET(x) (writel(TW_CONTROL_ISSUE_SOFT_RESET | \
|
||||
TW_CONTROL_CLEAR_HOST_INTERRUPT | \
|
||||
TW_CONTROL_CLEAR_ATTENTION_INTERRUPT | \
|
||||
TW_CONTROL_MASK_COMMAND_INTERRUPT | \
|
||||
@ -586,7 +600,7 @@ typedef struct TAG_TW_Ioctl_Driver_Command {
|
||||
|
||||
typedef struct TAG_TW_Ioctl_Apache {
|
||||
TW_Ioctl_Driver_Command driver_command;
|
||||
char padding[488];
|
||||
char padding[488];
|
||||
TW_Command_Full firmware_command;
|
||||
char data_buffer[1];
|
||||
} TW_Ioctl_Buf_Apache;
|
||||
@ -634,10 +648,10 @@ typedef struct TAG_TW_Compatibility_Info
|
||||
#pragma pack()
|
||||
|
||||
typedef struct TAG_TW_Device_Extension {
|
||||
u32 __iomem *base_addr;
|
||||
unsigned long *generic_buffer_virt[TW_Q_LENGTH];
|
||||
dma_addr_t generic_buffer_phys[TW_Q_LENGTH];
|
||||
TW_Command_Full *command_packet_virt[TW_Q_LENGTH];
|
||||
u32 __iomem *base_addr;
|
||||
unsigned long *generic_buffer_virt[TW_Q_LENGTH];
|
||||
dma_addr_t generic_buffer_phys[TW_Q_LENGTH];
|
||||
TW_Command_Full *command_packet_virt[TW_Q_LENGTH];
|
||||
dma_addr_t command_packet_phys[TW_Q_LENGTH];
|
||||
struct pci_dev *tw_pci_dev;
|
||||
struct scsi_cmnd *srb[TW_Q_LENGTH];
|
||||
@ -647,10 +661,10 @@ typedef struct TAG_TW_Device_Extension {
|
||||
unsigned char pending_queue[TW_Q_LENGTH];
|
||||
unsigned char pending_head;
|
||||
unsigned char pending_tail;
|
||||
int state[TW_Q_LENGTH];
|
||||
int state[TW_Q_LENGTH];
|
||||
unsigned int posted_request_count;
|
||||
unsigned int max_posted_request_count;
|
||||
unsigned int pending_request_count;
|
||||
unsigned int pending_request_count;
|
||||
unsigned int max_pending_request_count;
|
||||
unsigned int max_sgl_entries;
|
||||
unsigned int sgl_entries;
|
||||
@ -661,12 +675,12 @@ typedef struct TAG_TW_Device_Extension {
|
||||
struct Scsi_Host *host;
|
||||
long flags;
|
||||
int reset_print;
|
||||
TW_Event *event_queue[TW_Q_LENGTH];
|
||||
unsigned char error_index;
|
||||
TW_Event *event_queue[TW_Q_LENGTH];
|
||||
unsigned char error_index;
|
||||
unsigned char event_queue_wrapped;
|
||||
unsigned int error_sequence_id;
|
||||
int ioctl_sem_lock;
|
||||
ktime_t ioctl_time;
|
||||
unsigned int error_sequence_id;
|
||||
int ioctl_sem_lock;
|
||||
ktime_t ioctl_time;
|
||||
int chrdev_request_id;
|
||||
wait_queue_head_t ioctl_wqueue;
|
||||
struct mutex ioctl_lock;
|
||||
|
@ -120,7 +120,7 @@ static struct bin_attribute twl_sysfs_aen_read_attr = {
|
||||
.attr = {
|
||||
.name = "3ware_aen_read",
|
||||
.mode = S_IRUSR,
|
||||
},
|
||||
},
|
||||
.size = 0,
|
||||
.read = twl_sysfs_aen_read
|
||||
};
|
||||
@ -151,7 +151,7 @@ static struct bin_attribute twl_sysfs_compat_info_attr = {
|
||||
.attr = {
|
||||
.name = "3ware_compat_info",
|
||||
.mode = S_IRUSR,
|
||||
},
|
||||
},
|
||||
.size = 0,
|
||||
.read = twl_sysfs_compat_info
|
||||
};
|
||||
@ -174,7 +174,7 @@ static ssize_t twl_show_stats(struct device *dev,
|
||||
"Last sector count: %4d\n"
|
||||
"Max sector count: %4d\n"
|
||||
"SCSI Host Resets: %4d\n"
|
||||
"AEN's: %4d\n",
|
||||
"AEN's: %4d\n",
|
||||
TW_DRIVER_VERSION,
|
||||
tw_dev->posted_request_count,
|
||||
tw_dev->max_posted_request_count,
|
||||
@ -191,7 +191,7 @@ static ssize_t twl_show_stats(struct device *dev,
|
||||
/* stats sysfs attribute initializer */
|
||||
static struct device_attribute twl_host_stats_attr = {
|
||||
.attr = {
|
||||
.name = "3ware_stats",
|
||||
.name = "3ware_stats",
|
||||
.mode = S_IRUGO,
|
||||
},
|
||||
.show = twl_show_stats
|
||||
@ -432,7 +432,7 @@ static void twl_aen_sync_time(TW_Device_Extension *tw_dev, int request_id)
|
||||
param->parameter_id = cpu_to_le16(0x3); /* SchedulerTime */
|
||||
param->parameter_size_bytes = cpu_to_le16(4);
|
||||
|
||||
/* Convert system time in UTC to local time seconds since last
|
||||
/* Convert system time in UTC to local time seconds since last
|
||||
Sunday 12:00AM */
|
||||
local_time = (ktime_get_real_seconds() - (sys_tz.tz_minuteswest * 60));
|
||||
div_u64_rem(local_time - (3 * 86400), 604800, &schedulertime);
|
||||
@ -483,7 +483,7 @@ static int twl_aen_complete(TW_Device_Extension *tw_dev, int request_id)
|
||||
/* Keep reading the queue in case there are more aen's */
|
||||
if (twl_aen_read_queue(tw_dev, request_id))
|
||||
goto out2;
|
||||
else {
|
||||
else {
|
||||
retval = 0;
|
||||
goto out;
|
||||
}
|
||||
@ -548,7 +548,7 @@ static int twl_poll_response(TW_Device_Extension *tw_dev, int request_id, int se
|
||||
msleep(50);
|
||||
}
|
||||
retval = 0;
|
||||
out:
|
||||
out:
|
||||
return retval;
|
||||
} /* End twl_poll_response() */
|
||||
|
||||
@ -802,7 +802,7 @@ static long twl_chrdev_ioctl(struct file *file, unsigned int cmd, unsigned long
|
||||
|
||||
/* Now copy in the command packet response */
|
||||
memcpy(&(tw_ioctl->firmware_command), tw_dev->command_packet_virt[request_id], sizeof(TW_Command_Full));
|
||||
|
||||
|
||||
/* Now complete the io */
|
||||
spin_lock_irqsave(tw_dev->host->host_lock, flags);
|
||||
tw_dev->posted_request_count--;
|
||||
@ -879,7 +879,7 @@ static int twl_fill_sense(TW_Device_Extension *tw_dev, int i, int request_id, in
|
||||
tw_dev->host->host_no,
|
||||
TW_MESSAGE_SOURCE_CONTROLLER_ERROR,
|
||||
header->status_block.error,
|
||||
error_str,
|
||||
error_str,
|
||||
header->err_specific_desc);
|
||||
else
|
||||
printk(KERN_WARNING "3w-sas: ERROR: (0x%02X:0x%04X): %s:%s.\n",
|
||||
@ -937,8 +937,8 @@ static void *twl_get_param(TW_Device_Extension *tw_dev, int request_id, int tabl
|
||||
command_packet = &full_command_packet->command.oldcommand;
|
||||
|
||||
command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_GET_PARAM);
|
||||
command_packet->size = TW_COMMAND_SIZE;
|
||||
command_packet->request_id = request_id;
|
||||
command_packet->size = TW_COMMAND_SIZE;
|
||||
command_packet->request_id = request_id;
|
||||
command_packet->byte6_offset.block_count = cpu_to_le16(1);
|
||||
|
||||
/* Now setup the param */
|
||||
@ -968,14 +968,14 @@ static void *twl_get_param(TW_Device_Extension *tw_dev, int request_id, int tabl
|
||||
|
||||
/* This function will send an initconnection command to controller */
|
||||
static int twl_initconnection(TW_Device_Extension *tw_dev, int message_credits,
|
||||
u32 set_features, unsigned short current_fw_srl,
|
||||
unsigned short current_fw_arch_id,
|
||||
unsigned short current_fw_branch,
|
||||
unsigned short current_fw_build,
|
||||
unsigned short *fw_on_ctlr_srl,
|
||||
unsigned short *fw_on_ctlr_arch_id,
|
||||
unsigned short *fw_on_ctlr_branch,
|
||||
unsigned short *fw_on_ctlr_build,
|
||||
u32 set_features, unsigned short current_fw_srl,
|
||||
unsigned short current_fw_arch_id,
|
||||
unsigned short current_fw_branch,
|
||||
unsigned short current_fw_build,
|
||||
unsigned short *fw_on_ctlr_srl,
|
||||
unsigned short *fw_on_ctlr_arch_id,
|
||||
unsigned short *fw_on_ctlr_branch,
|
||||
unsigned short *fw_on_ctlr_build,
|
||||
u32 *init_connect_result)
|
||||
{
|
||||
TW_Command_Full *full_command_packet;
|
||||
@ -986,7 +986,7 @@ static int twl_initconnection(TW_Device_Extension *tw_dev, int message_credits,
|
||||
full_command_packet = tw_dev->command_packet_virt[request_id];
|
||||
memset(full_command_packet, 0, sizeof(TW_Command_Full));
|
||||
full_command_packet->header.header_desc.size_header = 128;
|
||||
|
||||
|
||||
tw_initconnect = (TW_Initconnect *)&full_command_packet->command.oldcommand;
|
||||
tw_initconnect->opcode__reserved = TW_OPRES_IN(0, TW_OP_INIT_CONNECTION);
|
||||
tw_initconnect->request_id = request_id;
|
||||
@ -1004,7 +1004,7 @@ static int twl_initconnection(TW_Device_Extension *tw_dev, int message_credits,
|
||||
tw_initconnect->fw_arch_id = cpu_to_le16(current_fw_arch_id);
|
||||
tw_initconnect->fw_branch = cpu_to_le16(current_fw_branch);
|
||||
tw_initconnect->fw_build = cpu_to_le16(current_fw_build);
|
||||
} else
|
||||
} else
|
||||
tw_initconnect->size = TW_INIT_COMMAND_PACKET_SIZE;
|
||||
|
||||
/* Send command packet to the board */
|
||||
@ -1211,7 +1211,7 @@ static irqreturn_t twl_interrupt(int irq, void *dev_instance)
|
||||
|
||||
if (!error)
|
||||
cmd->result = (DID_OK << 16);
|
||||
|
||||
|
||||
/* Report residual bytes for single sgl */
|
||||
if ((scsi_sg_count(cmd) <= 1) && (full_command_packet->command.newcommand.status == 0)) {
|
||||
if (full_command_packet->command.newcommand.sg_list[0].length < scsi_bufflen(tw_dev->srb[request_id]))
|
||||
@ -1245,7 +1245,7 @@ static int twl_poll_register(TW_Device_Extension *tw_dev, void *reg, u32 value,
|
||||
reg_value = readl(reg);
|
||||
before = jiffies;
|
||||
|
||||
while ((reg_value & value) != result) {
|
||||
while ((reg_value & value) != result) {
|
||||
reg_value = readl(reg);
|
||||
if (time_after(jiffies, before + HZ * seconds))
|
||||
goto out;
|
||||
@ -1470,7 +1470,7 @@ static int twl_scsi_queue_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_
|
||||
|
||||
/* Save done function into scsi_cmnd struct */
|
||||
SCpnt->scsi_done = done;
|
||||
|
||||
|
||||
/* Get a free request id */
|
||||
twl_get_request_id(tw_dev, &request_id);
|
||||
|
||||
@ -1524,7 +1524,7 @@ static void twl_shutdown(struct pci_dev *pdev)
|
||||
|
||||
tw_dev = (TW_Device_Extension *)host->hostdata;
|
||||
|
||||
if (tw_dev->online)
|
||||
if (tw_dev->online)
|
||||
__twl_shutdown(tw_dev);
|
||||
} /* End twl_shutdown() */
|
||||
|
||||
@ -1675,7 +1675,7 @@ static int twl_probe(struct pci_dev *pdev, const struct pci_device_id *dev_id)
|
||||
|
||||
/* Re-enable interrupts on the card */
|
||||
TWL_UNMASK_INTERRUPTS(tw_dev);
|
||||
|
||||
|
||||
/* Finally, scan the host */
|
||||
scsi_scan_host(host);
|
||||
|
||||
|
@ -52,17 +52,17 @@ static char *twl_aen_severity_table[] =
|
||||
};
|
||||
|
||||
/* Liberator register offsets */
|
||||
#define TWL_STATUS 0x0 /* Status */
|
||||
#define TWL_HIBDB 0x20 /* Inbound doorbell */
|
||||
#define TWL_HISTAT 0x30 /* Host interrupt status */
|
||||
#define TWL_HIMASK 0x34 /* Host interrupt mask */
|
||||
#define TWL_STATUS 0x0 /* Status */
|
||||
#define TWL_HIBDB 0x20 /* Inbound doorbell */
|
||||
#define TWL_HISTAT 0x30 /* Host interrupt status */
|
||||
#define TWL_HIMASK 0x34 /* Host interrupt mask */
|
||||
#define TWL_HOBDB 0x9C /* Outbound doorbell */
|
||||
#define TWL_HOBDBC 0xA0 /* Outbound doorbell clear */
|
||||
#define TWL_SCRPD3 0xBC /* Scratchpad */
|
||||
#define TWL_HIBQPL 0xC0 /* Host inbound Q low */
|
||||
#define TWL_HIBQPH 0xC4 /* Host inbound Q high */
|
||||
#define TWL_HOBQPL 0xC8 /* Host outbound Q low */
|
||||
#define TWL_HOBQPH 0xCC /* Host outbound Q high */
|
||||
#define TWL_HOBDBC 0xA0 /* Outbound doorbell clear */
|
||||
#define TWL_SCRPD3 0xBC /* Scratchpad */
|
||||
#define TWL_HIBQPL 0xC0 /* Host inbound Q low */
|
||||
#define TWL_HIBQPH 0xC4 /* Host inbound Q high */
|
||||
#define TWL_HOBQPL 0xC8 /* Host outbound Q low */
|
||||
#define TWL_HOBQPH 0xCC /* Host outbound Q high */
|
||||
#define TWL_HISTATUS_VALID_INTERRUPT 0xC
|
||||
#define TWL_HISTATUS_ATTENTION_INTERRUPT 0x4
|
||||
#define TWL_HISTATUS_RESPONSE_INTERRUPT 0x8
|
||||
@ -80,12 +80,12 @@ static char *twl_aen_severity_table[] =
|
||||
#define TW_OP_EXECUTE_SCSI 0x10
|
||||
|
||||
/* Asynchronous Event Notification (AEN) codes used by the driver */
|
||||
#define TW_AEN_QUEUE_EMPTY 0x0000
|
||||
#define TW_AEN_SOFT_RESET 0x0001
|
||||
#define TW_AEN_QUEUE_EMPTY 0x0000
|
||||
#define TW_AEN_SOFT_RESET 0x0001
|
||||
#define TW_AEN_SYNC_TIME_WITH_HOST 0x031
|
||||
#define TW_AEN_SEVERITY_ERROR 0x1
|
||||
#define TW_AEN_SEVERITY_DEBUG 0x4
|
||||
#define TW_AEN_NOT_RETRIEVED 0x1
|
||||
#define TW_AEN_SEVERITY_ERROR 0x1
|
||||
#define TW_AEN_SEVERITY_DEBUG 0x4
|
||||
#define TW_AEN_NOT_RETRIEVED 0x1
|
||||
|
||||
/* Command state defines */
|
||||
#define TW_S_INITIAL 0x1 /* Initial state */
|
||||
@ -101,7 +101,7 @@ static char *twl_aen_severity_table[] =
|
||||
#define TW_CURRENT_DRIVER_BRANCH 0
|
||||
|
||||
/* Misc defines */
|
||||
#define TW_SECTOR_SIZE 512
|
||||
#define TW_SECTOR_SIZE 512
|
||||
#define TW_MAX_UNITS 32
|
||||
#define TW_INIT_MESSAGE_CREDITS 0x100
|
||||
#define TW_INIT_COMMAND_PACKET_SIZE 0x3
|
||||
@ -116,15 +116,15 @@ static char *twl_aen_severity_table[] =
|
||||
#define TW_MAX_RESET_TRIES 2
|
||||
#define TW_MAX_CMDS_PER_LUN 254
|
||||
#define TW_MAX_AEN_DRAIN 255
|
||||
#define TW_IN_RESET 2
|
||||
#define TW_IN_RESET 2
|
||||
#define TW_USING_MSI 3
|
||||
#define TW_IN_ATTENTION_LOOP 4
|
||||
#define TW_MAX_SECTORS 256
|
||||
#define TW_MAX_CDB_LEN 16
|
||||
#define TW_IOCTL_CHRDEV_TIMEOUT 60 /* 60 seconds */
|
||||
#define TW_IOCTL_CHRDEV_FREE -1
|
||||
#define TW_COMMAND_OFFSET 128 /* 128 bytes */
|
||||
#define TW_VERSION_TABLE 0x0402
|
||||
#define TW_MAX_SECTORS 256
|
||||
#define TW_MAX_CDB_LEN 16
|
||||
#define TW_IOCTL_CHRDEV_TIMEOUT 60 /* 60 seconds */
|
||||
#define TW_IOCTL_CHRDEV_FREE -1
|
||||
#define TW_COMMAND_OFFSET 128 /* 128 bytes */
|
||||
#define TW_VERSION_TABLE 0x0402
|
||||
#define TW_TIMEKEEP_TABLE 0x040A
|
||||
#define TW_INFORMATION_TABLE 0x0403
|
||||
#define TW_PARAM_FWVER 3
|
||||
@ -136,15 +136,15 @@ static char *twl_aen_severity_table[] =
|
||||
#define TW_PARAM_PHY_SUMMARY_TABLE 1
|
||||
#define TW_PARAM_PHYCOUNT 2
|
||||
#define TW_PARAM_PHYCOUNT_LENGTH 1
|
||||
#define TW_IOCTL_FIRMWARE_PASS_THROUGH 0x108 // Used by smartmontools
|
||||
#define TW_IOCTL_FIRMWARE_PASS_THROUGH 0x108 // Used by smartmontools
|
||||
#define TW_ALLOCATION_LENGTH 128
|
||||
#define TW_SENSE_DATA_LENGTH 18
|
||||
#define TW_ERROR_LOGICAL_UNIT_NOT_SUPPORTED 0x10a
|
||||
#define TW_ERROR_INVALID_FIELD_IN_CDB 0x10d
|
||||
#define TW_ERROR_UNIT_OFFLINE 0x128
|
||||
#define TW_ERROR_UNIT_OFFLINE 0x128
|
||||
#define TW_MESSAGE_SOURCE_CONTROLLER_ERROR 3
|
||||
#define TW_MESSAGE_SOURCE_CONTROLLER_EVENT 4
|
||||
#define TW_DRIVER 6
|
||||
#define TW_DRIVER 6
|
||||
#ifndef PCI_DEVICE_ID_3WARE_9750
|
||||
#define PCI_DEVICE_ID_3WARE_9750 0x1010
|
||||
#endif
|
||||
@ -167,25 +167,41 @@ static char *twl_aen_severity_table[] =
|
||||
#define TW_NOTMFA_OUT(x) (x & 0x1)
|
||||
|
||||
/* request_id: 12, lun: 4 */
|
||||
#define TW_REQ_LUN_IN(lun, request_id) (((lun << 12) & 0xf000) | (request_id & 0xfff))
|
||||
#define TW_REQ_LUN_IN(lun, request_id) \
|
||||
(((lun << 12) & 0xf000) | (request_id & 0xfff))
|
||||
#define TW_LUN_OUT(lun) ((lun >> 12) & 0xf)
|
||||
|
||||
/* Register access macros */
|
||||
#define TWL_STATUS_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_STATUS)
|
||||
#define TWL_HOBQPL_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_HOBQPL)
|
||||
#define TWL_HOBQPH_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_HOBQPH)
|
||||
#define TWL_HOBDB_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_HOBDB)
|
||||
#define TWL_HOBDBC_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_HOBDBC)
|
||||
#define TWL_HIMASK_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_HIMASK)
|
||||
#define TWL_HISTAT_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_HISTAT)
|
||||
#define TWL_HIBQPH_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_HIBQPH)
|
||||
#define TWL_HIBQPL_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_HIBQPL)
|
||||
#define TWL_HIBDB_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_HIBDB)
|
||||
#define TWL_SCRPD3_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_SCRPD3)
|
||||
#define TWL_MASK_INTERRUPTS(x) (writel(~0, TWL_HIMASK_REG_ADDR(tw_dev)))
|
||||
#define TWL_UNMASK_INTERRUPTS(x) (writel(~TWL_HISTATUS_VALID_INTERRUPT, TWL_HIMASK_REG_ADDR(tw_dev)))
|
||||
#define TWL_CLEAR_DB_INTERRUPT(x) (writel(~0, TWL_HOBDBC_REG_ADDR(tw_dev)))
|
||||
#define TWL_SOFT_RESET(x) (writel(TWL_ISSUE_SOFT_RESET, TWL_HIBDB_REG_ADDR(tw_dev)))
|
||||
#define TWL_STATUS_REG_ADDR(x) \
|
||||
((unsigned char __iomem *)x->base_addr + TWL_STATUS)
|
||||
#define TWL_HOBQPL_REG_ADDR(x) \
|
||||
((unsigned char __iomem *)x->base_addr + TWL_HOBQPL)
|
||||
#define TWL_HOBQPH_REG_ADDR(x) \
|
||||
((unsigned char __iomem *)x->base_addr + TWL_HOBQPH)
|
||||
#define TWL_HOBDB_REG_ADDR(x) \
|
||||
((unsigned char __iomem *)x->base_addr + TWL_HOBDB)
|
||||
#define TWL_HOBDBC_REG_ADDR(x) \
|
||||
((unsigned char __iomem *)x->base_addr + TWL_HOBDBC)
|
||||
#define TWL_HIMASK_REG_ADDR(x) \
|
||||
((unsigned char __iomem *)x->base_addr + TWL_HIMASK)
|
||||
#define TWL_HISTAT_REG_ADDR(x) \
|
||||
((unsigned char __iomem *)x->base_addr + TWL_HISTAT)
|
||||
#define TWL_HIBQPH_REG_ADDR(x) \
|
||||
((unsigned char __iomem *)x->base_addr + TWL_HIBQPH)
|
||||
#define TWL_HIBQPL_REG_ADDR(x) \
|
||||
((unsigned char __iomem *)x->base_addr + TWL_HIBQPL)
|
||||
#define TWL_HIBDB_REG_ADDR(x) \
|
||||
((unsigned char __iomem *)x->base_addr + TWL_HIBDB)
|
||||
#define TWL_SCRPD3_REG_ADDR(x) \
|
||||
((unsigned char __iomem *)x->base_addr + TWL_SCRPD3)
|
||||
#define TWL_MASK_INTERRUPTS(x) \
|
||||
(writel(~0, TWL_HIMASK_REG_ADDR(tw_dev)))
|
||||
#define TWL_UNMASK_INTERRUPTS(x) \
|
||||
(writel(~TWL_HISTATUS_VALID_INTERRUPT, TWL_HIMASK_REG_ADDR(tw_dev)))
|
||||
#define TWL_CLEAR_DB_INTERRUPT(x) \
|
||||
(writel(~0, TWL_HOBDBC_REG_ADDR(tw_dev)))
|
||||
#define TWL_SOFT_RESET(x) \
|
||||
(writel(TWL_ISSUE_SOFT_RESET, TWL_HIBDB_REG_ADDR(tw_dev)))
|
||||
|
||||
/* Macros */
|
||||
#define TW_PRINTK(h,a,b,c) { \
|
||||
@ -317,7 +333,7 @@ typedef struct TAG_TW_Ioctl_Driver_Command {
|
||||
|
||||
typedef struct TAG_TW_Ioctl_Apache {
|
||||
TW_Ioctl_Driver_Command driver_command;
|
||||
char padding[488];
|
||||
char padding[488];
|
||||
TW_Command_Full firmware_command;
|
||||
char data_buffer[1];
|
||||
} TW_Ioctl_Buf_Apache;
|
||||
@ -352,10 +368,10 @@ typedef struct TAG_TW_Compatibility_Info
|
||||
#pragma pack()
|
||||
|
||||
typedef struct TAG_TW_Device_Extension {
|
||||
void __iomem *base_addr;
|
||||
unsigned long *generic_buffer_virt[TW_Q_LENGTH];
|
||||
dma_addr_t generic_buffer_phys[TW_Q_LENGTH];
|
||||
TW_Command_Full *command_packet_virt[TW_Q_LENGTH];
|
||||
void __iomem *base_addr;
|
||||
unsigned long *generic_buffer_virt[TW_Q_LENGTH];
|
||||
dma_addr_t generic_buffer_phys[TW_Q_LENGTH];
|
||||
TW_Command_Full *command_packet_virt[TW_Q_LENGTH];
|
||||
dma_addr_t command_packet_phys[TW_Q_LENGTH];
|
||||
TW_Command_Apache_Header *sense_buffer_virt[TW_Q_LENGTH];
|
||||
dma_addr_t sense_buffer_phys[TW_Q_LENGTH];
|
||||
@ -364,7 +380,7 @@ typedef struct TAG_TW_Device_Extension {
|
||||
unsigned char free_queue[TW_Q_LENGTH];
|
||||
unsigned char free_head;
|
||||
unsigned char free_tail;
|
||||
int state[TW_Q_LENGTH];
|
||||
int state[TW_Q_LENGTH];
|
||||
unsigned int posted_request_count;
|
||||
unsigned int max_posted_request_count;
|
||||
unsigned int max_sgl_entries;
|
||||
@ -375,9 +391,9 @@ typedef struct TAG_TW_Device_Extension {
|
||||
unsigned int aen_count;
|
||||
struct Scsi_Host *host;
|
||||
long flags;
|
||||
TW_Event *event_queue[TW_Q_LENGTH];
|
||||
unsigned char error_index;
|
||||
unsigned int error_sequence_id;
|
||||
TW_Event *event_queue[TW_Q_LENGTH];
|
||||
unsigned char error_index;
|
||||
unsigned int error_sequence_id;
|
||||
int chrdev_request_id;
|
||||
wait_queue_head_t ioctl_wqueue;
|
||||
struct mutex ioctl_lock;
|
||||
|
@ -1,52 +1,52 @@
|
||||
/*
|
||||
/*
|
||||
3w-xxxx.c -- 3ware Storage Controller device driver for Linux.
|
||||
|
||||
Written By: Adam Radford <aradford@gmail.com>
|
||||
Modifications By: Joel Jacobson <linux@3ware.com>
|
||||
Arnaldo Carvalho de Melo <acme@conectiva.com.br>
|
||||
Arnaldo Carvalho de Melo <acme@conectiva.com.br>
|
||||
Brad Strand <linux@3ware.com>
|
||||
|
||||
Copyright (C) 1999-2010 3ware Inc.
|
||||
|
||||
Kernel compatibility By: Andre Hedrick <andre@suse.com>
|
||||
Kernel compatibility By: Andre Hedrick <andre@suse.com>
|
||||
Non-Copyright (C) 2000 Andre Hedrick <andre@suse.com>
|
||||
|
||||
|
||||
Further tiny build fixes and trivial hoovering Alan Cox
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
NO WARRANTY
|
||||
THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
|
||||
LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
|
||||
solely responsible for determining the appropriateness of using and
|
||||
distributing the Program and assumes all risks associated with its
|
||||
exercise of rights under this Agreement, including but not limited to
|
||||
the risks and costs of program errors, damage to or loss of data,
|
||||
programs or equipment, and unavailability or interruption of operations.
|
||||
NO WARRANTY
|
||||
THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
|
||||
LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
|
||||
solely responsible for determining the appropriateness of using and
|
||||
distributing the Program and assumes all risks associated with its
|
||||
exercise of rights under this Agreement, including but not limited to
|
||||
the risks and costs of program errors, damage to or loss of data,
|
||||
programs or equipment, and unavailability or interruption of operations.
|
||||
|
||||
DISCLAIMER OF LIABILITY
|
||||
NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
|
||||
HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
|
||||
DISCLAIMER OF LIABILITY
|
||||
NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
|
||||
HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
Bugs/Comments/Suggestions should be mailed to:
|
||||
Bugs/Comments/Suggestions should be mailed to:
|
||||
|
||||
aradford@gmail.com
|
||||
|
||||
@ -70,7 +70,7 @@
|
||||
1.02.00.003 - Fix tw_interrupt() to report error to scsi layer when
|
||||
controller status is non-zero.
|
||||
Added handling of request_sense opcode.
|
||||
Fix possible null pointer dereference in
|
||||
Fix possible null pointer dereference in
|
||||
tw_reset_device_extension()
|
||||
1.02.00.004 - Add support for device id of 3ware 7000 series controllers.
|
||||
Make tw_setfeature() call with interrupts disabled.
|
||||
@ -239,7 +239,7 @@ static int tw_reset_device_extension(TW_Device_Extension *tw_dev);
|
||||
/* This function will check the status register for unexpected bits */
|
||||
static int tw_check_bits(u32 status_reg_value)
|
||||
{
|
||||
if ((status_reg_value & TW_STATUS_EXPECTED_BITS) != TW_STATUS_EXPECTED_BITS) {
|
||||
if ((status_reg_value & TW_STATUS_EXPECTED_BITS) != TW_STATUS_EXPECTED_BITS) {
|
||||
dprintk(KERN_WARNING "3w-xxxx: tw_check_bits(): No expected bits (0x%x).\n", status_reg_value);
|
||||
return 1;
|
||||
}
|
||||
@ -291,7 +291,7 @@ static int tw_decode_bits(TW_Device_Extension *tw_dev, u32 status_reg_value, int
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
} /* End tw_decode_bits() */
|
||||
|
||||
@ -390,7 +390,7 @@ static int tw_post_command_packet(TW_Device_Extension *tw_dev, int request_id)
|
||||
} else {
|
||||
tw_dev->pending_tail = tw_dev->pending_tail + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
TW_UNMASK_COMMAND_INTERRUPT(tw_dev);
|
||||
return 1;
|
||||
}
|
||||
@ -403,7 +403,7 @@ static int tw_decode_sense(TW_Device_Extension *tw_dev, int request_id, int fill
|
||||
int i;
|
||||
TW_Command *command;
|
||||
|
||||
dprintk(KERN_WARNING "3w-xxxx: tw_decode_sense()\n");
|
||||
dprintk(KERN_WARNING "3w-xxxx: tw_decode_sense()\n");
|
||||
command = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
|
||||
|
||||
printk(KERN_WARNING "3w-xxxx: scsi%d: Command failed: status = 0x%x, flags = 0x%x, unit #%d.\n", tw_dev->host->host_no, command->status, command->flags, TW_UNIT_OUT(command->unit__hostid));
|
||||
@ -443,10 +443,10 @@ static int tw_decode_sense(TW_Device_Extension *tw_dev, int request_id, int fill
|
||||
} /* End tw_decode_sense() */
|
||||
|
||||
/* This function will report controller error status */
|
||||
static int tw_check_errors(TW_Device_Extension *tw_dev)
|
||||
static int tw_check_errors(TW_Device_Extension *tw_dev)
|
||||
{
|
||||
u32 status_reg_value;
|
||||
|
||||
|
||||
status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev));
|
||||
|
||||
if (TW_STATUS_ERRORS(status_reg_value) || tw_check_bits(status_reg_value)) {
|
||||
@ -458,7 +458,7 @@ static int tw_check_errors(TW_Device_Extension *tw_dev)
|
||||
} /* End tw_check_errors() */
|
||||
|
||||
/* This function will empty the response que */
|
||||
static void tw_empty_response_que(TW_Device_Extension *tw_dev)
|
||||
static void tw_empty_response_que(TW_Device_Extension *tw_dev)
|
||||
{
|
||||
u32 status_reg_value, response_que_value;
|
||||
|
||||
@ -525,7 +525,7 @@ static ssize_t tw_show_stats(struct device *dev, struct device_attribute *attr,
|
||||
/* Create sysfs 'stats' entry */
|
||||
static struct device_attribute tw_host_stats_attr = {
|
||||
.attr = {
|
||||
.name = "stats",
|
||||
.name = "stats",
|
||||
.mode = S_IRUGO,
|
||||
},
|
||||
.show = tw_show_stats
|
||||
@ -538,7 +538,7 @@ static struct device_attribute *tw_host_attrs[] = {
|
||||
};
|
||||
|
||||
/* This function will read the aen queue from the isr */
|
||||
static int tw_aen_read_queue(TW_Device_Extension *tw_dev, int request_id)
|
||||
static int tw_aen_read_queue(TW_Device_Extension *tw_dev, int request_id)
|
||||
{
|
||||
TW_Command *command_packet;
|
||||
TW_Param *param;
|
||||
@ -604,7 +604,7 @@ static int tw_aen_read_queue(TW_Device_Extension *tw_dev, int request_id)
|
||||
} /* End tw_aen_read_queue() */
|
||||
|
||||
/* This function will complete an aen request from the isr */
|
||||
static int tw_aen_complete(TW_Device_Extension *tw_dev, int request_id)
|
||||
static int tw_aen_complete(TW_Device_Extension *tw_dev, int request_id)
|
||||
{
|
||||
TW_Param *param;
|
||||
unsigned short aen;
|
||||
@ -628,7 +628,7 @@ static int tw_aen_complete(TW_Device_Extension *tw_dev, int request_id)
|
||||
if ((tw_aen_string[aen & 0xff][strlen(tw_aen_string[aen & 0xff])-1]) == '#') {
|
||||
printk(KERN_WARNING "3w-xxxx: scsi%d: AEN: %s%d.\n", tw_dev->host->host_no, tw_aen_string[aen & 0xff], aen >> 8);
|
||||
} else {
|
||||
if (aen != 0x0)
|
||||
if (aen != 0x0)
|
||||
printk(KERN_WARNING "3w-xxxx: scsi%d: AEN: %s.\n", tw_dev->host->host_no, tw_aen_string[aen & 0xff]);
|
||||
}
|
||||
} else {
|
||||
@ -746,7 +746,7 @@ static int tw_aen_drain_queue(TW_Device_Extension *tw_dev)
|
||||
printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Unexpected request id.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
if (command_packet->status != 0) {
|
||||
if (command_packet->flags != TW_AEN_TABLE_UNDEFINED) {
|
||||
/* Bad response */
|
||||
@ -908,7 +908,7 @@ static long tw_chrdev_ioctl(struct file *file, unsigned int cmd, unsigned long a
|
||||
|
||||
/* Hardware can only do multiple of 512 byte transfers */
|
||||
data_buffer_length_adjusted = (data_buffer_length + 511) & ~511;
|
||||
|
||||
|
||||
/* Now allocate ioctl buf memory */
|
||||
cpu_addr = dma_alloc_coherent(&tw_dev->tw_pci_dev->dev, data_buffer_length_adjusted+sizeof(TW_New_Ioctl) - 1, &dma_handle, GFP_KERNEL);
|
||||
if (cpu_addr == NULL) {
|
||||
@ -1075,7 +1075,7 @@ static void tw_free_device_extension(TW_Device_Extension *tw_dev)
|
||||
} /* End tw_free_device_extension() */
|
||||
|
||||
/* This function will send an initconnection command to controller */
|
||||
static int tw_initconnection(TW_Device_Extension *tw_dev, int message_credits)
|
||||
static int tw_initconnection(TW_Device_Extension *tw_dev, int message_credits)
|
||||
{
|
||||
unsigned long command_que_value;
|
||||
TW_Command *command_packet;
|
||||
@ -1105,10 +1105,10 @@ static int tw_initconnection(TW_Device_Extension *tw_dev, int message_credits)
|
||||
printk(KERN_WARNING "3w-xxxx: tw_initconnection(): Bad command packet physical address.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* Send command packet to the board */
|
||||
outl(command_que_value, TW_COMMAND_QUEUE_REG_ADDR(tw_dev));
|
||||
|
||||
|
||||
/* Poll for completion */
|
||||
if (tw_poll_status_gone(tw_dev, TW_STATUS_RESPONSE_QUEUE_EMPTY, 30) == 0) {
|
||||
response_queue.value = inl(TW_RESPONSE_QUEUE_REG_ADDR(tw_dev));
|
||||
@ -1130,7 +1130,7 @@ static int tw_initconnection(TW_Device_Extension *tw_dev, int message_credits)
|
||||
|
||||
/* Set a value in the features table */
|
||||
static int tw_setfeature(TW_Device_Extension *tw_dev, int parm, int param_size,
|
||||
unsigned char *val)
|
||||
unsigned char *val)
|
||||
{
|
||||
TW_Param *param;
|
||||
TW_Command *command_packet;
|
||||
@ -1139,7 +1139,7 @@ static int tw_setfeature(TW_Device_Extension *tw_dev, int parm, int param_size,
|
||||
unsigned long command_que_value;
|
||||
unsigned long param_value;
|
||||
|
||||
/* Initialize SetParam command packet */
|
||||
/* Initialize SetParam command packet */
|
||||
if (tw_dev->command_packet_virtual_address[request_id] == NULL) {
|
||||
printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Bad command packet virtual address.\n");
|
||||
return 1;
|
||||
@ -1169,7 +1169,7 @@ static int tw_setfeature(TW_Device_Extension *tw_dev, int parm, int param_size,
|
||||
command_packet->request_id = request_id;
|
||||
command_packet->byte6.parameter_count = 1;
|
||||
|
||||
command_que_value = tw_dev->command_packet_physical_address[request_id];
|
||||
command_que_value = tw_dev->command_packet_physical_address[request_id];
|
||||
if (command_que_value == 0) {
|
||||
printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Bad command packet physical address.\n");
|
||||
return 1;
|
||||
@ -1199,7 +1199,7 @@ static int tw_setfeature(TW_Device_Extension *tw_dev, int parm, int param_size,
|
||||
} /* End tw_setfeature() */
|
||||
|
||||
/* This function will reset a controller */
|
||||
static int tw_reset_sequence(TW_Device_Extension *tw_dev)
|
||||
static int tw_reset_sequence(TW_Device_Extension *tw_dev)
|
||||
{
|
||||
int error = 0;
|
||||
int tries = 0;
|
||||
@ -1298,7 +1298,7 @@ static int tw_reset_device_extension(TW_Device_Extension *tw_dev)
|
||||
|
||||
/* Abort all requests that are in progress */
|
||||
for (i=0;i<TW_Q_LENGTH;i++) {
|
||||
if ((tw_dev->state[i] != TW_S_FINISHED) &&
|
||||
if ((tw_dev->state[i] != TW_S_FINISHED) &&
|
||||
(tw_dev->state[i] != TW_S_INITIAL) &&
|
||||
(tw_dev->state[i] != TW_S_COMPLETED)) {
|
||||
srb = tw_dev->srb[i];
|
||||
@ -1339,11 +1339,11 @@ static int tw_reset_device_extension(TW_Device_Extension *tw_dev)
|
||||
|
||||
/* This funciton returns unit geometry in cylinders/heads/sectors */
|
||||
static int tw_scsi_biosparam(struct scsi_device *sdev, struct block_device *bdev,
|
||||
sector_t capacity, int geom[])
|
||||
sector_t capacity, int geom[])
|
||||
{
|
||||
int heads, sectors, cylinders;
|
||||
TW_Device_Extension *tw_dev;
|
||||
|
||||
|
||||
dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_biosparam()\n");
|
||||
tw_dev = (TW_Device_Extension *)sdev->host->hostdata;
|
||||
|
||||
@ -1358,7 +1358,7 @@ static int tw_scsi_biosparam(struct scsi_device *sdev, struct block_device *bdev
|
||||
}
|
||||
|
||||
dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_biosparam(): heads = %d, sectors = %d, cylinders = %d\n", heads, sectors, cylinders);
|
||||
geom[0] = heads;
|
||||
geom[0] = heads;
|
||||
geom[1] = sectors;
|
||||
geom[2] = cylinders;
|
||||
|
||||
@ -1366,7 +1366,7 @@ static int tw_scsi_biosparam(struct scsi_device *sdev, struct block_device *bdev
|
||||
} /* End tw_scsi_biosparam() */
|
||||
|
||||
/* This is the new scsi eh reset function */
|
||||
static int tw_scsi_eh_reset(struct scsi_cmnd *SCpnt)
|
||||
static int tw_scsi_eh_reset(struct scsi_cmnd *SCpnt)
|
||||
{
|
||||
TW_Device_Extension *tw_dev=NULL;
|
||||
int retval = FAILED;
|
||||
@ -1554,7 +1554,7 @@ static int tw_scsiop_mode_sense(TW_Device_Extension *tw_dev, int request_id)
|
||||
|
||||
/* Now try to post the command packet */
|
||||
tw_post_command_packet(tw_dev, request_id);
|
||||
|
||||
|
||||
return 0;
|
||||
} /* End tw_scsiop_mode_sense() */
|
||||
|
||||
@ -1575,16 +1575,16 @@ static int tw_scsiop_mode_sense_complete(TW_Device_Extension *tw_dev, int reques
|
||||
flags = (char *)&(param->data[0]);
|
||||
memset(request_buffer, 0, sizeof(request_buffer));
|
||||
|
||||
request_buffer[0] = 0xf; /* mode data length */
|
||||
request_buffer[1] = 0; /* default medium type */
|
||||
request_buffer[2] = 0x10; /* dpo/fua support on */
|
||||
request_buffer[3] = 0; /* no block descriptors */
|
||||
request_buffer[4] = 0x8; /* caching page */
|
||||
request_buffer[5] = 0xa; /* page length */
|
||||
request_buffer[0] = 0xf; /* mode data length */
|
||||
request_buffer[1] = 0; /* default medium type */
|
||||
request_buffer[2] = 0x10; /* dpo/fua support on */
|
||||
request_buffer[3] = 0; /* no block descriptors */
|
||||
request_buffer[4] = 0x8; /* caching page */
|
||||
request_buffer[5] = 0xa; /* page length */
|
||||
if (*flags & 0x1)
|
||||
request_buffer[6] = 0x5; /* WCE on, RCD on */
|
||||
request_buffer[6] = 0x5; /* WCE on, RCD on */
|
||||
else
|
||||
request_buffer[6] = 0x1; /* WCE off, RCD on */
|
||||
request_buffer[6] = 0x1; /* WCE off, RCD on */
|
||||
tw_transfer_internal(tw_dev, request_id, request_buffer,
|
||||
sizeof(request_buffer));
|
||||
|
||||
@ -1592,7 +1592,7 @@ static int tw_scsiop_mode_sense_complete(TW_Device_Extension *tw_dev, int reques
|
||||
} /* End tw_scsiop_mode_sense_complete() */
|
||||
|
||||
/* This function handles scsi read_capacity commands */
|
||||
static int tw_scsiop_read_capacity(TW_Device_Extension *tw_dev, int request_id)
|
||||
static int tw_scsiop_read_capacity(TW_Device_Extension *tw_dev, int request_id)
|
||||
{
|
||||
TW_Param *param;
|
||||
TW_Command *command_packet;
|
||||
@ -1624,8 +1624,8 @@ static int tw_scsiop_read_capacity(TW_Device_Extension *tw_dev, int request_id)
|
||||
}
|
||||
param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
|
||||
memset(param, 0, sizeof(TW_Sector));
|
||||
param->table_id = TW_UNIT_INFORMATION_TABLE_BASE +
|
||||
tw_dev->srb[request_id]->device->id;
|
||||
param->table_id = TW_UNIT_INFORMATION_TABLE_BASE +
|
||||
tw_dev->srb[request_id]->device->id;
|
||||
param->parameter_id = 4; /* unitcapacity parameter */
|
||||
param->parameter_size_bytes = 4;
|
||||
param_value = tw_dev->alignment_physical_address[request_id];
|
||||
@ -1633,7 +1633,7 @@ static int tw_scsiop_read_capacity(TW_Device_Extension *tw_dev, int request_id)
|
||||
dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity(): Bad alignment physical address.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
command_packet->byte8.param.sgl[0].address = param_value;
|
||||
command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
|
||||
command_que_value = tw_dev->command_packet_physical_address[request_id];
|
||||
@ -1644,7 +1644,7 @@ static int tw_scsiop_read_capacity(TW_Device_Extension *tw_dev, int request_id)
|
||||
|
||||
/* Now try to post the command to the board */
|
||||
tw_post_command_packet(tw_dev, request_id);
|
||||
|
||||
|
||||
return 0;
|
||||
} /* End tw_scsiop_read_capacity() */
|
||||
|
||||
@ -1666,7 +1666,7 @@ static int tw_scsiop_read_capacity_complete(TW_Device_Extension *tw_dev, int req
|
||||
}
|
||||
param_data = &(param->data[0]);
|
||||
|
||||
capacity = (param_data[3] << 24) | (param_data[2] << 16) |
|
||||
capacity = (param_data[3] << 24) | (param_data[2] << 16) |
|
||||
(param_data[1] << 8) | param_data[0];
|
||||
|
||||
/* Subtract one sector to fix get last sector ioctl */
|
||||
@ -1692,7 +1692,7 @@ static int tw_scsiop_read_capacity_complete(TW_Device_Extension *tw_dev, int req
|
||||
} /* End tw_scsiop_read_capacity_complete() */
|
||||
|
||||
/* This function handles scsi read or write commands */
|
||||
static int tw_scsiop_read_write(TW_Device_Extension *tw_dev, int request_id)
|
||||
static int tw_scsiop_read_write(TW_Device_Extension *tw_dev, int request_id)
|
||||
{
|
||||
TW_Command *command_packet;
|
||||
unsigned long command_que_value;
|
||||
@ -1742,12 +1742,12 @@ static int tw_scsiop_read_write(TW_Device_Extension *tw_dev, int request_id)
|
||||
lba = ((u32)srb->cmnd[2] << 24) | ((u32)srb->cmnd[3] << 16) | ((u32)srb->cmnd[4] << 8) | (u32)srb->cmnd[5];
|
||||
num_sectors = (u32)srb->cmnd[8] | ((u32)srb->cmnd[7] << 8);
|
||||
}
|
||||
|
||||
|
||||
/* Update sector statistic */
|
||||
tw_dev->sector_count = num_sectors;
|
||||
if (tw_dev->sector_count > tw_dev->max_sector_count)
|
||||
tw_dev->max_sector_count = tw_dev->sector_count;
|
||||
|
||||
|
||||
dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_write(): lba = 0x%x num_sectors = 0x%x\n", lba, num_sectors);
|
||||
command_packet->byte8.io.lba = lba;
|
||||
command_packet->byte6.block_count = num_sectors;
|
||||
@ -1772,7 +1772,7 @@ static int tw_scsiop_read_write(TW_Device_Extension *tw_dev, int request_id)
|
||||
dprintk(KERN_WARNING "3w-xxxx: tw_scsiop_read_write(): Bad command packet physical address.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* Now try to post the command to the board */
|
||||
tw_post_command_packet(tw_dev, request_id);
|
||||
|
||||
@ -1933,7 +1933,7 @@ static int tw_scsi_queue_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_c
|
||||
|
||||
/* Save done function into struct scsi_cmnd */
|
||||
SCpnt->scsi_done = done;
|
||||
|
||||
|
||||
/* Queue the command and get a request id */
|
||||
tw_state_request_start(tw_dev, &request_id);
|
||||
|
||||
@ -1941,48 +1941,47 @@ static int tw_scsi_queue_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_c
|
||||
tw_dev->srb[request_id] = SCpnt;
|
||||
|
||||
switch (*command) {
|
||||
case READ_10:
|
||||
case READ_6:
|
||||
case WRITE_10:
|
||||
case WRITE_6:
|
||||
dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught READ/WRITE.\n");
|
||||
retval = tw_scsiop_read_write(tw_dev, request_id);
|
||||
break;
|
||||
case TEST_UNIT_READY:
|
||||
dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught TEST_UNIT_READY.\n");
|
||||
retval = tw_scsiop_test_unit_ready(tw_dev, request_id);
|
||||
break;
|
||||
case INQUIRY:
|
||||
dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught INQUIRY.\n");
|
||||
retval = tw_scsiop_inquiry(tw_dev, request_id);
|
||||
break;
|
||||
case READ_CAPACITY:
|
||||
dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught READ_CAPACITY.\n");
|
||||
retval = tw_scsiop_read_capacity(tw_dev, request_id);
|
||||
break;
|
||||
case REQUEST_SENSE:
|
||||
dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught REQUEST_SENSE.\n");
|
||||
retval = tw_scsiop_request_sense(tw_dev, request_id);
|
||||
break;
|
||||
case MODE_SENSE:
|
||||
dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught MODE_SENSE.\n");
|
||||
retval = tw_scsiop_mode_sense(tw_dev, request_id);
|
||||
break;
|
||||
case SYNCHRONIZE_CACHE:
|
||||
dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught SYNCHRONIZE_CACHE.\n");
|
||||
retval = tw_scsiop_synchronize_cache(tw_dev, request_id);
|
||||
break;
|
||||
case TW_IOCTL:
|
||||
printk(KERN_WARNING "3w-xxxx: SCSI_IOCTL_SEND_COMMAND deprecated, please update your 3ware tools.\n");
|
||||
break;
|
||||
default:
|
||||
printk(KERN_NOTICE "3w-xxxx: scsi%d: Unknown scsi opcode: 0x%x\n", tw_dev->host->host_no, *command);
|
||||
tw_dev->state[request_id] = TW_S_COMPLETED;
|
||||
tw_state_request_finish(tw_dev, request_id);
|
||||
SCpnt->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION;
|
||||
scsi_build_sense_buffer(1, SCpnt->sense_buffer, ILLEGAL_REQUEST, 0x20, 0);
|
||||
done(SCpnt);
|
||||
retval = 0;
|
||||
case READ_10:
|
||||
case READ_6:
|
||||
case WRITE_10:
|
||||
case WRITE_6:
|
||||
dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught READ/WRITE.\n");
|
||||
retval = tw_scsiop_read_write(tw_dev, request_id);
|
||||
break;
|
||||
case TEST_UNIT_READY:
|
||||
dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught TEST_UNIT_READY.\n");
|
||||
retval = tw_scsiop_test_unit_ready(tw_dev, request_id);
|
||||
break;
|
||||
case INQUIRY:
|
||||
dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught INQUIRY.\n");
|
||||
retval = tw_scsiop_inquiry(tw_dev, request_id);
|
||||
break;
|
||||
case READ_CAPACITY:
|
||||
dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught READ_CAPACITY.\n");
|
||||
retval = tw_scsiop_read_capacity(tw_dev, request_id);
|
||||
break;
|
||||
case REQUEST_SENSE:
|
||||
dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught REQUEST_SENSE.\n");
|
||||
retval = tw_scsiop_request_sense(tw_dev, request_id);
|
||||
break;
|
||||
case MODE_SENSE:
|
||||
dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught MODE_SENSE.\n");
|
||||
retval = tw_scsiop_mode_sense(tw_dev, request_id);
|
||||
break;
|
||||
case SYNCHRONIZE_CACHE:
|
||||
dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught SYNCHRONIZE_CACHE.\n");
|
||||
retval = tw_scsiop_synchronize_cache(tw_dev, request_id);
|
||||
break;
|
||||
case TW_IOCTL:
|
||||
printk(KERN_WARNING "3w-xxxx: SCSI_IOCTL_SEND_COMMAND deprecated, please update your 3ware tools.\n");
|
||||
break;
|
||||
default:
|
||||
printk(KERN_NOTICE "3w-xxxx: scsi%d: Unknown scsi opcode: 0x%x\n", tw_dev->host->host_no, *command);
|
||||
tw_dev->state[request_id] = TW_S_COMPLETED;
|
||||
tw_state_request_finish(tw_dev, request_id);
|
||||
scsi_build_sense_buffer(1, SCpnt->sense_buffer, ILLEGAL_REQUEST, 0x20, 0);
|
||||
done(SCpnt);
|
||||
retval = 0;
|
||||
}
|
||||
if (retval) {
|
||||
tw_dev->state[request_id] = TW_S_COMPLETED;
|
||||
@ -1997,7 +1996,7 @@ static int tw_scsi_queue_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_c
|
||||
static DEF_SCSI_QCMD(tw_scsi_queue)
|
||||
|
||||
/* This function is the interrupt service routine */
|
||||
static irqreturn_t tw_interrupt(int irq, void *dev_instance)
|
||||
static irqreturn_t tw_interrupt(int irq, void *dev_instance)
|
||||
{
|
||||
int request_id;
|
||||
u32 status_reg_value;
|
||||
@ -2073,7 +2072,7 @@ static irqreturn_t tw_interrupt(int irq, void *dev_instance)
|
||||
}
|
||||
}
|
||||
/* If there are no more pending requests, we mask command interrupt */
|
||||
if (tw_dev->pending_request_count == 0)
|
||||
if (tw_dev->pending_request_count == 0)
|
||||
TW_MASK_COMMAND_INTERRUPT(tw_dev);
|
||||
}
|
||||
|
||||
@ -2174,7 +2173,7 @@ static irqreturn_t tw_interrupt(int irq, void *dev_instance)
|
||||
tw_dev->posted_request_count--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Check for valid status after each drain */
|
||||
status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev));
|
||||
if (tw_check_bits(status_reg_value)) {
|
||||
@ -2244,7 +2243,7 @@ static struct scsi_host_template driver_template = {
|
||||
.this_id = -1,
|
||||
.sg_tablesize = TW_MAX_SGL_LENGTH,
|
||||
.max_sectors = TW_MAX_SECTORS,
|
||||
.cmd_per_lun = TW_MAX_CMDS_PER_LUN,
|
||||
.cmd_per_lun = TW_MAX_CMDS_PER_LUN,
|
||||
.shost_attrs = tw_host_attrs,
|
||||
.emulated = 1,
|
||||
.no_write_same = 1,
|
||||
|
@ -1,9 +1,9 @@
|
||||
/*
|
||||
/*
|
||||
3w-xxxx.h -- 3ware Storage Controller device driver for Linux.
|
||||
|
||||
|
||||
Written By: Adam Radford <aradford@gmail.com>
|
||||
Modifications By: Joel Jacobson <linux@3ware.com>
|
||||
Arnaldo Carvalho de Melo <acme@conectiva.com.br>
|
||||
Arnaldo Carvalho de Melo <acme@conectiva.com.br>
|
||||
Brad Strand <linux@3ware.com>
|
||||
|
||||
Copyright (C) 1999-2010 3ware Inc.
|
||||
@ -15,39 +15,39 @@
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
NO WARRANTY
|
||||
THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
|
||||
LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
|
||||
solely responsible for determining the appropriateness of using and
|
||||
distributing the Program and assumes all risks associated with its
|
||||
exercise of rights under this Agreement, including but not limited to
|
||||
the risks and costs of program errors, damage to or loss of data,
|
||||
programs or equipment, and unavailability or interruption of operations.
|
||||
NO WARRANTY
|
||||
THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
|
||||
LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
|
||||
solely responsible for determining the appropriateness of using and
|
||||
distributing the Program and assumes all risks associated with its
|
||||
exercise of rights under this Agreement, including but not limited to
|
||||
the risks and costs of program errors, damage to or loss of data,
|
||||
programs or equipment, and unavailability or interruption of operations.
|
||||
|
||||
DISCLAIMER OF LIABILITY
|
||||
NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
|
||||
HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
|
||||
DISCLAIMER OF LIABILITY
|
||||
NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
|
||||
HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
Bugs/Comments/Suggestions should be mailed to:
|
||||
Bugs/Comments/Suggestions should be mailed to:
|
||||
|
||||
aradford@gmail.com
|
||||
|
||||
|
||||
For more information, goto:
|
||||
http://www.lsi.com
|
||||
*/
|
||||
@ -99,21 +99,21 @@ static char *tw_aen_string[] = {
|
||||
static unsigned char tw_sense_table[][4] =
|
||||
{
|
||||
/* Codes for newer firmware */
|
||||
// ATA Error SCSI Error
|
||||
{0x01, 0x03, 0x13, 0x00}, // Address mark not found Address mark not found for data field
|
||||
{0x04, 0x0b, 0x00, 0x00}, // Aborted command Aborted command
|
||||
{0x10, 0x0b, 0x14, 0x00}, // ID not found Recorded entity not found
|
||||
{0x40, 0x03, 0x11, 0x00}, // Uncorrectable ECC error Unrecovered read error
|
||||
{0x61, 0x04, 0x00, 0x00}, // Device fault Hardware error
|
||||
{0x84, 0x0b, 0x47, 0x00}, // Data CRC error SCSI parity error
|
||||
{0xd0, 0x0b, 0x00, 0x00}, // Device busy Aborted command
|
||||
{0xd1, 0x0b, 0x00, 0x00}, // Device busy Aborted command
|
||||
{0x37, 0x02, 0x04, 0x00}, // Unit offline Not ready
|
||||
{0x09, 0x02, 0x04, 0x00}, // Unrecovered disk error Not ready
|
||||
// ATA Error SCSI Error
|
||||
{0x01, 0x03, 0x13, 0x00}, // Address mark not found Address mark not found for data field
|
||||
{0x04, 0x0b, 0x00, 0x00}, // Aborted command Aborted command
|
||||
{0x10, 0x0b, 0x14, 0x00}, // ID not found Recorded entity not found
|
||||
{0x40, 0x03, 0x11, 0x00}, // Uncorrectable ECC error Unrecovered read error
|
||||
{0x61, 0x04, 0x00, 0x00}, // Device fault Hardware error
|
||||
{0x84, 0x0b, 0x47, 0x00}, // Data CRC error SCSI parity error
|
||||
{0xd0, 0x0b, 0x00, 0x00}, // Device busy Aborted command
|
||||
{0xd1, 0x0b, 0x00, 0x00}, // Device busy Aborted command
|
||||
{0x37, 0x02, 0x04, 0x00}, // Unit offline Not ready
|
||||
{0x09, 0x02, 0x04, 0x00}, // Unrecovered disk error Not ready
|
||||
|
||||
/* Codes for older firmware */
|
||||
// 3ware Error SCSI Error
|
||||
{0x51, 0x0b, 0x00, 0x00} // Unspecified Aborted command
|
||||
/* Codes for older firmware */
|
||||
// 3ware Error SCSI Error
|
||||
{0x51, 0x0b, 0x00, 0x00} // Unspecified Aborted command
|
||||
};
|
||||
|
||||
/* Control register bit definitions */
|
||||
@ -128,9 +128,9 @@ static unsigned char tw_sense_table[][4] =
|
||||
#define TW_CONTROL_ENABLE_INTERRUPTS 0x00000080
|
||||
#define TW_CONTROL_DISABLE_INTERRUPTS 0x00000040
|
||||
#define TW_CONTROL_ISSUE_HOST_INTERRUPT 0x00000020
|
||||
#define TW_CONTROL_CLEAR_PARITY_ERROR 0x00800000
|
||||
#define TW_CONTROL_CLEAR_QUEUE_ERROR 0x00400000
|
||||
#define TW_CONTROL_CLEAR_PCI_ABORT 0x00100000
|
||||
#define TW_CONTROL_CLEAR_PARITY_ERROR 0x00800000
|
||||
#define TW_CONTROL_CLEAR_QUEUE_ERROR 0x00400000
|
||||
#define TW_CONTROL_CLEAR_PCI_ABORT 0x00100000
|
||||
#define TW_CONTROL_CLEAR_SBUF_WRITE_ERROR 0x00000008
|
||||
|
||||
/* Status register bit definitions */
|
||||
@ -152,8 +152,8 @@ static unsigned char tw_sense_table[][4] =
|
||||
#define TW_STATUS_CLEARABLE_BITS 0x00D00000
|
||||
#define TW_STATUS_EXPECTED_BITS 0x00002000
|
||||
#define TW_STATUS_UNEXPECTED_BITS 0x00F00008
|
||||
#define TW_STATUS_SBUF_WRITE_ERROR 0x00000008
|
||||
#define TW_STATUS_VALID_INTERRUPT 0x00DF0008
|
||||
#define TW_STATUS_SBUF_WRITE_ERROR 0x00000008
|
||||
#define TW_STATUS_VALID_INTERRUPT 0x00DF0008
|
||||
|
||||
/* RESPONSE QUEUE BIT DEFINITIONS */
|
||||
#define TW_RESPONSE_ID_MASK 0x00000FF0
|
||||
@ -179,33 +179,33 @@ static unsigned char tw_sense_table[][4] =
|
||||
#define TW_OP_SECTOR_INFO 0x1a
|
||||
#define TW_OP_AEN_LISTEN 0x1c
|
||||
#define TW_OP_FLUSH_CACHE 0x0e
|
||||
#define TW_CMD_PACKET 0x1d
|
||||
#define TW_CMD_PACKET 0x1d
|
||||
#define TW_CMD_PACKET_WITH_DATA 0x1f
|
||||
|
||||
/* Asynchronous Event Notification (AEN) Codes */
|
||||
#define TW_AEN_QUEUE_EMPTY 0x0000
|
||||
#define TW_AEN_SOFT_RESET 0x0001
|
||||
#define TW_AEN_SOFT_RESET 0x0001
|
||||
#define TW_AEN_DEGRADED_MIRROR 0x0002
|
||||
#define TW_AEN_CONTROLLER_ERROR 0x0003
|
||||
#define TW_AEN_REBUILD_FAIL 0x0004
|
||||
#define TW_AEN_REBUILD_DONE 0x0005
|
||||
#define TW_AEN_QUEUE_FULL 0x00ff
|
||||
#define TW_AEN_QUEUE_FULL 0x00ff
|
||||
#define TW_AEN_TABLE_UNDEFINED 0x15
|
||||
#define TW_AEN_APORT_TIMEOUT 0x0009
|
||||
#define TW_AEN_DRIVE_ERROR 0x000A
|
||||
#define TW_AEN_SMART_FAIL 0x000F
|
||||
#define TW_AEN_SBUF_FAIL 0x0024
|
||||
#define TW_AEN_SMART_FAIL 0x000F
|
||||
#define TW_AEN_SBUF_FAIL 0x0024
|
||||
|
||||
/* Misc defines */
|
||||
#define TW_ALIGNMENT_6000 64 /* 64 bytes */
|
||||
#define TW_ALIGNMENT_7000 4 /* 4 bytes */
|
||||
#define TW_ALIGNMENT_7000 4 /* 4 bytes */
|
||||
#define TW_MAX_UNITS 16
|
||||
#define TW_COMMAND_ALIGNMENT_MASK 0x1ff
|
||||
#define TW_INIT_MESSAGE_CREDITS 0x100
|
||||
#define TW_INIT_COMMAND_PACKET_SIZE 0x3
|
||||
#define TW_POLL_MAX_RETRIES 20000
|
||||
#define TW_POLL_MAX_RETRIES 20000
|
||||
#define TW_MAX_SGL_LENGTH 62
|
||||
#define TW_ATA_PASS_SGL_MAX 60
|
||||
#define TW_ATA_PASS_SGL_MAX 60
|
||||
#define TW_Q_LENGTH 256
|
||||
#define TW_Q_START 0
|
||||
#define TW_MAX_SLOT 32
|
||||
@ -216,20 +216,20 @@ static unsigned char tw_sense_table[][4] =
|
||||
chrdev ioctl, one for
|
||||
internal aen post */
|
||||
#define TW_BLOCK_SIZE 0x200 /* 512-byte blocks */
|
||||
#define TW_IOCTL 0x80
|
||||
#define TW_UNIT_ONLINE 1
|
||||
#define TW_IN_INTR 1
|
||||
#define TW_IN_RESET 2
|
||||
#define TW_IN_CHRDEV_IOCTL 3
|
||||
#define TW_MAX_SECTORS 256
|
||||
#define TW_IOCTL 0x80
|
||||
#define TW_UNIT_ONLINE 1
|
||||
#define TW_IN_INTR 1
|
||||
#define TW_IN_RESET 2
|
||||
#define TW_IN_CHRDEV_IOCTL 3
|
||||
#define TW_MAX_SECTORS 256
|
||||
#define TW_MAX_IOCTL_SECTORS 512
|
||||
#define TW_AEN_WAIT_TIME 1000
|
||||
#define TW_IOCTL_WAIT_TIME (1 * HZ) /* 1 second */
|
||||
#define TW_ISR_DONT_COMPLETE 2
|
||||
#define TW_ISR_DONT_RESULT 3
|
||||
#define TW_IOCTL_TIMEOUT 25 /* 25 seconds */
|
||||
#define TW_IOCTL_CHRDEV_TIMEOUT 60 /* 60 seconds */
|
||||
#define TW_IOCTL_CHRDEV_FREE -1
|
||||
#define TW_AEN_WAIT_TIME 1000
|
||||
#define TW_IOCTL_WAIT_TIME (1 * HZ) /* 1 second */
|
||||
#define TW_ISR_DONT_COMPLETE 2
|
||||
#define TW_ISR_DONT_RESULT 3
|
||||
#define TW_IOCTL_TIMEOUT 25 /* 25 seconds */
|
||||
#define TW_IOCTL_CHRDEV_TIMEOUT 60 /* 60 seconds */
|
||||
#define TW_IOCTL_CHRDEV_FREE -1
|
||||
#define TW_MAX_CDB_LEN 16
|
||||
|
||||
/* Bitmask macros to eliminate bitfields */
|
||||
@ -250,26 +250,35 @@ static unsigned char tw_sense_table[][4] =
|
||||
#define TW_STATUS_REG_ADDR(x) (x->base_addr + 0x4)
|
||||
#define TW_COMMAND_QUEUE_REG_ADDR(x) (x->base_addr + 0x8)
|
||||
#define TW_RESPONSE_QUEUE_REG_ADDR(x) (x->base_addr + 0xC)
|
||||
#define TW_CLEAR_ALL_INTERRUPTS(x) (outl(TW_STATUS_VALID_INTERRUPT, TW_CONTROL_REG_ADDR(x)))
|
||||
#define TW_CLEAR_ATTENTION_INTERRUPT(x) (outl(TW_CONTROL_CLEAR_ATTENTION_INTERRUPT, TW_CONTROL_REG_ADDR(x)))
|
||||
#define TW_CLEAR_HOST_INTERRUPT(x) (outl(TW_CONTROL_CLEAR_HOST_INTERRUPT, TW_CONTROL_REG_ADDR(x)))
|
||||
#define TW_DISABLE_INTERRUPTS(x) (outl(TW_CONTROL_DISABLE_INTERRUPTS, TW_CONTROL_REG_ADDR(x)))
|
||||
#define TW_ENABLE_AND_CLEAR_INTERRUPTS(x) (outl(TW_CONTROL_CLEAR_ATTENTION_INTERRUPT | TW_CONTROL_UNMASK_RESPONSE_INTERRUPT | TW_CONTROL_ENABLE_INTERRUPTS, TW_CONTROL_REG_ADDR(x)))
|
||||
#define TW_MASK_COMMAND_INTERRUPT(x) (outl(TW_CONTROL_MASK_COMMAND_INTERRUPT, TW_CONTROL_REG_ADDR(x)))
|
||||
#define TW_UNMASK_COMMAND_INTERRUPT(x) (outl(TW_CONTROL_UNMASK_COMMAND_INTERRUPT, TW_CONTROL_REG_ADDR(x)))
|
||||
#define TW_SOFT_RESET(x) (outl(TW_CONTROL_ISSUE_SOFT_RESET | \
|
||||
TW_CONTROL_CLEAR_HOST_INTERRUPT | \
|
||||
TW_CONTROL_CLEAR_ATTENTION_INTERRUPT | \
|
||||
TW_CONTROL_MASK_COMMAND_INTERRUPT | \
|
||||
TW_CONTROL_MASK_RESPONSE_INTERRUPT | \
|
||||
TW_CONTROL_CLEAR_ERROR_STATUS | \
|
||||
TW_CONTROL_DISABLE_INTERRUPTS, TW_CONTROL_REG_ADDR(x)))
|
||||
#define TW_STATUS_ERRORS(x) \
|
||||
(((x & TW_STATUS_PCI_ABORT) || \
|
||||
(x & TW_STATUS_PCI_PARITY_ERROR) || \
|
||||
(x & TW_STATUS_QUEUE_ERROR) || \
|
||||
(x & TW_STATUS_MICROCONTROLLER_ERROR)) && \
|
||||
(x & TW_STATUS_MICROCONTROLLER_READY))
|
||||
#define TW_CLEAR_ALL_INTERRUPTS(x) \
|
||||
(outl(TW_STATUS_VALID_INTERRUPT, TW_CONTROL_REG_ADDR(x)))
|
||||
#define TW_CLEAR_ATTENTION_INTERRUPT(x) \
|
||||
(outl(TW_CONTROL_CLEAR_ATTENTION_INTERRUPT, TW_CONTROL_REG_ADDR(x)))
|
||||
#define TW_CLEAR_HOST_INTERRUPT(x) \
|
||||
(outl(TW_CONTROL_CLEAR_HOST_INTERRUPT, TW_CONTROL_REG_ADDR(x)))
|
||||
#define TW_DISABLE_INTERRUPTS(x) \
|
||||
(outl(TW_CONTROL_DISABLE_INTERRUPTS, TW_CONTROL_REG_ADDR(x)))
|
||||
#define TW_ENABLE_AND_CLEAR_INTERRUPTS(x) \
|
||||
(outl(TW_CONTROL_CLEAR_ATTENTION_INTERRUPT | \
|
||||
TW_CONTROL_UNMASK_RESPONSE_INTERRUPT | \
|
||||
TW_CONTROL_ENABLE_INTERRUPTS, TW_CONTROL_REG_ADDR(x)))
|
||||
#define TW_MASK_COMMAND_INTERRUPT(x) \
|
||||
(outl(TW_CONTROL_MASK_COMMAND_INTERRUPT, TW_CONTROL_REG_ADDR(x)))
|
||||
#define TW_UNMASK_COMMAND_INTERRUPT(x) \
|
||||
(outl(TW_CONTROL_UNMASK_COMMAND_INTERRUPT, TW_CONTROL_REG_ADDR(x)))
|
||||
#define TW_SOFT_RESET(x) (outl(TW_CONTROL_ISSUE_SOFT_RESET | \
|
||||
TW_CONTROL_CLEAR_HOST_INTERRUPT | \
|
||||
TW_CONTROL_CLEAR_ATTENTION_INTERRUPT | \
|
||||
TW_CONTROL_MASK_COMMAND_INTERRUPT | \
|
||||
TW_CONTROL_MASK_RESPONSE_INTERRUPT | \
|
||||
TW_CONTROL_CLEAR_ERROR_STATUS | \
|
||||
TW_CONTROL_DISABLE_INTERRUPTS, TW_CONTROL_REG_ADDR(x)))
|
||||
#define TW_STATUS_ERRORS(x) \
|
||||
(((x & TW_STATUS_PCI_ABORT) || \
|
||||
(x & TW_STATUS_PCI_PARITY_ERROR) || \
|
||||
(x & TW_STATUS_QUEUE_ERROR) || \
|
||||
(x & TW_STATUS_MICROCONTROLLER_ERROR)) && \
|
||||
(x & TW_STATUS_MICROCONTROLLER_READY))
|
||||
|
||||
#ifdef TW_DEBUG
|
||||
#define dprintk(msg...) printk(msg)
|
||||
|
@ -669,20 +669,6 @@ config SCSI_FDOMAIN_ISA
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called fdomain_isa.
|
||||
|
||||
config SCSI_GDTH
|
||||
tristate "Intel/ICP (former GDT SCSI Disk Array) RAID Controller support"
|
||||
depends on PCI && SCSI
|
||||
help
|
||||
Formerly called GDT SCSI Disk Array Controller Support.
|
||||
|
||||
This is a driver for RAID/SCSI Disk Array Controllers (EISA/ISA/PCI)
|
||||
manufactured by Intel Corporation/ICP vortex GmbH. It is documented
|
||||
in the kernel source in <file:drivers/scsi/gdth.c> and
|
||||
<file:drivers/scsi/gdth.h>.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called gdth.
|
||||
|
||||
config SCSI_ISCI
|
||||
tristate "Intel(R) C600 Series Chipset SAS Controller"
|
||||
depends on PCI && SCSI
|
||||
@ -1159,6 +1145,7 @@ config SCSI_LPFC
|
||||
depends on NVME_TARGET_FC || NVME_TARGET_FC=n
|
||||
depends on NVME_FC || NVME_FC=n
|
||||
select CRC_T10DIF
|
||||
select IRQ_POLL
|
||||
help
|
||||
This lpfc driver supports the Emulex LightPulse
|
||||
Family of Fibre Channel PCI host adapters.
|
||||
@ -1182,6 +1169,7 @@ config SCSI_SIM710
|
||||
config SCSI_DC395x
|
||||
tristate "Tekram DC395(U/UW/F) and DC315(U) SCSI support"
|
||||
depends on PCI && SCSI
|
||||
select SCSI_SPI_ATTRS
|
||||
help
|
||||
This driver supports PCI SCSI host adapters based on the ASIC
|
||||
TRM-S1040 chip, e.g Tekram DC395(U/UW/F) and DC315(U) variants.
|
||||
|
@ -16,7 +16,6 @@
|
||||
|
||||
|
||||
CFLAGS_aha152x.o = -DAHA152X_STAT -DAUTOCONF
|
||||
CFLAGS_gdth.o = # -DDEBUG_GDTH=2 -D__SERIAL__ -D__COM2__ -DGDTH_STATISTICS
|
||||
|
||||
obj-$(CONFIG_PCMCIA) += pcmcia/
|
||||
|
||||
@ -103,7 +102,6 @@ obj-$(CONFIG_SCSI_MPT3SAS) += mpt3sas/
|
||||
obj-$(CONFIG_SCSI_UFSHCD) += ufs/
|
||||
obj-$(CONFIG_SCSI_ACARD) += atp870u.o
|
||||
obj-$(CONFIG_SCSI_SUNESP) += esp_scsi.o sun_esp.o
|
||||
obj-$(CONFIG_SCSI_GDTH) += gdth.o
|
||||
obj-$(CONFIG_SCSI_INITIO) += initio.o
|
||||
obj-$(CONFIG_SCSI_INIA100) += a100u2w.o
|
||||
obj-$(CONFIG_SCSI_QLOGICPTI) += qlogicpti.o
|
||||
|
@ -556,7 +556,7 @@ static void get_container_name_callback(void *context, struct fib * fibptr)
|
||||
}
|
||||
}
|
||||
|
||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
|
||||
scsicmd->result = DID_OK << 16 | SAM_STAT_GOOD;
|
||||
|
||||
aac_fib_complete(fibptr);
|
||||
scsicmd->scsi_done(scsicmd);
|
||||
@ -1092,7 +1092,7 @@ static void get_container_serial_callback(void *context, struct fib * fibptr)
|
||||
}
|
||||
}
|
||||
|
||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
|
||||
scsicmd->result = DID_OK << 16 | SAM_STAT_GOOD;
|
||||
|
||||
aac_fib_complete(fibptr);
|
||||
scsicmd->scsi_done(scsicmd);
|
||||
@ -1191,8 +1191,7 @@ static int aac_bounds_32(struct aac_dev * dev, struct scsi_cmnd * cmd, u64 lba)
|
||||
if (lba & 0xffffffff00000000LL) {
|
||||
int cid = scmd_id(cmd);
|
||||
dprintk((KERN_DEBUG "aacraid: Illegal lba\n"));
|
||||
cmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
|
||||
SAM_STAT_CHECK_CONDITION;
|
||||
cmd->result = DID_OK << 16 | SAM_STAT_CHECK_CONDITION;
|
||||
set_sense(&dev->fsa_dev[cid].sense_data,
|
||||
HARDWARE_ERROR, SENCODE_INTERNAL_TARGET_FAILURE,
|
||||
ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0);
|
||||
@ -2364,13 +2363,11 @@ static void io_callback(void *context, struct fib * fibptr)
|
||||
readreply = (struct aac_read_reply *)fib_data(fibptr);
|
||||
switch (le32_to_cpu(readreply->status)) {
|
||||
case ST_OK:
|
||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
|
||||
SAM_STAT_GOOD;
|
||||
scsicmd->result = DID_OK << 16 | SAM_STAT_GOOD;
|
||||
dev->fsa_dev[cid].sense_data.sense_key = NO_SENSE;
|
||||
break;
|
||||
case ST_NOT_READY:
|
||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
|
||||
SAM_STAT_CHECK_CONDITION;
|
||||
scsicmd->result = DID_OK << 16 | SAM_STAT_CHECK_CONDITION;
|
||||
set_sense(&dev->fsa_dev[cid].sense_data, NOT_READY,
|
||||
SENCODE_BECOMING_READY, ASENCODE_BECOMING_READY, 0, 0);
|
||||
memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data,
|
||||
@ -2378,8 +2375,7 @@ static void io_callback(void *context, struct fib * fibptr)
|
||||
SCSI_SENSE_BUFFERSIZE));
|
||||
break;
|
||||
case ST_MEDERR:
|
||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
|
||||
SAM_STAT_CHECK_CONDITION;
|
||||
scsicmd->result = DID_OK << 16 | SAM_STAT_CHECK_CONDITION;
|
||||
set_sense(&dev->fsa_dev[cid].sense_data, MEDIUM_ERROR,
|
||||
SENCODE_UNRECOVERED_READ_ERROR, ASENCODE_NO_SENSE, 0, 0);
|
||||
memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data,
|
||||
@ -2391,8 +2387,7 @@ static void io_callback(void *context, struct fib * fibptr)
|
||||
printk(KERN_WARNING "io_callback: io failed, status = %d\n",
|
||||
le32_to_cpu(readreply->status));
|
||||
#endif
|
||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
|
||||
SAM_STAT_CHECK_CONDITION;
|
||||
scsicmd->result = DID_OK << 16 | SAM_STAT_CHECK_CONDITION;
|
||||
set_sense(&dev->fsa_dev[cid].sense_data,
|
||||
HARDWARE_ERROR, SENCODE_INTERNAL_TARGET_FAILURE,
|
||||
ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0);
|
||||
@ -2467,8 +2462,7 @@ static int aac_read(struct scsi_cmnd * scsicmd)
|
||||
if ((lba + count) > (dev->fsa_dev[scmd_id(scsicmd)].size)) {
|
||||
cid = scmd_id(scsicmd);
|
||||
dprintk((KERN_DEBUG "aacraid: Illegal lba\n"));
|
||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
|
||||
SAM_STAT_CHECK_CONDITION;
|
||||
scsicmd->result = DID_OK << 16 | SAM_STAT_CHECK_CONDITION;
|
||||
set_sense(&dev->fsa_dev[cid].sense_data,
|
||||
ILLEGAL_REQUEST, SENCODE_LBA_OUT_OF_RANGE,
|
||||
ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0);
|
||||
@ -2500,7 +2494,7 @@ static int aac_read(struct scsi_cmnd * scsicmd)
|
||||
/*
|
||||
* For some reason, the Fib didn't queue, return QUEUE_FULL
|
||||
*/
|
||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_TASK_SET_FULL;
|
||||
scsicmd->result = DID_OK << 16 | SAM_STAT_TASK_SET_FULL;
|
||||
scsicmd->scsi_done(scsicmd);
|
||||
aac_fib_complete(cmd_fibcontext);
|
||||
aac_fib_free(cmd_fibcontext);
|
||||
@ -2559,8 +2553,7 @@ static int aac_write(struct scsi_cmnd * scsicmd)
|
||||
if ((lba + count) > (dev->fsa_dev[scmd_id(scsicmd)].size)) {
|
||||
cid = scmd_id(scsicmd);
|
||||
dprintk((KERN_DEBUG "aacraid: Illegal lba\n"));
|
||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
|
||||
SAM_STAT_CHECK_CONDITION;
|
||||
scsicmd->result = DID_OK << 16 | SAM_STAT_CHECK_CONDITION;
|
||||
set_sense(&dev->fsa_dev[cid].sense_data,
|
||||
ILLEGAL_REQUEST, SENCODE_LBA_OUT_OF_RANGE,
|
||||
ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0);
|
||||
@ -2592,7 +2585,7 @@ static int aac_write(struct scsi_cmnd * scsicmd)
|
||||
/*
|
||||
* For some reason, the Fib didn't queue, return QUEUE_FULL
|
||||
*/
|
||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_TASK_SET_FULL;
|
||||
scsicmd->result = DID_OK << 16 | SAM_STAT_TASK_SET_FULL;
|
||||
scsicmd->scsi_done(scsicmd);
|
||||
|
||||
aac_fib_complete(cmd_fibcontext);
|
||||
@ -2615,8 +2608,7 @@ static void synchronize_callback(void *context, struct fib *fibptr)
|
||||
|
||||
synchronizereply = fib_data(fibptr);
|
||||
if (le32_to_cpu(synchronizereply->status) == CT_OK)
|
||||
cmd->result = DID_OK << 16 |
|
||||
COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
|
||||
cmd->result = DID_OK << 16 | SAM_STAT_GOOD;
|
||||
else {
|
||||
struct scsi_device *sdev = cmd->device;
|
||||
struct aac_dev *dev = fibptr->dev;
|
||||
@ -2624,8 +2616,7 @@ static void synchronize_callback(void *context, struct fib *fibptr)
|
||||
printk(KERN_WARNING
|
||||
"synchronize_callback: synchronize failed, status = %d\n",
|
||||
le32_to_cpu(synchronizereply->status));
|
||||
cmd->result = DID_OK << 16 |
|
||||
COMMAND_COMPLETE << 8 | SAM_STAT_CHECK_CONDITION;
|
||||
cmd->result = DID_OK << 16 | SAM_STAT_CHECK_CONDITION;
|
||||
set_sense(&dev->fsa_dev[cid].sense_data,
|
||||
HARDWARE_ERROR, SENCODE_INTERNAL_TARGET_FAILURE,
|
||||
ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0);
|
||||
@ -2699,7 +2690,7 @@ static void aac_start_stop_callback(void *context, struct fib *fibptr)
|
||||
|
||||
BUG_ON(fibptr == NULL);
|
||||
|
||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
|
||||
scsicmd->result = DID_OK << 16 | SAM_STAT_GOOD;
|
||||
|
||||
aac_fib_complete(fibptr);
|
||||
aac_fib_free(fibptr);
|
||||
@ -2716,8 +2707,7 @@ static int aac_start_stop(struct scsi_cmnd *scsicmd)
|
||||
|
||||
if (!(aac->supplement_adapter_info.supported_options2 &
|
||||
AAC_OPTION_POWER_MANAGEMENT)) {
|
||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
|
||||
SAM_STAT_GOOD;
|
||||
scsicmd->result = DID_OK << 16 | SAM_STAT_GOOD;
|
||||
scsicmd->scsi_done(scsicmd);
|
||||
return 0;
|
||||
}
|
||||
@ -2848,7 +2838,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
|
||||
(scsicmd->cmnd[0] != TEST_UNIT_READY))
|
||||
{
|
||||
dprintk((KERN_WARNING "Only INQUIRY & TUR command supported for controller, rcvd = 0x%x.\n", scsicmd->cmnd[0]));
|
||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_CHECK_CONDITION;
|
||||
scsicmd->result = DID_OK << 16 | SAM_STAT_CHECK_CONDITION;
|
||||
set_sense(&dev->fsa_dev[cid].sense_data,
|
||||
ILLEGAL_REQUEST, SENCODE_INVALID_COMMAND,
|
||||
ASENCODE_INVALID_COMMAND, 0, 0);
|
||||
@ -2877,8 +2867,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
|
||||
|
||||
case SYNCHRONIZE_CACHE:
|
||||
if (((aac_cache & 6) == 6) && dev->cache_protected) {
|
||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
|
||||
SAM_STAT_GOOD;
|
||||
scsicmd->result = DID_OK << 16 | SAM_STAT_GOOD;
|
||||
break;
|
||||
}
|
||||
/* Issue FIB to tell Firmware to flush it's cache */
|
||||
@ -2907,9 +2896,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
|
||||
arr[1] = scsicmd->cmnd[2];
|
||||
scsi_sg_copy_from_buffer(scsicmd, &inq_data,
|
||||
sizeof(inq_data));
|
||||
scsicmd->result = DID_OK << 16 |
|
||||
COMMAND_COMPLETE << 8 |
|
||||
SAM_STAT_GOOD;
|
||||
scsicmd->result = DID_OK << 16 | SAM_STAT_GOOD;
|
||||
} else if (scsicmd->cmnd[2] == 0x80) {
|
||||
/* unit serial number page */
|
||||
arr[3] = setinqserial(dev, &arr[4],
|
||||
@ -2920,9 +2907,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
|
||||
if (aac_wwn != 2)
|
||||
return aac_get_container_serial(
|
||||
scsicmd);
|
||||
scsicmd->result = DID_OK << 16 |
|
||||
COMMAND_COMPLETE << 8 |
|
||||
SAM_STAT_GOOD;
|
||||
scsicmd->result = DID_OK << 16 | SAM_STAT_GOOD;
|
||||
} else if (scsicmd->cmnd[2] == 0x83) {
|
||||
/* vpd page 0x83 - Device Identification Page */
|
||||
char *sno = (char *)&inq_data;
|
||||
@ -2931,14 +2916,10 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
|
||||
if (aac_wwn != 2)
|
||||
return aac_get_container_serial(
|
||||
scsicmd);
|
||||
scsicmd->result = DID_OK << 16 |
|
||||
COMMAND_COMPLETE << 8 |
|
||||
SAM_STAT_GOOD;
|
||||
scsicmd->result = DID_OK << 16 | SAM_STAT_GOOD;
|
||||
} else {
|
||||
/* vpd page not implemented */
|
||||
scsicmd->result = DID_OK << 16 |
|
||||
COMMAND_COMPLETE << 8 |
|
||||
SAM_STAT_CHECK_CONDITION;
|
||||
scsicmd->result = DID_OK << 16 | SAM_STAT_CHECK_CONDITION;
|
||||
set_sense(&dev->fsa_dev[cid].sense_data,
|
||||
ILLEGAL_REQUEST, SENCODE_INVALID_CDB_FIELD,
|
||||
ASENCODE_NO_SENSE, 7, 2);
|
||||
@ -2964,8 +2945,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
|
||||
inq_data.inqd_pdt = INQD_PDT_PROC; /* Processor device */
|
||||
scsi_sg_copy_from_buffer(scsicmd, &inq_data,
|
||||
sizeof(inq_data));
|
||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
|
||||
SAM_STAT_GOOD;
|
||||
scsicmd->result = DID_OK << 16 | SAM_STAT_GOOD;
|
||||
break;
|
||||
}
|
||||
if (dev->in_reset)
|
||||
@ -3014,8 +2994,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
|
||||
/* Do not cache partition table for arrays */
|
||||
scsicmd->device->removable = 1;
|
||||
|
||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
|
||||
SAM_STAT_GOOD;
|
||||
scsicmd->result = DID_OK << 16 | SAM_STAT_GOOD;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -3041,8 +3020,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
|
||||
scsi_sg_copy_from_buffer(scsicmd, cp, sizeof(cp));
|
||||
/* Do not cache partition table for arrays */
|
||||
scsicmd->device->removable = 1;
|
||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
|
||||
SAM_STAT_GOOD;
|
||||
scsicmd->result = DID_OK << 16 | SAM_STAT_GOOD;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -3121,8 +3099,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
|
||||
scsi_sg_copy_from_buffer(scsicmd,
|
||||
(char *)&mpd,
|
||||
mode_buf_length);
|
||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
|
||||
SAM_STAT_GOOD;
|
||||
scsicmd->result = DID_OK << 16 | SAM_STAT_GOOD;
|
||||
break;
|
||||
}
|
||||
case MODE_SENSE_10:
|
||||
@ -3199,8 +3176,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
|
||||
(char *)&mpd10,
|
||||
mode_buf_length);
|
||||
|
||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
|
||||
SAM_STAT_GOOD;
|
||||
scsicmd->result = DID_OK << 16 | SAM_STAT_GOOD;
|
||||
break;
|
||||
}
|
||||
case REQUEST_SENSE:
|
||||
@ -3209,8 +3185,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
|
||||
sizeof(struct sense_data));
|
||||
memset(&dev->fsa_dev[cid].sense_data, 0,
|
||||
sizeof(struct sense_data));
|
||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
|
||||
SAM_STAT_GOOD;
|
||||
scsicmd->result = DID_OK << 16 | SAM_STAT_GOOD;
|
||||
break;
|
||||
|
||||
case ALLOW_MEDIUM_REMOVAL:
|
||||
@ -3220,16 +3195,14 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
|
||||
else
|
||||
fsa_dev_ptr[cid].locked = 0;
|
||||
|
||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
|
||||
SAM_STAT_GOOD;
|
||||
scsicmd->result = DID_OK << 16 | SAM_STAT_GOOD;
|
||||
break;
|
||||
/*
|
||||
* These commands are all No-Ops
|
||||
*/
|
||||
case TEST_UNIT_READY:
|
||||
if (fsa_dev_ptr[cid].sense_data.sense_key == NOT_READY) {
|
||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
|
||||
SAM_STAT_CHECK_CONDITION;
|
||||
scsicmd->result = DID_OK << 16 | SAM_STAT_CHECK_CONDITION;
|
||||
set_sense(&dev->fsa_dev[cid].sense_data,
|
||||
NOT_READY, SENCODE_BECOMING_READY,
|
||||
ASENCODE_BECOMING_READY, 0, 0);
|
||||
@ -3246,8 +3219,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
|
||||
case REZERO_UNIT:
|
||||
case REASSIGN_BLOCKS:
|
||||
case SEEK_10:
|
||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
|
||||
SAM_STAT_GOOD;
|
||||
scsicmd->result = DID_OK << 16 | SAM_STAT_GOOD;
|
||||
break;
|
||||
|
||||
case START_STOP:
|
||||
@ -3259,8 +3231,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
|
||||
*/
|
||||
dprintk((KERN_WARNING "Unhandled SCSI Command: 0x%x.\n",
|
||||
scsicmd->cmnd[0]));
|
||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
|
||||
SAM_STAT_CHECK_CONDITION;
|
||||
scsicmd->result = DID_OK << 16 | SAM_STAT_CHECK_CONDITION;
|
||||
set_sense(&dev->fsa_dev[cid].sense_data,
|
||||
ILLEGAL_REQUEST, SENCODE_INVALID_COMMAND,
|
||||
ASENCODE_INVALID_COMMAND, 0, 0);
|
||||
@ -3441,9 +3412,7 @@ static void aac_srb_callback(void *context, struct fib * fibptr)
|
||||
le32_to_cpu(srbreply->status));
|
||||
len = min_t(u32, le32_to_cpu(srbreply->sense_data_size),
|
||||
SCSI_SENSE_BUFFERSIZE);
|
||||
scsicmd->result = DID_ERROR << 16
|
||||
| COMMAND_COMPLETE << 8
|
||||
| SAM_STAT_CHECK_CONDITION;
|
||||
scsicmd->result = DID_ERROR << 16 | SAM_STAT_CHECK_CONDITION;
|
||||
memcpy(scsicmd->sense_buffer,
|
||||
srbreply->sense_data, len);
|
||||
}
|
||||
@ -3455,7 +3424,7 @@ static void aac_srb_callback(void *context, struct fib * fibptr)
|
||||
case SRB_STATUS_ERROR_RECOVERY:
|
||||
case SRB_STATUS_PENDING:
|
||||
case SRB_STATUS_SUCCESS:
|
||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8;
|
||||
scsicmd->result = DID_OK << 16;
|
||||
break;
|
||||
case SRB_STATUS_DATA_OVERRUN:
|
||||
switch (scsicmd->cmnd[0]) {
|
||||
@ -3472,60 +3441,52 @@ static void aac_srb_callback(void *context, struct fib * fibptr)
|
||||
pr_warn("aacraid: SCSI CMD underflow\n");
|
||||
else
|
||||
pr_warn("aacraid: SCSI CMD Data Overrun\n");
|
||||
scsicmd->result = DID_ERROR << 16
|
||||
| COMMAND_COMPLETE << 8;
|
||||
scsicmd->result = DID_ERROR << 16;
|
||||
break;
|
||||
case INQUIRY:
|
||||
scsicmd->result = DID_OK << 16
|
||||
| COMMAND_COMPLETE << 8;
|
||||
scsicmd->result = DID_OK << 16;
|
||||
break;
|
||||
default:
|
||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8;
|
||||
scsicmd->result = DID_OK << 16;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SRB_STATUS_ABORTED:
|
||||
scsicmd->result = DID_ABORT << 16 | ABORT << 8;
|
||||
scsicmd->result = DID_ABORT << 16;
|
||||
break;
|
||||
case SRB_STATUS_ABORT_FAILED:
|
||||
/*
|
||||
* Not sure about this one - but assuming the
|
||||
* hba was trying to abort for some reason
|
||||
*/
|
||||
scsicmd->result = DID_ERROR << 16 | ABORT << 8;
|
||||
scsicmd->result = DID_ERROR << 16;
|
||||
break;
|
||||
case SRB_STATUS_PARITY_ERROR:
|
||||
scsicmd->result = DID_PARITY << 16
|
||||
| MSG_PARITY_ERROR << 8;
|
||||
scsicmd->result = DID_PARITY << 16;
|
||||
break;
|
||||
case SRB_STATUS_NO_DEVICE:
|
||||
case SRB_STATUS_INVALID_PATH_ID:
|
||||
case SRB_STATUS_INVALID_TARGET_ID:
|
||||
case SRB_STATUS_INVALID_LUN:
|
||||
case SRB_STATUS_SELECTION_TIMEOUT:
|
||||
scsicmd->result = DID_NO_CONNECT << 16
|
||||
| COMMAND_COMPLETE << 8;
|
||||
scsicmd->result = DID_NO_CONNECT << 16;
|
||||
break;
|
||||
|
||||
case SRB_STATUS_COMMAND_TIMEOUT:
|
||||
case SRB_STATUS_TIMEOUT:
|
||||
scsicmd->result = DID_TIME_OUT << 16
|
||||
| COMMAND_COMPLETE << 8;
|
||||
scsicmd->result = DID_TIME_OUT << 16;
|
||||
break;
|
||||
|
||||
case SRB_STATUS_BUSY:
|
||||
scsicmd->result = DID_BUS_BUSY << 16
|
||||
| COMMAND_COMPLETE << 8;
|
||||
scsicmd->result = DID_BUS_BUSY << 16;
|
||||
break;
|
||||
|
||||
case SRB_STATUS_BUS_RESET:
|
||||
scsicmd->result = DID_RESET << 16
|
||||
| COMMAND_COMPLETE << 8;
|
||||
scsicmd->result = DID_RESET << 16;
|
||||
break;
|
||||
|
||||
case SRB_STATUS_MESSAGE_REJECTED:
|
||||
scsicmd->result = DID_ERROR << 16
|
||||
| MESSAGE_REJECT << 8;
|
||||
scsicmd->result = DID_ERROR << 16;
|
||||
break;
|
||||
case SRB_STATUS_REQUEST_FLUSHED:
|
||||
case SRB_STATUS_ERROR:
|
||||
@ -3561,19 +3522,14 @@ static void aac_srb_callback(void *context, struct fib * fibptr)
|
||||
|| (scsicmd->cmnd[0] == ATA_16)) {
|
||||
|
||||
if (scsicmd->cmnd[2] & (0x01 << 5)) {
|
||||
scsicmd->result = DID_OK << 16
|
||||
| COMMAND_COMPLETE << 8;
|
||||
break;
|
||||
scsicmd->result = DID_OK << 16;
|
||||
} else {
|
||||
scsicmd->result = DID_ERROR << 16
|
||||
| COMMAND_COMPLETE << 8;
|
||||
break;
|
||||
scsicmd->result = DID_ERROR << 16;
|
||||
}
|
||||
} else {
|
||||
scsicmd->result = DID_ERROR << 16
|
||||
| COMMAND_COMPLETE << 8;
|
||||
break;
|
||||
scsicmd->result = DID_ERROR << 16;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (le32_to_cpu(srbreply->scsi_status)
|
||||
== SAM_STAT_CHECK_CONDITION) {
|
||||
@ -3609,7 +3565,7 @@ static void hba_resp_task_complete(struct aac_dev *dev,
|
||||
|
||||
switch (err->status) {
|
||||
case SAM_STAT_GOOD:
|
||||
scsicmd->result |= DID_OK << 16 | COMMAND_COMPLETE << 8;
|
||||
scsicmd->result |= DID_OK << 16;
|
||||
break;
|
||||
case SAM_STAT_CHECK_CONDITION:
|
||||
{
|
||||
@ -3620,19 +3576,19 @@ static void hba_resp_task_complete(struct aac_dev *dev,
|
||||
if (len)
|
||||
memcpy(scsicmd->sense_buffer,
|
||||
err->sense_response_buf, len);
|
||||
scsicmd->result |= DID_OK << 16 | COMMAND_COMPLETE << 8;
|
||||
scsicmd->result |= DID_OK << 16;
|
||||
break;
|
||||
}
|
||||
case SAM_STAT_BUSY:
|
||||
scsicmd->result |= DID_BUS_BUSY << 16 | COMMAND_COMPLETE << 8;
|
||||
scsicmd->result |= DID_BUS_BUSY << 16;
|
||||
break;
|
||||
case SAM_STAT_TASK_ABORTED:
|
||||
scsicmd->result |= DID_ABORT << 16 | ABORT << 8;
|
||||
scsicmd->result |= DID_ABORT << 16;
|
||||
break;
|
||||
case SAM_STAT_RESERVATION_CONFLICT:
|
||||
case SAM_STAT_TASK_SET_FULL:
|
||||
default:
|
||||
scsicmd->result |= DID_ERROR << 16 | COMMAND_COMPLETE << 8;
|
||||
scsicmd->result |= DID_ERROR << 16;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -3652,27 +3608,26 @@ static void hba_resp_task_failure(struct aac_dev *dev,
|
||||
dev->hba_map[bus][cid].devtype = AAC_DEVTYPE_ARC_RAW;
|
||||
dev->hba_map[bus][cid].rmw_nexus = 0xffffffff;
|
||||
}
|
||||
scsicmd->result = DID_NO_CONNECT << 16 | COMMAND_COMPLETE << 8;
|
||||
scsicmd->result = DID_NO_CONNECT << 16;
|
||||
break;
|
||||
}
|
||||
case HBA_RESP_STAT_IO_ERROR:
|
||||
case HBA_RESP_STAT_NO_PATH_TO_DEVICE:
|
||||
scsicmd->result = DID_OK << 16 |
|
||||
COMMAND_COMPLETE << 8 | SAM_STAT_BUSY;
|
||||
scsicmd->result = DID_OK << 16 | SAM_STAT_BUSY;
|
||||
break;
|
||||
case HBA_RESP_STAT_IO_ABORTED:
|
||||
scsicmd->result = DID_ABORT << 16 | ABORT << 8;
|
||||
scsicmd->result = DID_ABORT << 16;
|
||||
break;
|
||||
case HBA_RESP_STAT_INVALID_DEVICE:
|
||||
scsicmd->result = DID_NO_CONNECT << 16 | COMMAND_COMPLETE << 8;
|
||||
scsicmd->result = DID_NO_CONNECT << 16;
|
||||
break;
|
||||
case HBA_RESP_STAT_UNDERRUN:
|
||||
/* UNDERRUN is OK */
|
||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8;
|
||||
scsicmd->result = DID_OK << 16;
|
||||
break;
|
||||
case HBA_RESP_STAT_OVERRUN:
|
||||
default:
|
||||
scsicmd->result = DID_ERROR << 16 | COMMAND_COMPLETE << 8;
|
||||
scsicmd->result = DID_ERROR << 16;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -3705,7 +3660,7 @@ void aac_hba_callback(void *context, struct fib *fibptr)
|
||||
|
||||
if (fibptr->flags & FIB_CONTEXT_FLAG_FASTRESP) {
|
||||
/* fast response */
|
||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8;
|
||||
scsicmd->result = DID_OK << 16;
|
||||
goto out;
|
||||
}
|
||||
|
||||
@ -3717,17 +3672,17 @@ void aac_hba_callback(void *context, struct fib *fibptr)
|
||||
hba_resp_task_failure(dev, scsicmd, err);
|
||||
break;
|
||||
case HBA_RESP_SVCRES_TMF_REJECTED:
|
||||
scsicmd->result = DID_ERROR << 16 | MESSAGE_REJECT << 8;
|
||||
scsicmd->result = DID_ERROR << 16;
|
||||
break;
|
||||
case HBA_RESP_SVCRES_TMF_LUN_INVALID:
|
||||
scsicmd->result = DID_NO_CONNECT << 16 | COMMAND_COMPLETE << 8;
|
||||
scsicmd->result = DID_NO_CONNECT << 16;
|
||||
break;
|
||||
case HBA_RESP_SVCRES_TMF_COMPLETE:
|
||||
case HBA_RESP_SVCRES_TMF_SUCCEEDED:
|
||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8;
|
||||
scsicmd->result = DID_OK << 16;
|
||||
break;
|
||||
default:
|
||||
scsicmd->result = DID_ERROR << 16 | COMMAND_COMPLETE << 8;
|
||||
scsicmd->result = DID_ERROR << 16;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -2085,12 +2085,6 @@ do { \
|
||||
#define ASC_BUSY 0
|
||||
#define ASC_ERROR (-1)
|
||||
|
||||
/* struct scsi_cmnd function return codes */
|
||||
#define STATUS_BYTE(byte) (byte)
|
||||
#define MSG_BYTE(byte) ((byte) << 8)
|
||||
#define HOST_BYTE(byte) ((byte) << 16)
|
||||
#define DRIVER_BYTE(byte) ((byte) << 24)
|
||||
|
||||
#define ASC_STATS(shost, counter) ASC_STATS_ADD(shost, counter, 1)
|
||||
#ifndef ADVANSYS_STATS
|
||||
#define ASC_STATS_ADD(shost, counter, count)
|
||||
@ -5986,10 +5980,10 @@ static void adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp)
|
||||
/*
|
||||
* 'done_status' contains the command's ending status.
|
||||
*/
|
||||
scp->result = 0;
|
||||
switch (scsiqp->done_status) {
|
||||
case QD_NO_ERROR:
|
||||
ASC_DBG(2, "QD_NO_ERROR\n");
|
||||
scp->result = 0;
|
||||
|
||||
/*
|
||||
* Check for an underrun condition.
|
||||
@ -6010,47 +6004,33 @@ static void adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp)
|
||||
ASC_DBG(2, "QD_WITH_ERROR\n");
|
||||
switch (scsiqp->host_status) {
|
||||
case QHSTA_NO_ERROR:
|
||||
set_status_byte(scp, scsiqp->scsi_status);
|
||||
if (scsiqp->scsi_status == SAM_STAT_CHECK_CONDITION) {
|
||||
ASC_DBG(2, "SAM_STAT_CHECK_CONDITION\n");
|
||||
ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
|
||||
SCSI_SENSE_BUFFERSIZE);
|
||||
/*
|
||||
* Note: The 'status_byte()' macro used by
|
||||
* target drivers defined in scsi.h shifts the
|
||||
* status byte returned by host drivers right
|
||||
* by 1 bit. This is why target drivers also
|
||||
* use right shifted status byte definitions.
|
||||
* For instance target drivers use
|
||||
* CHECK_CONDITION, defined to 0x1, instead of
|
||||
* the SCSI defined check condition value of
|
||||
* 0x2. Host drivers are supposed to return
|
||||
* the status byte as it is defined by SCSI.
|
||||
*/
|
||||
scp->result = DRIVER_BYTE(DRIVER_SENSE) |
|
||||
STATUS_BYTE(scsiqp->scsi_status);
|
||||
} else {
|
||||
scp->result = STATUS_BYTE(scsiqp->scsi_status);
|
||||
set_driver_byte(scp, DRIVER_SENSE);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Some other QHSTA error occurred. */
|
||||
ASC_DBG(1, "host_status 0x%x\n", scsiqp->host_status);
|
||||
scp->result = HOST_BYTE(DID_BAD_TARGET);
|
||||
set_host_byte(scp, DID_BAD_TARGET);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case QD_ABORTED_BY_HOST:
|
||||
ASC_DBG(1, "QD_ABORTED_BY_HOST\n");
|
||||
scp->result =
|
||||
HOST_BYTE(DID_ABORT) | STATUS_BYTE(scsiqp->scsi_status);
|
||||
set_status_byte(scp, scsiqp->scsi_status);
|
||||
set_host_byte(scp, DID_ABORT);
|
||||
break;
|
||||
|
||||
default:
|
||||
ASC_DBG(1, "done_status 0x%x\n", scsiqp->done_status);
|
||||
scp->result =
|
||||
HOST_BYTE(DID_ERROR) | STATUS_BYTE(scsiqp->scsi_status);
|
||||
set_status_byte(scp, scsiqp->scsi_status);
|
||||
set_host_byte(scp, DID_ERROR);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -6752,10 +6732,10 @@ static void asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep)
|
||||
/*
|
||||
* 'qdonep' contains the command's ending status.
|
||||
*/
|
||||
scp->result = 0;
|
||||
switch (qdonep->d3.done_stat) {
|
||||
case QD_NO_ERROR:
|
||||
ASC_DBG(2, "QD_NO_ERROR\n");
|
||||
scp->result = 0;
|
||||
|
||||
/*
|
||||
* Check for an underrun condition.
|
||||
@ -6775,51 +6755,35 @@ static void asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep)
|
||||
ASC_DBG(2, "QD_WITH_ERROR\n");
|
||||
switch (qdonep->d3.host_stat) {
|
||||
case QHSTA_NO_ERROR:
|
||||
set_status_byte(scp, qdonep->d3.scsi_stat);
|
||||
if (qdonep->d3.scsi_stat == SAM_STAT_CHECK_CONDITION) {
|
||||
ASC_DBG(2, "SAM_STAT_CHECK_CONDITION\n");
|
||||
ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
|
||||
SCSI_SENSE_BUFFERSIZE);
|
||||
/*
|
||||
* Note: The 'status_byte()' macro used by
|
||||
* target drivers defined in scsi.h shifts the
|
||||
* status byte returned by host drivers right
|
||||
* by 1 bit. This is why target drivers also
|
||||
* use right shifted status byte definitions.
|
||||
* For instance target drivers use
|
||||
* CHECK_CONDITION, defined to 0x1, instead of
|
||||
* the SCSI defined check condition value of
|
||||
* 0x2. Host drivers are supposed to return
|
||||
* the status byte as it is defined by SCSI.
|
||||
*/
|
||||
scp->result = DRIVER_BYTE(DRIVER_SENSE) |
|
||||
STATUS_BYTE(qdonep->d3.scsi_stat);
|
||||
} else {
|
||||
scp->result = STATUS_BYTE(qdonep->d3.scsi_stat);
|
||||
set_driver_byte(scp, DRIVER_SENSE);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
/* QHSTA error occurred */
|
||||
ASC_DBG(1, "host_stat 0x%x\n", qdonep->d3.host_stat);
|
||||
scp->result = HOST_BYTE(DID_BAD_TARGET);
|
||||
set_host_byte(scp, DID_BAD_TARGET);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case QD_ABORTED_BY_HOST:
|
||||
ASC_DBG(1, "QD_ABORTED_BY_HOST\n");
|
||||
scp->result =
|
||||
HOST_BYTE(DID_ABORT) | MSG_BYTE(qdonep->d3.
|
||||
scsi_msg) |
|
||||
STATUS_BYTE(qdonep->d3.scsi_stat);
|
||||
set_status_byte(scp, qdonep->d3.scsi_stat);
|
||||
set_msg_byte(scp, qdonep->d3.scsi_msg);
|
||||
set_host_byte(scp, DID_ABORT);
|
||||
break;
|
||||
|
||||
default:
|
||||
ASC_DBG(1, "done_stat 0x%x\n", qdonep->d3.done_stat);
|
||||
scp->result =
|
||||
HOST_BYTE(DID_ERROR) | MSG_BYTE(qdonep->d3.
|
||||
scsi_msg) |
|
||||
STATUS_BYTE(qdonep->d3.scsi_stat);
|
||||
set_status_byte(scp, qdonep->d3.scsi_stat);
|
||||
set_msg_byte(scp, qdonep->d3.scsi_msg);
|
||||
set_host_byte(scp, DID_ERROR);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -7558,7 +7522,7 @@ static int asc_build_req(struct asc_board *boardp, struct scsi_cmnd *scp,
|
||||
"sg_tablesize %d\n", use_sg,
|
||||
scp->device->host->sg_tablesize);
|
||||
scsi_dma_unmap(scp);
|
||||
scp->result = HOST_BYTE(DID_ERROR);
|
||||
set_host_byte(scp, DID_ERROR);
|
||||
return ASC_ERROR;
|
||||
}
|
||||
|
||||
@ -7566,7 +7530,7 @@ static int asc_build_req(struct asc_board *boardp, struct scsi_cmnd *scp,
|
||||
use_sg * sizeof(struct asc_sg_list), GFP_ATOMIC);
|
||||
if (!asc_sg_head) {
|
||||
scsi_dma_unmap(scp);
|
||||
scp->result = HOST_BYTE(DID_SOFT_ERROR);
|
||||
set_host_byte(scp, DID_SOFT_ERROR);
|
||||
return ASC_ERROR;
|
||||
}
|
||||
|
||||
@ -7809,7 +7773,7 @@ adv_build_req(struct asc_board *boardp, struct scsi_cmnd *scp,
|
||||
"ADV_MAX_SG_LIST %d\n", use_sg,
|
||||
scp->device->host->sg_tablesize);
|
||||
scsi_dma_unmap(scp);
|
||||
scp->result = HOST_BYTE(DID_ERROR);
|
||||
set_host_byte(scp, DID_ERROR);
|
||||
reqp->cmndp = NULL;
|
||||
scp->host_scribble = NULL;
|
||||
|
||||
@ -7821,7 +7785,7 @@ adv_build_req(struct asc_board *boardp, struct scsi_cmnd *scp,
|
||||
ret = adv_get_sglist(boardp, reqp, scsiqp, scp, use_sg);
|
||||
if (ret != ADV_SUCCESS) {
|
||||
scsi_dma_unmap(scp);
|
||||
scp->result = HOST_BYTE(DID_ERROR);
|
||||
set_host_byte(scp, DID_ERROR);
|
||||
reqp->cmndp = NULL;
|
||||
scp->host_scribble = NULL;
|
||||
|
||||
@ -8518,13 +8482,13 @@ static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp)
|
||||
scmd_printk(KERN_ERR, scp, "ExeScsiQueue() ASC_ERROR, "
|
||||
"err_code 0x%x\n", err_code);
|
||||
ASC_STATS(scp->device->host, exe_error);
|
||||
scp->result = HOST_BYTE(DID_ERROR);
|
||||
set_host_byte(scp, DID_ERROR);
|
||||
break;
|
||||
default:
|
||||
scmd_printk(KERN_ERR, scp, "ExeScsiQueue() unknown, "
|
||||
"err_code 0x%x\n", err_code);
|
||||
ASC_STATS(scp->device->host, exe_unknown);
|
||||
scp->result = HOST_BYTE(DID_ERROR);
|
||||
set_host_byte(scp, DID_ERROR);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -119,8 +119,10 @@ static int aha1542_out(unsigned int base, u8 *buf, int len)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Only used at boot time, so we do not need to worry about latency as much
|
||||
here */
|
||||
/*
|
||||
* Only used at boot time, so we do not need to worry about latency as much
|
||||
* here
|
||||
*/
|
||||
|
||||
static int aha1542_in(unsigned int base, u8 *buf, int len, int timeout)
|
||||
{
|
||||
@ -142,35 +144,43 @@ static int makecode(unsigned hosterr, unsigned scsierr)
|
||||
break;
|
||||
|
||||
case 0x11: /* Selection time out-The initiator selection or target
|
||||
reselection was not complete within the SCSI Time out period */
|
||||
* reselection was not complete within the SCSI Time out period
|
||||
*/
|
||||
hosterr = DID_TIME_OUT;
|
||||
break;
|
||||
|
||||
case 0x12: /* Data overrun/underrun-The target attempted to transfer more data
|
||||
than was allocated by the Data Length field or the sum of the
|
||||
Scatter / Gather Data Length fields. */
|
||||
* than was allocated by the Data Length field or the sum of the
|
||||
* Scatter / Gather Data Length fields.
|
||||
*/
|
||||
|
||||
case 0x13: /* Unexpected bus free-The target dropped the SCSI BSY at an unexpected time. */
|
||||
|
||||
case 0x15: /* MBO command was not 00, 01 or 02-The first byte of the CB was
|
||||
invalid. This usually indicates a software failure. */
|
||||
* invalid. This usually indicates a software failure.
|
||||
*/
|
||||
|
||||
case 0x16: /* Invalid CCB Operation Code-The first byte of the CCB was invalid.
|
||||
This usually indicates a software failure. */
|
||||
* This usually indicates a software failure.
|
||||
*/
|
||||
|
||||
case 0x17: /* Linked CCB does not have the same LUN-A subsequent CCB of a set
|
||||
of linked CCB's does not specify the same logical unit number as
|
||||
the first. */
|
||||
* of linked CCB's does not specify the same logical unit number as
|
||||
* the first.
|
||||
*/
|
||||
case 0x18: /* Invalid Target Direction received from Host-The direction of a
|
||||
Target Mode CCB was invalid. */
|
||||
* Target Mode CCB was invalid.
|
||||
*/
|
||||
|
||||
case 0x19: /* Duplicate CCB Received in Target Mode-More than once CCB was
|
||||
received to service data transfer between the same target LUN
|
||||
and initiator SCSI ID in the same direction. */
|
||||
* received to service data transfer between the same target LUN
|
||||
* and initiator SCSI ID in the same direction.
|
||||
*/
|
||||
|
||||
case 0x1a: /* Invalid CCB or Segment List Parameter-A segment list with a zero
|
||||
length segment or invalid segment list boundaries was received.
|
||||
A CCB parameter was invalid. */
|
||||
* length segment or invalid segment list boundaries was received.
|
||||
* A CCB parameter was invalid.
|
||||
*/
|
||||
#ifdef DEBUG
|
||||
printk("Aha1542: %x %x\n", hosterr, scsierr);
|
||||
#endif
|
||||
@ -178,9 +188,10 @@ static int makecode(unsigned hosterr, unsigned scsierr)
|
||||
break;
|
||||
|
||||
case 0x14: /* Target bus phase sequence failure-An invalid bus phase or bus
|
||||
phase sequence was requested by the target. The host adapter
|
||||
will generate a SCSI Reset Condition, notifying the host with
|
||||
a SCRD interrupt */
|
||||
* phase sequence was requested by the target. The host adapter
|
||||
* will generate a SCSI Reset Condition, notifying the host with
|
||||
* a SCRD interrupt
|
||||
*/
|
||||
hosterr = DID_RESET;
|
||||
break;
|
||||
default:
|
||||
@ -216,8 +227,10 @@ static int aha1542_test_port(struct Scsi_Host *sh)
|
||||
if (inb(INTRFLAGS(sh->io_port)) & INTRMASK)
|
||||
return 0;
|
||||
|
||||
/* Perform a host adapter inquiry instead so we do not need to set
|
||||
up the mailboxes ahead of time */
|
||||
/*
|
||||
* Perform a host adapter inquiry instead so we do not need to set
|
||||
* up the mailboxes ahead of time
|
||||
*/
|
||||
|
||||
aha1542_outb(sh->io_port, CMD_INQUIRY);
|
||||
|
||||
@ -292,10 +305,12 @@ static irqreturn_t aha1542_interrupt(int irq, void *dev_id)
|
||||
while (1) {
|
||||
flag = inb(INTRFLAGS(sh->io_port));
|
||||
|
||||
/* Check for unusual interrupts. If any of these happen, we should
|
||||
probably do something special, but for now just printing a message
|
||||
is sufficient. A SCSI reset detected is something that we really
|
||||
need to deal with in some way. */
|
||||
/*
|
||||
* Check for unusual interrupts. If any of these happen, we should
|
||||
* probably do something special, but for now just printing a message
|
||||
* is sufficient. A SCSI reset detected is something that we really
|
||||
* need to deal with in some way.
|
||||
*/
|
||||
if (flag & ~MBIF) {
|
||||
if (flag & MBOA)
|
||||
printk("MBOF ");
|
||||
@ -355,9 +370,11 @@ static irqreturn_t aha1542_interrupt(int irq, void *dev_id)
|
||||
}
|
||||
my_done = tmp_cmd->scsi_done;
|
||||
aha1542_free_cmd(tmp_cmd);
|
||||
/* Fetch the sense data, and tuck it away, in the required slot. The
|
||||
Adaptec automatically fetches it, and there is no guarantee that
|
||||
we will still have it in the cdb when we come back */
|
||||
/*
|
||||
* Fetch the sense data, and tuck it away, in the required slot. The
|
||||
* Adaptec automatically fetches it, and there is no guarantee that
|
||||
* we will still have it in the cdb when we come back
|
||||
*/
|
||||
if (ccb[mbo].tarstat == 2)
|
||||
memcpy(tmp_cmd->sense_buffer, &ccb[mbo].cdb[ccb[mbo].cdblen],
|
||||
SCSI_SENSE_BUFFERSIZE);
|
||||
@ -383,7 +400,8 @@ static irqreturn_t aha1542_interrupt(int irq, void *dev_id)
|
||||
#endif
|
||||
tmp_cmd->result = errstatus;
|
||||
aha1542->int_cmds[mbo] = NULL; /* This effectively frees up the mailbox slot, as
|
||||
far as queuecommand is concerned */
|
||||
* far as queuecommand is concerned
|
||||
*/
|
||||
my_done(tmp_cmd);
|
||||
number_serviced++;
|
||||
};
|
||||
@ -433,8 +451,10 @@ static int aha1542_queuecommand(struct Scsi_Host *sh, struct scsi_cmnd *cmd)
|
||||
goto out_free_chain;
|
||||
}
|
||||
|
||||
/* Use the outgoing mailboxes in a round-robin fashion, because this
|
||||
is how the host adapter will scan for them */
|
||||
/*
|
||||
* Use the outgoing mailboxes in a round-robin fashion, because this
|
||||
* is how the host adapter will scan for them
|
||||
*/
|
||||
|
||||
spin_lock_irqsave(sh->host_lock, flags);
|
||||
mbo = aha1542->aha1542_last_mbo_used + 1;
|
||||
@ -453,7 +473,8 @@ static int aha1542_queuecommand(struct Scsi_Host *sh, struct scsi_cmnd *cmd)
|
||||
panic("Unable to find empty mailbox for aha1542.\n");
|
||||
|
||||
aha1542->int_cmds[mbo] = cmd; /* This will effectively prevent someone else from
|
||||
screwing with this cdb. */
|
||||
* screwing with this cdb.
|
||||
*/
|
||||
|
||||
aha1542->aha1542_last_mbo_used = mbo;
|
||||
|
||||
@ -565,8 +586,10 @@ static int aha1542_getconfig(struct Scsi_Host *sh)
|
||||
sh->dma_channel = 0;
|
||||
break;
|
||||
case 0:
|
||||
/* This means that the adapter, although Adaptec 1542 compatible, doesn't use a DMA channel.
|
||||
Currently only aware of the BusLogic BT-445S VL-Bus adapter which needs this. */
|
||||
/*
|
||||
* This means that the adapter, although Adaptec 1542 compatible, doesn't use a DMA channel.
|
||||
* Currently only aware of the BusLogic BT-445S VL-Bus adapter which needs this.
|
||||
*/
|
||||
sh->dma_channel = 0xFF;
|
||||
break;
|
||||
default:
|
||||
@ -600,8 +623,10 @@ static int aha1542_getconfig(struct Scsi_Host *sh)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* This function should only be called for 1542C boards - we can detect
|
||||
the special firmware settings and unlock the board */
|
||||
/*
|
||||
* This function should only be called for 1542C boards - we can detect
|
||||
* the special firmware settings and unlock the board
|
||||
*/
|
||||
|
||||
static int aha1542_mbenable(struct Scsi_Host *sh)
|
||||
{
|
||||
@ -655,10 +680,11 @@ static int aha1542_query(struct Scsi_Host *sh)
|
||||
|
||||
aha1542->bios_translation = BIOS_TRANSLATION_6432; /* Default case */
|
||||
|
||||
/* For an AHA1740 series board, we ignore the board since there is a
|
||||
hardware bug which can lead to wrong blocks being returned if the board
|
||||
is operating in the 1542 emulation mode. Since there is an extended mode
|
||||
driver, we simply ignore the board and let the 1740 driver pick it up.
|
||||
/*
|
||||
* For an AHA1740 series board, we ignore the board since there is a
|
||||
* hardware bug which can lead to wrong blocks being returned if the board
|
||||
* is operating in the 1542 emulation mode. Since there is an extended mode
|
||||
* driver, we simply ignore the board and let the 1740 driver pick it up.
|
||||
*/
|
||||
|
||||
if (inquiry_result[0] == 0x43) {
|
||||
@ -666,8 +692,10 @@ static int aha1542_query(struct Scsi_Host *sh)
|
||||
return 1;
|
||||
};
|
||||
|
||||
/* Always call this - boards that do not support extended bios translation
|
||||
will ignore the command, and we will set the proper default */
|
||||
/*
|
||||
* Always call this - boards that do not support extended bios translation
|
||||
* will ignore the command, and we will set the proper default
|
||||
*/
|
||||
|
||||
aha1542->bios_translation = aha1542_mbenable(sh);
|
||||
|
||||
@ -877,8 +905,9 @@ static int aha1542_dev_reset(struct scsi_cmnd *cmd)
|
||||
panic("Unable to find empty mailbox for aha1542.\n");
|
||||
|
||||
aha1542->int_cmds[mbo] = cmd; /* This will effectively
|
||||
prevent someone else from
|
||||
screwing with this cdb. */
|
||||
* prevent someone else from
|
||||
* screwing with this cdb.
|
||||
*/
|
||||
|
||||
aha1542->aha1542_last_mbo_used = mbo;
|
||||
|
||||
@ -894,9 +923,9 @@ static int aha1542_dev_reset(struct scsi_cmnd *cmd)
|
||||
ccb[mbo].linkptr[0] = ccb[mbo].linkptr[1] = ccb[mbo].linkptr[2] = 0;
|
||||
ccb[mbo].commlinkid = 0;
|
||||
|
||||
/*
|
||||
* Now tell the 1542 to flush all pending commands for this
|
||||
* target
|
||||
/*
|
||||
* Now tell the 1542 to flush all pending commands for this
|
||||
* target
|
||||
*/
|
||||
aha1542_outb(sh->io_port, CMD_START_SCSI);
|
||||
spin_unlock_irqrestore(sh->host_lock, flags);
|
||||
@ -915,7 +944,7 @@ static int aha1542_reset(struct scsi_cmnd *cmd, u8 reset_cmd)
|
||||
int i;
|
||||
|
||||
spin_lock_irqsave(sh->host_lock, flags);
|
||||
/*
|
||||
/*
|
||||
* This does a scsi reset for all devices on the bus.
|
||||
* In principle, we could also reset the 1542 - should
|
||||
* we do this? Try this first, and we can add that later
|
||||
@ -939,7 +968,7 @@ static int aha1542_reset(struct scsi_cmnd *cmd, u8 reset_cmd)
|
||||
/*
|
||||
* Now try to pick up the pieces. For all pending commands,
|
||||
* free any internal data structures, and basically clear things
|
||||
* out. We do not try and restart any commands or anything -
|
||||
* out. We do not try and restart any commands or anything -
|
||||
* the strategy handler takes care of that crap.
|
||||
*/
|
||||
shost_printk(KERN_WARNING, cmd->device->host, "Sent BUS RESET to scsi host %d\n", cmd->device->host->host_no);
|
||||
@ -1008,10 +1037,10 @@ static struct scsi_host_template driver_template = {
|
||||
.eh_bus_reset_handler = aha1542_bus_reset,
|
||||
.eh_host_reset_handler = aha1542_host_reset,
|
||||
.bios_param = aha1542_biosparam,
|
||||
.can_queue = AHA1542_MAILBOXES,
|
||||
.can_queue = AHA1542_MAILBOXES,
|
||||
.this_id = 7,
|
||||
.sg_tablesize = 16,
|
||||
.unchecked_isa_dma = 1,
|
||||
.unchecked_isa_dma = 1,
|
||||
};
|
||||
|
||||
static int aha1542_isa_match(struct device *pdev, unsigned int ndev)
|
||||
@ -1062,8 +1091,10 @@ static int aha1542_pnp_probe(struct pnp_dev *pdev, const struct pnp_device_id *i
|
||||
|
||||
io[indx] = pnp_port_start(pdev, 0);
|
||||
|
||||
/* The card can be queried for its DMA, we have
|
||||
the DMA set up that is enough */
|
||||
/*
|
||||
* The card can be queried for its DMA, we have
|
||||
* the DMA set up that is enough
|
||||
*/
|
||||
|
||||
dev_info(&pdev->dev, "ISAPnP found an AHA1535 at I/O 0x%03X", io[indx]);
|
||||
}
|
||||
|
@ -78,23 +78,28 @@ static inline void any2scsi(u8 *p, u32 v)
|
||||
#define MAX_CDB 12
|
||||
#define MAX_SENSE 14
|
||||
|
||||
struct ccb { /* Command Control Block 5.3 */
|
||||
u8 op; /* Command Control Block Operation Code */
|
||||
u8 idlun; /* op=0,2:Target Id, op=1:Initiator Id */
|
||||
/* Outbound data transfer, length is checked*/
|
||||
/* Inbound data transfer, length is checked */
|
||||
/* Logical Unit Number */
|
||||
/* Command Control Block (CCB), 5.3 */
|
||||
struct ccb {
|
||||
u8 op; /* Command Control Block Operation Code: */
|
||||
/* 0x00: SCSI Initiator CCB, 0x01: SCSI Target CCB, */
|
||||
/* 0x02: SCSI Initiator CCB with Scatter/Gather, */
|
||||
/* 0x81: SCSI Bus Device Reset CCB */
|
||||
u8 idlun; /* Address and Direction Control: */
|
||||
/* Bits 7-5: op=0, 2: Target ID, op=1: Initiator ID */
|
||||
/* Bit 4: Outbound data transfer, length is checked */
|
||||
/* Bit 3: Inbound data transfer, length is checked */
|
||||
/* Bits 2-0: Logical Unit Number */
|
||||
u8 cdblen; /* SCSI Command Length */
|
||||
u8 rsalen; /* Request Sense Allocation Length/Disable */
|
||||
u8 datalen[3]; /* Data Length (msb, .., lsb) */
|
||||
u8 dataptr[3]; /* Data Pointer */
|
||||
u8 linkptr[3]; /* Link Pointer */
|
||||
u8 rsalen; /* Request Sense Allocation Length/Disable Auto Sense */
|
||||
u8 datalen[3]; /* Data Length (MSB, ..., LSB) */
|
||||
u8 dataptr[3]; /* Data Pointer (MSB, ..., LSB) */
|
||||
u8 linkptr[3]; /* Link Pointer (MSB, ..., LSB) */
|
||||
u8 commlinkid; /* Command Linking Identifier */
|
||||
u8 hastat; /* Host Adapter Status (HASTAT) */
|
||||
u8 tarstat; /* Target Device Status */
|
||||
u8 hastat; /* Host Adapter Status (HASTAT) */
|
||||
u8 tarstat; /* Target Device Status (TARSTAT) */
|
||||
u8 reserved[2];
|
||||
u8 cdb[MAX_CDB+MAX_SENSE]; /* SCSI Command Descriptor Block */
|
||||
/* REQUEST SENSE */
|
||||
u8 cdb[MAX_CDB + MAX_SENSE]; /* SCSI Command Descriptor Block */
|
||||
/* followed by the Auto Sense data */
|
||||
};
|
||||
|
||||
#define AHA1542_REGION_SIZE 4
|
||||
|
@ -211,7 +211,7 @@ typedef enum {
|
||||
*/
|
||||
typedef enum {
|
||||
AHD_FENONE = 0x00000,
|
||||
AHD_WIDE = 0x00001,/* Wide Channel */
|
||||
AHD_WIDE = 0x00001,/* Wide Channel */
|
||||
AHD_AIC79XXB_SLOWCRC = 0x00002,/* SLOWCRC bit should be set */
|
||||
AHD_MULTI_FUNC = 0x00100,/* Multi-Function/Channel Device */
|
||||
AHD_TARGETMODE = 0x01000,/* Has tested target mode support */
|
||||
@ -433,7 +433,7 @@ union initiator_data {
|
||||
* Target mode version of the shared data SCB segment.
|
||||
*/
|
||||
struct target_data {
|
||||
uint32_t spare[2];
|
||||
uint32_t spare[2];
|
||||
uint8_t scsi_status; /* SCSI status to give to initiator */
|
||||
uint8_t target_phases; /* Bitmap of phases to execute */
|
||||
uint8_t data_phase; /* Data-In or Data-Out */
|
||||
@ -608,9 +608,9 @@ struct scb {
|
||||
struct ahd_softc *ahd_softc;
|
||||
scb_flag flags;
|
||||
struct scb_platform_data *platform_data;
|
||||
struct map_node *hscb_map;
|
||||
struct map_node *sg_map;
|
||||
struct map_node *sense_map;
|
||||
struct map_node *hscb_map;
|
||||
struct map_node *sg_map;
|
||||
struct map_node *sense_map;
|
||||
void *sg_list;
|
||||
uint8_t *sense_data;
|
||||
dma_addr_t sg_list_busaddr;
|
||||
@ -674,7 +674,7 @@ struct scb_data {
|
||||
struct target_cmd {
|
||||
uint8_t scsiid; /* Our ID and the initiator's ID */
|
||||
uint8_t identify; /* Identify message */
|
||||
uint8_t bytes[22]; /*
|
||||
uint8_t bytes[22]; /*
|
||||
* Bytes contains any additional message
|
||||
* bytes terminated by 0xFF. The remainder
|
||||
* is the cdb to execute.
|
||||
@ -712,7 +712,7 @@ struct ahd_tmode_event {
|
||||
* structure here so we can store arrays of them, etc. in OS neutral
|
||||
* data structures.
|
||||
*/
|
||||
#ifdef AHD_TARGET_MODE
|
||||
#ifdef AHD_TARGET_MODE
|
||||
struct ahd_tmode_lstate {
|
||||
struct cam_path *path;
|
||||
struct ccb_hdr_slist accept_tios;
|
||||
@ -807,11 +807,11 @@ struct ahd_tmode_tstate {
|
||||
/***************************** Lookup Tables **********************************/
|
||||
/*
|
||||
* Phase -> name and message out response
|
||||
* to parity errors in each phase table.
|
||||
* to parity errors in each phase table.
|
||||
*/
|
||||
struct ahd_phase_table_entry {
|
||||
uint8_t phase;
|
||||
uint8_t mesg_out; /* Message response to parity errors */
|
||||
uint8_t phase;
|
||||
uint8_t mesg_out; /* Message response to parity errors */
|
||||
const char *phasemsg;
|
||||
};
|
||||
|
||||
@ -844,7 +844,7 @@ struct seeprom_config {
|
||||
#define CFBS_ENABLED 0x04
|
||||
#define CFBS_DISABLED_SCAN 0x08
|
||||
#define CFENABLEDV 0x0010 /* Perform Domain Validation */
|
||||
#define CFCTRL_A 0x0020 /* BIOS displays Ctrl-A message */
|
||||
#define CFCTRL_A 0x0020 /* BIOS displays Ctrl-A message */
|
||||
#define CFSPARITY 0x0040 /* SCSI parity */
|
||||
#define CFEXTEND 0x0080 /* extended translation enabled */
|
||||
#define CFBOOTCD 0x0100 /* Support Bootable CD-ROM */
|
||||
@ -858,7 +858,7 @@ struct seeprom_config {
|
||||
/*
|
||||
* Host Adapter Control Bits
|
||||
*/
|
||||
uint16_t adapter_control; /* word 17 */
|
||||
uint16_t adapter_control; /* word 17 */
|
||||
#define CFAUTOTERM 0x0001 /* Perform Auto termination */
|
||||
#define CFSTERM 0x0002 /* SCSI low byte termination */
|
||||
#define CFWSTERM 0x0004 /* SCSI high byte termination */
|
||||
@ -867,7 +867,7 @@ struct seeprom_config {
|
||||
#define CFSEHIGHTERM 0x0020 /* Ultra2 secondary high term */
|
||||
#define CFSTPWLEVEL 0x0040 /* Termination level control */
|
||||
#define CFBIOSAUTOTERM 0x0080 /* Perform Auto termination */
|
||||
#define CFTERM_MENU 0x0100 /* BIOS displays termination menu */
|
||||
#define CFTERM_MENU 0x0100 /* BIOS displays termination menu */
|
||||
#define CFCLUSTERENB 0x8000 /* Cluster Enable */
|
||||
|
||||
/*
|
||||
@ -881,7 +881,7 @@ struct seeprom_config {
|
||||
/*
|
||||
* Maximum targets
|
||||
*/
|
||||
uint16_t max_targets; /* word 19 */
|
||||
uint16_t max_targets; /* word 19 */
|
||||
#define CFMAXTARG 0x00ff /* maximum targets */
|
||||
#define CFBOOTLUN 0x0f00 /* Lun to boot from */
|
||||
#define CFBOOTID 0xf000 /* Target to boot from */
|
||||
@ -941,7 +941,7 @@ struct vpd_config {
|
||||
#define FLX_ROMSTAT_EE_2MBx8 0x2
|
||||
#define FLX_ROMSTAT_EE_4MBx8 0x3
|
||||
#define FLX_ROMSTAT_EE_16MBx8 0x4
|
||||
#define CURSENSE_ENB 0x1
|
||||
#define CURSENSE_ENB 0x1
|
||||
#define FLXADDR_FLEXSTAT 0x2
|
||||
#define FLX_FSTAT_BUSY 0x1
|
||||
#define FLXADDR_CURRENT_STAT 0x4
|
||||
@ -1051,8 +1051,8 @@ struct ahd_completion
|
||||
};
|
||||
|
||||
struct ahd_softc {
|
||||
bus_space_tag_t tags[2];
|
||||
bus_space_handle_t bshs[2];
|
||||
bus_space_tag_t tags[2];
|
||||
bus_space_handle_t bshs[2];
|
||||
struct scb_data scb_data;
|
||||
|
||||
struct hardware_scb *next_queued_hscb;
|
||||
@ -1243,7 +1243,7 @@ struct ahd_softc {
|
||||
u_int int_coalescing_threshold;
|
||||
u_int int_coalescing_stop_threshold;
|
||||
|
||||
uint16_t user_discenable;/* Disconnection allowed */
|
||||
uint16_t user_discenable;/* Disconnection allowed */
|
||||
uint16_t user_tagenable;/* Tagged Queuing allowed */
|
||||
};
|
||||
|
||||
|
@ -57,7 +57,7 @@ static const char *const ahd_chip_names[] =
|
||||
* Hardware error codes.
|
||||
*/
|
||||
struct ahd_hard_error_entry {
|
||||
uint8_t errno;
|
||||
uint8_t errno;
|
||||
const char *errmesg;
|
||||
};
|
||||
|
||||
@ -73,16 +73,16 @@ static const u_int num_errors = ARRAY_SIZE(ahd_hard_errors);
|
||||
|
||||
static const struct ahd_phase_table_entry ahd_phase_table[] =
|
||||
{
|
||||
{ P_DATAOUT, MSG_NOOP, "in Data-out phase" },
|
||||
{ P_DATAIN, MSG_INITIATOR_DET_ERR, "in Data-in phase" },
|
||||
{ P_DATAOUT_DT, MSG_NOOP, "in DT Data-out phase" },
|
||||
{ P_DATAIN_DT, MSG_INITIATOR_DET_ERR, "in DT Data-in phase" },
|
||||
{ P_COMMAND, MSG_NOOP, "in Command phase" },
|
||||
{ P_MESGOUT, MSG_NOOP, "in Message-out phase" },
|
||||
{ P_STATUS, MSG_INITIATOR_DET_ERR, "in Status phase" },
|
||||
{ P_DATAOUT, NOP, "in Data-out phase" },
|
||||
{ P_DATAIN, INITIATOR_ERROR, "in Data-in phase" },
|
||||
{ P_DATAOUT_DT, NOP, "in DT Data-out phase" },
|
||||
{ P_DATAIN_DT, INITIATOR_ERROR, "in DT Data-in phase" },
|
||||
{ P_COMMAND, NOP, "in Command phase" },
|
||||
{ P_MESGOUT, NOP, "in Message-out phase" },
|
||||
{ P_STATUS, INITIATOR_ERROR, "in Status phase" },
|
||||
{ P_MESGIN, MSG_PARITY_ERROR, "in Message-in phase" },
|
||||
{ P_BUSFREE, MSG_NOOP, "while idle" },
|
||||
{ 0, MSG_NOOP, "in unknown phase" }
|
||||
{ P_BUSFREE, NOP, "while idle" },
|
||||
{ 0, NOP, "in unknown phase" }
|
||||
};
|
||||
|
||||
/*
|
||||
@ -113,7 +113,7 @@ static void ahd_free_tstate(struct ahd_softc *ahd,
|
||||
u_int scsi_id, char channel, int force);
|
||||
#endif
|
||||
static void ahd_devlimited_syncrate(struct ahd_softc *ahd,
|
||||
struct ahd_initiator_tinfo *,
|
||||
struct ahd_initiator_tinfo *,
|
||||
u_int *period,
|
||||
u_int *ppr_options,
|
||||
role_t role);
|
||||
@ -170,7 +170,7 @@ static void ahd_setup_target_msgin(struct ahd_softc *ahd,
|
||||
static u_int ahd_sglist_size(struct ahd_softc *ahd);
|
||||
static u_int ahd_sglist_allocsize(struct ahd_softc *ahd);
|
||||
static bus_dmamap_callback_t
|
||||
ahd_dmamap_cb;
|
||||
ahd_dmamap_cb;
|
||||
static void ahd_initialize_hscbs(struct ahd_softc *ahd);
|
||||
static int ahd_init_scbdata(struct ahd_softc *ahd);
|
||||
static void ahd_fini_scbdata(struct ahd_softc *ahd);
|
||||
@ -268,7 +268,7 @@ static void ahd_run_tqinfifo(struct ahd_softc *ahd, int paused);
|
||||
static void ahd_handle_hwerrint(struct ahd_softc *ahd);
|
||||
static void ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat);
|
||||
static void ahd_handle_scsiint(struct ahd_softc *ahd,
|
||||
u_int intstat);
|
||||
u_int intstat);
|
||||
|
||||
/************************ Sequencer Execution Control *************************/
|
||||
void
|
||||
@ -1126,7 +1126,7 @@ ahd_restart(struct ahd_softc *ahd)
|
||||
/* No more pending messages */
|
||||
ahd_clear_msg_state(ahd);
|
||||
ahd_outb(ahd, SCSISIGO, 0); /* De-assert BSY */
|
||||
ahd_outb(ahd, MSG_OUT, MSG_NOOP); /* No message to send */
|
||||
ahd_outb(ahd, MSG_OUT, NOP); /* No message to send */
|
||||
ahd_outb(ahd, SXFRCTL1, ahd_inb(ahd, SXFRCTL1) & ~BITBUCKET);
|
||||
ahd_outb(ahd, SEQINTCTL, 0);
|
||||
ahd_outb(ahd, LASTPHASE, P_BUSFREE);
|
||||
@ -1203,7 +1203,7 @@ ahd_flush_qoutfifo(struct ahd_softc *ahd)
|
||||
while ((ahd_inb(ahd, LQISTAT2) & LQIGSAVAIL) != 0) {
|
||||
u_int fifo_mode;
|
||||
u_int i;
|
||||
|
||||
|
||||
scbid = ahd_inw(ahd, GSFIFO);
|
||||
scb = ahd_lookup_scb(ahd, scbid);
|
||||
if (scb == NULL) {
|
||||
@ -1326,7 +1326,7 @@ ahd_flush_qoutfifo(struct ahd_softc *ahd)
|
||||
while (!SCBID_IS_NULL(scbid)) {
|
||||
uint8_t *hscb_ptr;
|
||||
u_int i;
|
||||
|
||||
|
||||
ahd_set_scbptr(ahd, scbid);
|
||||
next_scbid = ahd_inw_scbram(ahd, SCB_NEXT_COMPLETE);
|
||||
scb = ahd_lookup_scb(ahd, scbid);
|
||||
@ -1991,7 +1991,7 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat)
|
||||
{
|
||||
struct scb *scb;
|
||||
u_int scb_index;
|
||||
|
||||
|
||||
#ifdef AHD_DEBUG
|
||||
if ((ahd_debug & AHD_SHOW_RECOVERY) != 0) {
|
||||
printk("%s: CFG4OVERRUN mode = %x\n", ahd_name(ahd),
|
||||
@ -2007,7 +2007,7 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat)
|
||||
*/
|
||||
ahd_assert_atn(ahd);
|
||||
ahd_outb(ahd, MSG_OUT, HOST_MSG);
|
||||
ahd->msgout_buf[0] = MSG_ABORT_TASK;
|
||||
ahd->msgout_buf[0] = ABORT_TASK;
|
||||
ahd->msgout_len = 1;
|
||||
ahd->msgout_index = 0;
|
||||
ahd->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
|
||||
@ -2094,8 +2094,7 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat)
|
||||
ahd->msg_type =
|
||||
MSG_TYPE_TARGET_MSGOUT;
|
||||
ahd->msgin_index = 0;
|
||||
}
|
||||
else
|
||||
} else
|
||||
ahd_setup_target_msgin(ahd,
|
||||
&devinfo,
|
||||
scb);
|
||||
@ -2136,7 +2135,7 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat)
|
||||
printk("SXFRCTL0 == 0x%x\n", ahd_inb(ahd, SXFRCTL0));
|
||||
printk("SEQCTL0 == 0x%x\n", ahd_inb(ahd, SEQCTL0));
|
||||
ahd_dump_card_state(ahd);
|
||||
ahd->msgout_buf[0] = MSG_BUS_DEV_RESET;
|
||||
ahd->msgout_buf[0] = TARGET_RESET;
|
||||
ahd->msgout_len = 1;
|
||||
ahd->msgout_index = 0;
|
||||
ahd->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
|
||||
@ -2338,9 +2337,9 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat)
|
||||
;
|
||||
ahd_outb(ahd, SCB_TASK_MANAGEMENT, 0);
|
||||
ahd_search_qinfifo(ahd, SCB_GET_TARGET(ahd, scb),
|
||||
SCB_GET_CHANNEL(ahd, scb),
|
||||
SCB_GET_LUN(scb), SCB_GET_TAG(scb),
|
||||
ROLE_INITIATOR, /*status*/0,
|
||||
SCB_GET_CHANNEL(ahd, scb),
|
||||
SCB_GET_LUN(scb), SCB_GET_TAG(scb),
|
||||
ROLE_INITIATOR, /*status*/0,
|
||||
SEARCH_REMOVE);
|
||||
}
|
||||
break;
|
||||
@ -2692,16 +2691,16 @@ ahd_handle_transmission_error(struct ahd_softc *ahd)
|
||||
lastphase = ahd_inb(ahd, LASTPHASE);
|
||||
curphase = ahd_inb(ahd, SCSISIGI) & PHASE_MASK;
|
||||
perrdiag = ahd_inb(ahd, PERRDIAG);
|
||||
msg_out = MSG_INITIATOR_DET_ERR;
|
||||
msg_out = INITIATOR_ERROR;
|
||||
ahd_outb(ahd, CLRSINT1, CLRSCSIPERR);
|
||||
|
||||
|
||||
/*
|
||||
* Try to find the SCB associated with this error.
|
||||
*/
|
||||
silent = FALSE;
|
||||
if (lqistat1 == 0
|
||||
|| (lqistat1 & LQICRCI_NLQ) != 0) {
|
||||
if ((lqistat1 & (LQICRCI_NLQ|LQIOVERI_NLQ)) != 0)
|
||||
if ((lqistat1 & (LQICRCI_NLQ|LQIOVERI_NLQ)) != 0)
|
||||
ahd_set_active_fifo(ahd);
|
||||
scbid = ahd_get_scbptr(ahd);
|
||||
scb = ahd_lookup_scb(ahd, scbid);
|
||||
@ -2818,20 +2817,20 @@ ahd_handle_transmission_error(struct ahd_softc *ahd)
|
||||
ahd_lookup_phase_entry(curphase)->phasemsg);
|
||||
ahd_inb(ahd, SCSIDAT);
|
||||
}
|
||||
|
||||
|
||||
if (curphase == P_MESGIN)
|
||||
msg_out = MSG_PARITY_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* We've set the hardware to assert ATN if we
|
||||
* We've set the hardware to assert ATN if we
|
||||
* get a parity error on "in" phases, so all we
|
||||
* need to do is stuff the message buffer with
|
||||
* the appropriate message. "In" phases have set
|
||||
* mesg_out to something other than MSG_NOP.
|
||||
* mesg_out to something other than NOP.
|
||||
*/
|
||||
ahd->send_msg_perror = msg_out;
|
||||
if (scb != NULL && msg_out == MSG_INITIATOR_DET_ERR)
|
||||
if (scb != NULL && msg_out == INITIATOR_ERROR)
|
||||
scb->flags |= SCB_TRANSMISSION_ERROR;
|
||||
ahd_outb(ahd, MSG_OUT, HOST_MSG);
|
||||
ahd_outb(ahd, CLRINT, CLRSCSIINT);
|
||||
@ -3051,8 +3050,8 @@ ahd_handle_nonpkt_busfree(struct ahd_softc *ahd)
|
||||
u_int tag;
|
||||
|
||||
tag = SCB_LIST_NULL;
|
||||
if (ahd_sent_msg(ahd, AHDMSG_1B, MSG_ABORT_TAG, TRUE)
|
||||
|| ahd_sent_msg(ahd, AHDMSG_1B, MSG_ABORT, TRUE)) {
|
||||
if (ahd_sent_msg(ahd, AHDMSG_1B, ABORT_TASK, TRUE)
|
||||
|| ahd_sent_msg(ahd, AHDMSG_1B, ABORT_TASK_SET, TRUE)) {
|
||||
int found;
|
||||
int sent_msg;
|
||||
|
||||
@ -3067,9 +3066,9 @@ ahd_handle_nonpkt_busfree(struct ahd_softc *ahd)
|
||||
ahd_print_path(ahd, scb);
|
||||
printk("SCB %d - Abort%s Completed.\n",
|
||||
SCB_GET_TAG(scb),
|
||||
sent_msg == MSG_ABORT_TAG ? "" : " Tag");
|
||||
sent_msg == ABORT_TASK ? "" : " Tag");
|
||||
|
||||
if (sent_msg == MSG_ABORT_TAG)
|
||||
if (sent_msg == ABORT_TASK)
|
||||
tag = SCB_GET_TAG(scb);
|
||||
|
||||
if ((scb->flags & SCB_EXTERNAL_RESET) != 0) {
|
||||
@ -3094,12 +3093,12 @@ ahd_handle_nonpkt_busfree(struct ahd_softc *ahd)
|
||||
printk("found == 0x%x\n", found);
|
||||
printerror = 0;
|
||||
} else if (ahd_sent_msg(ahd, AHDMSG_1B,
|
||||
MSG_BUS_DEV_RESET, TRUE)) {
|
||||
TARGET_RESET, TRUE)) {
|
||||
ahd_handle_devreset(ahd, &devinfo, CAM_LUN_WILDCARD,
|
||||
CAM_BDR_SENT, "Bus Device Reset",
|
||||
/*verbose_level*/0);
|
||||
printerror = 0;
|
||||
} else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_PPR, FALSE)
|
||||
} else if (ahd_sent_msg(ahd, AHDMSG_EXT, EXTENDED_PPR, FALSE)
|
||||
&& ppr_busfree == 0) {
|
||||
struct ahd_initiator_tinfo *tinfo;
|
||||
struct ahd_tmode_tstate *tstate;
|
||||
@ -3152,7 +3151,7 @@ ahd_handle_nonpkt_busfree(struct ahd_softc *ahd)
|
||||
}
|
||||
printerror = 0;
|
||||
}
|
||||
} else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_WDTR, FALSE)
|
||||
} else if (ahd_sent_msg(ahd, AHDMSG_EXT, EXTENDED_WDTR, FALSE)
|
||||
&& ppr_busfree == 0) {
|
||||
/*
|
||||
* Negotiation Rejected. Go-narrow and
|
||||
@ -3177,7 +3176,7 @@ ahd_handle_nonpkt_busfree(struct ahd_softc *ahd)
|
||||
ahd_qinfifo_requeue_tail(ahd, scb);
|
||||
}
|
||||
printerror = 0;
|
||||
} else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_SDTR, FALSE)
|
||||
} else if (ahd_sent_msg(ahd, AHDMSG_EXT, EXTENDED_SDTR, FALSE)
|
||||
&& ppr_busfree == 0) {
|
||||
/*
|
||||
* Negotiation Rejected. Go-async and
|
||||
@ -3205,7 +3204,7 @@ ahd_handle_nonpkt_busfree(struct ahd_softc *ahd)
|
||||
printerror = 0;
|
||||
} else if ((ahd->msg_flags & MSG_FLAG_EXPECT_IDE_BUSFREE) != 0
|
||||
&& ahd_sent_msg(ahd, AHDMSG_1B,
|
||||
MSG_INITIATOR_DET_ERR, TRUE)) {
|
||||
INITIATOR_ERROR, TRUE)) {
|
||||
|
||||
#ifdef AHD_DEBUG
|
||||
if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
|
||||
@ -3214,7 +3213,7 @@ ahd_handle_nonpkt_busfree(struct ahd_softc *ahd)
|
||||
printerror = 0;
|
||||
} else if ((ahd->msg_flags & MSG_FLAG_EXPECT_QASREJ_BUSFREE)
|
||||
&& ahd_sent_msg(ahd, AHDMSG_1B,
|
||||
MSG_MESSAGE_REJECT, TRUE)) {
|
||||
MESSAGE_REJECT, TRUE)) {
|
||||
|
||||
#ifdef AHD_DEBUG
|
||||
if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
|
||||
@ -3368,7 +3367,7 @@ ahd_handle_proto_violation(struct ahd_softc *ahd)
|
||||
ahd_outb(ahd, MSG_OUT, HOST_MSG);
|
||||
if (scb == NULL) {
|
||||
ahd_print_devinfo(ahd, &devinfo);
|
||||
ahd->msgout_buf[0] = MSG_ABORT_TASK;
|
||||
ahd->msgout_buf[0] = ABORT_TASK;
|
||||
ahd->msgout_len = 1;
|
||||
ahd->msgout_index = 0;
|
||||
ahd->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
|
||||
@ -3446,7 +3445,6 @@ ahd_clear_critical_section(struct ahd_softc *ahd)
|
||||
|
||||
cs = ahd->critical_sections;
|
||||
for (i = 0; i < ahd->num_critical_sections; i++, cs++) {
|
||||
|
||||
if (cs->begin < seqaddr && cs->end >= seqaddr)
|
||||
break;
|
||||
}
|
||||
@ -3472,8 +3470,8 @@ ahd_clear_critical_section(struct ahd_softc *ahd)
|
||||
if (stepping == FALSE) {
|
||||
|
||||
first_instr = seqaddr;
|
||||
ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
|
||||
simode0 = ahd_inb(ahd, SIMODE0);
|
||||
ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
|
||||
simode0 = ahd_inb(ahd, SIMODE0);
|
||||
simode3 = ahd_inb(ahd, SIMODE3);
|
||||
lqimode0 = ahd_inb(ahd, LQIMODE0);
|
||||
lqimode1 = ahd_inb(ahd, LQIMODE1);
|
||||
@ -3515,7 +3513,7 @@ ahd_clear_critical_section(struct ahd_softc *ahd)
|
||||
ahd_outb(ahd, LQOMODE1, lqomode1);
|
||||
ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
|
||||
ahd_outb(ahd, SEQCTL0, ahd_inb(ahd, SEQCTL0) & ~STEP);
|
||||
ahd_outb(ahd, SIMODE1, simode1);
|
||||
ahd_outb(ahd, SIMODE1, simode1);
|
||||
/*
|
||||
* SCSIINT seems to glitch occasionally when
|
||||
* the interrupt masks are restored. Clear SCSIINT
|
||||
@ -3553,7 +3551,7 @@ ahd_clear_intstat(struct ahd_softc *ahd)
|
||||
ahd_outb(ahd, CLRSINT1, CLRSELTIMEO|CLRATNO|CLRSCSIRSTI
|
||||
|CLRBUSFREE|CLRSCSIPERR|CLRREQINIT);
|
||||
ahd_outb(ahd, CLRSINT0, CLRSELDO|CLRSELDI|CLRSELINGO
|
||||
|CLRIOERR|CLROVERRUN);
|
||||
|CLRIOERR|CLROVERRUN);
|
||||
ahd_outb(ahd, CLRINT, CLRSCSIINT);
|
||||
}
|
||||
|
||||
@ -3689,7 +3687,7 @@ ahd_devlimited_syncrate(struct ahd_softc *ahd,
|
||||
*/
|
||||
if (role == ROLE_TARGET)
|
||||
transinfo = &tinfo->user;
|
||||
else
|
||||
else
|
||||
transinfo = &tinfo->goal;
|
||||
*ppr_options &= (transinfo->ppr_options|MSG_EXT_PPR_PCOMP_EN);
|
||||
if (transinfo->width == MSG_EXT_WDTR_BUS_8_BIT) {
|
||||
@ -3720,7 +3718,7 @@ ahd_find_syncrate(struct ahd_softc *ahd, u_int *period,
|
||||
if ((*ppr_options & MSG_EXT_PPR_DT_REQ) != 0
|
||||
&& *period > AHD_SYNCRATE_MIN_DT)
|
||||
*ppr_options &= ~MSG_EXT_PPR_DT_REQ;
|
||||
|
||||
|
||||
if (*period > AHD_SYNCRATE_MIN)
|
||||
*period = 0;
|
||||
|
||||
@ -4083,7 +4081,7 @@ ahd_update_neg_table(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
|
||||
ahd_outb(ahd, NEGOADDR, devinfo->target);
|
||||
period = tinfo->period;
|
||||
offset = tinfo->offset;
|
||||
memcpy(iocell_opts, ahd->iocell_opts, sizeof(ahd->iocell_opts));
|
||||
memcpy(iocell_opts, ahd->iocell_opts, sizeof(ahd->iocell_opts));
|
||||
ppr_opts = tinfo->ppr_options & (MSG_EXT_PPR_QAS_REQ|MSG_EXT_PPR_DT_REQ
|
||||
|MSG_EXT_PPR_IU_REQ|MSG_EXT_PPR_RTI);
|
||||
con_opts = 0;
|
||||
@ -4391,7 +4389,7 @@ ahd_setup_initiator_msgout(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
|
||||
} else if (scb == NULL) {
|
||||
printk("%s: WARNING. No pending message for "
|
||||
"I_T msgin. Issuing NO-OP\n", ahd_name(ahd));
|
||||
ahd->msgout_buf[ahd->msgout_index++] = MSG_NOOP;
|
||||
ahd->msgout_buf[ahd->msgout_index++] = NOP;
|
||||
ahd->msgout_len++;
|
||||
ahd->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
|
||||
return;
|
||||
@ -4417,7 +4415,7 @@ ahd_setup_initiator_msgout(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
|
||||
}
|
||||
|
||||
if (scb->flags & SCB_DEVICE_RESET) {
|
||||
ahd->msgout_buf[ahd->msgout_index++] = MSG_BUS_DEV_RESET;
|
||||
ahd->msgout_buf[ahd->msgout_index++] = TARGET_RESET;
|
||||
ahd->msgout_len++;
|
||||
ahd_print_path(ahd, scb);
|
||||
printk("Bus Device Reset Message Sent\n");
|
||||
@ -4432,9 +4430,9 @@ ahd_setup_initiator_msgout(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
|
||||
} else if ((scb->flags & SCB_ABORT) != 0) {
|
||||
|
||||
if ((scb->hscb->control & TAG_ENB) != 0) {
|
||||
ahd->msgout_buf[ahd->msgout_index++] = MSG_ABORT_TAG;
|
||||
ahd->msgout_buf[ahd->msgout_index++] = ABORT_TASK;
|
||||
} else {
|
||||
ahd->msgout_buf[ahd->msgout_index++] = MSG_ABORT;
|
||||
ahd->msgout_buf[ahd->msgout_index++] = ABORT_TASK_SET;
|
||||
}
|
||||
ahd->msgout_len++;
|
||||
ahd_print_path(ahd, scb);
|
||||
@ -4666,7 +4664,7 @@ ahd_clear_msg_state(struct ahd_softc *ahd)
|
||||
*/
|
||||
ahd_outb(ahd, CLRSINT1, CLRATNO);
|
||||
}
|
||||
ahd_outb(ahd, MSG_OUT, MSG_NOOP);
|
||||
ahd_outb(ahd, MSG_OUT, NOP);
|
||||
ahd_outb(ahd, SEQ_FLAGS2,
|
||||
ahd_inb(ahd, SEQ_FLAGS2) & ~TARGET_MSG_PENDING);
|
||||
ahd_restore_modes(ahd, saved_modes);
|
||||
@ -4747,7 +4745,7 @@ ahd_handle_message_phase(struct ahd_softc *ahd)
|
||||
* with a busfree.
|
||||
*/
|
||||
if ((ahd->msg_flags & MSG_FLAG_PACKETIZED) != 0
|
||||
&& ahd->send_msg_perror == MSG_INITIATOR_DET_ERR)
|
||||
&& ahd->send_msg_perror == INITIATOR_ERROR)
|
||||
ahd->msg_flags |= MSG_FLAG_EXPECT_IDE_BUSFREE;
|
||||
|
||||
ahd_outb(ahd, RETURN_2, ahd->send_msg_perror);
|
||||
@ -4849,7 +4847,7 @@ ahd_handle_message_phase(struct ahd_softc *ahd)
|
||||
#endif
|
||||
ahd_assert_atn(ahd);
|
||||
}
|
||||
} else
|
||||
} else
|
||||
ahd->msgin_index++;
|
||||
|
||||
if (message_done == MSGLOOP_TERMINATED) {
|
||||
@ -4952,7 +4950,7 @@ ahd_handle_message_phase(struct ahd_softc *ahd)
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
ahd->msgin_index++;
|
||||
|
||||
/*
|
||||
@ -5025,7 +5023,7 @@ ahd_sent_msg(struct ahd_softc *ahd, ahd_msgtype type, u_int msgval, int full)
|
||||
index = 0;
|
||||
|
||||
while (index < ahd->msgout_len) {
|
||||
if (ahd->msgout_buf[index] == MSG_EXTENDED) {
|
||||
if (ahd->msgout_buf[index] == EXTENDED_MESSAGE) {
|
||||
u_int end_index;
|
||||
|
||||
end_index = index + 1 + ahd->msgout_buf[index + 1];
|
||||
@ -5039,8 +5037,8 @@ ahd_sent_msg(struct ahd_softc *ahd, ahd_msgtype type, u_int msgval, int full)
|
||||
found = TRUE;
|
||||
}
|
||||
index = end_index;
|
||||
} else if (ahd->msgout_buf[index] >= MSG_SIMPLE_TASK
|
||||
&& ahd->msgout_buf[index] <= MSG_IGN_WIDE_RESIDUE) {
|
||||
} else if (ahd->msgout_buf[index] >= SIMPLE_QUEUE_TAG
|
||||
&& ahd->msgout_buf[index] <= IGNORE_WIDE_RESIDUE) {
|
||||
|
||||
/* Skip tag type and tag id or residue param*/
|
||||
index += 2;
|
||||
@ -5091,36 +5089,36 @@ ahd_parse_msg(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
|
||||
* extended message type.
|
||||
*/
|
||||
switch (ahd->msgin_buf[0]) {
|
||||
case MSG_DISCONNECT:
|
||||
case MSG_SAVEDATAPOINTER:
|
||||
case MSG_CMDCOMPLETE:
|
||||
case MSG_RESTOREPOINTERS:
|
||||
case MSG_IGN_WIDE_RESIDUE:
|
||||
case DISCONNECT:
|
||||
case SAVE_POINTERS:
|
||||
case COMMAND_COMPLETE:
|
||||
case RESTORE_POINTERS:
|
||||
case IGNORE_WIDE_RESIDUE:
|
||||
/*
|
||||
* End our message loop as these are messages
|
||||
* the sequencer handles on its own.
|
||||
*/
|
||||
done = MSGLOOP_TERMINATED;
|
||||
break;
|
||||
case MSG_MESSAGE_REJECT:
|
||||
case MESSAGE_REJECT:
|
||||
response = ahd_handle_msg_reject(ahd, devinfo);
|
||||
fallthrough;
|
||||
case MSG_NOOP:
|
||||
case NOP:
|
||||
done = MSGLOOP_MSGCOMPLETE;
|
||||
break;
|
||||
case MSG_EXTENDED:
|
||||
case EXTENDED_MESSAGE:
|
||||
{
|
||||
/* Wait for enough of the message to begin validation */
|
||||
if (ahd->msgin_index < 2)
|
||||
break;
|
||||
switch (ahd->msgin_buf[2]) {
|
||||
case MSG_EXT_SDTR:
|
||||
case EXTENDED_SDTR:
|
||||
{
|
||||
u_int period;
|
||||
u_int ppr_options;
|
||||
u_int offset;
|
||||
u_int saved_offset;
|
||||
|
||||
|
||||
if (ahd->msgin_buf[1] != MSG_EXT_SDTR_LEN) {
|
||||
reject = TRUE;
|
||||
break;
|
||||
@ -5162,7 +5160,7 @@ ahd_parse_msg(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
|
||||
* and didn't have to fall down to async
|
||||
* transfers.
|
||||
*/
|
||||
if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_SDTR, TRUE)) {
|
||||
if (ahd_sent_msg(ahd, AHDMSG_EXT, EXTENDED_SDTR, TRUE)) {
|
||||
/* We started it */
|
||||
if (saved_offset != offset) {
|
||||
/* Went too low - force async */
|
||||
@ -5189,7 +5187,7 @@ ahd_parse_msg(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
|
||||
done = MSGLOOP_MSGCOMPLETE;
|
||||
break;
|
||||
}
|
||||
case MSG_EXT_WDTR:
|
||||
case EXTENDED_WDTR:
|
||||
{
|
||||
u_int bus_width;
|
||||
u_int saved_width;
|
||||
@ -5223,7 +5221,7 @@ ahd_parse_msg(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
|
||||
saved_width, bus_width);
|
||||
}
|
||||
|
||||
if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_WDTR, TRUE)) {
|
||||
if (ahd_sent_msg(ahd, AHDMSG_EXT, EXTENDED_WDTR, TRUE)) {
|
||||
/*
|
||||
* Don't send a WDTR back to the
|
||||
* target, since we asked first.
|
||||
@ -5285,7 +5283,7 @@ ahd_parse_msg(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
|
||||
done = MSGLOOP_MSGCOMPLETE;
|
||||
break;
|
||||
}
|
||||
case MSG_EXT_PPR:
|
||||
case EXTENDED_PPR:
|
||||
{
|
||||
u_int period;
|
||||
u_int offset;
|
||||
@ -5340,7 +5338,7 @@ ahd_parse_msg(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
|
||||
ahd_validate_offset(ahd, tinfo, period, &offset,
|
||||
bus_width, devinfo->role);
|
||||
|
||||
if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_PPR, TRUE)) {
|
||||
if (ahd_sent_msg(ahd, AHDMSG_EXT, EXTENDED_PPR, TRUE)) {
|
||||
/*
|
||||
* If we are unable to do any of the
|
||||
* requested options (we went too low),
|
||||
@ -5403,7 +5401,7 @@ ahd_parse_msg(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
|
||||
break;
|
||||
}
|
||||
#ifdef AHD_TARGET_MODE
|
||||
case MSG_BUS_DEV_RESET:
|
||||
case TARGET_RESET:
|
||||
ahd_handle_devreset(ahd, devinfo, CAM_LUN_WILDCARD,
|
||||
CAM_BDR_SENT,
|
||||
"Bus Device Reset Received",
|
||||
@ -5411,9 +5409,9 @@ ahd_parse_msg(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
|
||||
ahd_restart(ahd);
|
||||
done = MSGLOOP_TERMINATED;
|
||||
break;
|
||||
case MSG_ABORT_TAG:
|
||||
case MSG_ABORT:
|
||||
case MSG_CLEAR_QUEUE:
|
||||
case ABORT_TASK:
|
||||
case ABORT_TASK_SET:
|
||||
case CLEAR_TASK_SET:
|
||||
{
|
||||
int tag;
|
||||
|
||||
@ -5423,7 +5421,7 @@ ahd_parse_msg(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
|
||||
break;
|
||||
}
|
||||
tag = SCB_LIST_NULL;
|
||||
if (ahd->msgin_buf[0] == MSG_ABORT_TAG)
|
||||
if (ahd->msgin_buf[0] == ABORT_TASK)
|
||||
tag = ahd_inb(ahd, INITIATOR_TAG);
|
||||
ahd_abort_scbs(ahd, devinfo->target, devinfo->channel,
|
||||
devinfo->lun, tag, ROLE_TARGET,
|
||||
@ -5447,7 +5445,7 @@ ahd_parse_msg(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case MSG_QAS_REQUEST:
|
||||
case QAS_REQUEST:
|
||||
#ifdef AHD_DEBUG
|
||||
if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
|
||||
printk("%s: QAS request. SCSISIGI == 0x%x\n",
|
||||
@ -5455,7 +5453,7 @@ ahd_parse_msg(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
|
||||
#endif
|
||||
ahd->msg_flags |= MSG_FLAG_EXPECT_QASREJ_BUSFREE;
|
||||
fallthrough;
|
||||
case MSG_TERM_IO_PROC:
|
||||
case TERMINATE_IO_PROC:
|
||||
default:
|
||||
reject = TRUE;
|
||||
break;
|
||||
@ -5467,7 +5465,7 @@ ahd_parse_msg(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
|
||||
*/
|
||||
ahd->msgout_index = 0;
|
||||
ahd->msgout_len = 1;
|
||||
ahd->msgout_buf[0] = MSG_MESSAGE_REJECT;
|
||||
ahd->msgout_buf[0] = MESSAGE_REJECT;
|
||||
done = MSGLOOP_MSGCOMPLETE;
|
||||
response = TRUE;
|
||||
}
|
||||
@ -5506,8 +5504,8 @@ ahd_handle_msg_reject(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
|
||||
/* Might be necessary */
|
||||
last_msg = ahd_inb(ahd, LAST_MSG);
|
||||
|
||||
if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_PPR, /*full*/FALSE)) {
|
||||
if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_PPR, /*full*/TRUE)
|
||||
if (ahd_sent_msg(ahd, AHDMSG_EXT, EXTENDED_PPR, /*full*/FALSE)) {
|
||||
if (ahd_sent_msg(ahd, AHDMSG_EXT, EXTENDED_PPR, /*full*/TRUE)
|
||||
&& tinfo->goal.period <= AHD_SYNCRATE_PACED) {
|
||||
/*
|
||||
* Target may not like our SPI-4 PPR Options.
|
||||
@ -5544,7 +5542,7 @@ ahd_handle_msg_reject(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
|
||||
ahd_build_transfer_msg(ahd, devinfo);
|
||||
ahd->msgout_index = 0;
|
||||
response = 1;
|
||||
} else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_WDTR, /*full*/FALSE)) {
|
||||
} else if (ahd_sent_msg(ahd, AHDMSG_EXT, EXTENDED_WDTR, /*full*/FALSE)) {
|
||||
|
||||
/* note 8bit xfers */
|
||||
printk("(%s:%c:%d:%d): refuses WIDE negotiation. Using "
|
||||
@ -5569,7 +5567,7 @@ ahd_handle_msg_reject(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
|
||||
ahd->msgout_index = 0;
|
||||
response = 1;
|
||||
}
|
||||
} else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_SDTR, /*full*/FALSE)) {
|
||||
} else if (ahd_sent_msg(ahd, AHDMSG_EXT, EXTENDED_SDTR, /*full*/FALSE)) {
|
||||
/* note asynch xfers and clear flag */
|
||||
ahd_set_syncrate(ahd, devinfo, /*period*/0,
|
||||
/*offset*/0, /*ppr_options*/0,
|
||||
@ -5579,13 +5577,13 @@ ahd_handle_msg_reject(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
|
||||
"Using asynchronous transfers\n",
|
||||
ahd_name(ahd), devinfo->channel,
|
||||
devinfo->target, devinfo->lun);
|
||||
} else if ((scb->hscb->control & MSG_SIMPLE_TASK) != 0) {
|
||||
} else if ((scb->hscb->control & SIMPLE_QUEUE_TAG) != 0) {
|
||||
int tag_type;
|
||||
int mask;
|
||||
|
||||
tag_type = (scb->hscb->control & MSG_SIMPLE_TASK);
|
||||
tag_type = (scb->hscb->control & SIMPLE_QUEUE_TAG);
|
||||
|
||||
if (tag_type == MSG_SIMPLE_TASK) {
|
||||
if (tag_type == SIMPLE_QUEUE_TAG) {
|
||||
printk("(%s:%c:%d:%d): refuses tagged commands. "
|
||||
"Performing non-tagged I/O\n", ahd_name(ahd),
|
||||
devinfo->channel, devinfo->target, devinfo->lun);
|
||||
@ -5595,7 +5593,7 @@ ahd_handle_msg_reject(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
|
||||
printk("(%s:%c:%d:%d): refuses %s tagged commands. "
|
||||
"Performing simple queue tagged I/O only\n",
|
||||
ahd_name(ahd), devinfo->channel, devinfo->target,
|
||||
devinfo->lun, tag_type == MSG_ORDERED_TASK
|
||||
devinfo->lun, tag_type == ORDERED_QUEUE_TAG
|
||||
? "ordered" : "head of queue");
|
||||
ahd_set_tags(ahd, scb->io_ctx, devinfo, AHD_QUEUE_BASIC);
|
||||
mask = ~0x03;
|
||||
@ -5607,9 +5605,9 @@ ahd_handle_msg_reject(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
|
||||
*/
|
||||
ahd_outb(ahd, SCB_CONTROL,
|
||||
ahd_inb_scbram(ahd, SCB_CONTROL) & mask);
|
||||
scb->hscb->control &= mask;
|
||||
scb->hscb->control &= mask;
|
||||
ahd_set_transaction_tag(scb, /*enabled*/FALSE,
|
||||
/*type*/MSG_SIMPLE_TASK);
|
||||
/*type*/SIMPLE_QUEUE_TAG);
|
||||
ahd_outb(ahd, MSG_OUT, MSG_IDENTIFYFLAG);
|
||||
ahd_assert_atn(ahd);
|
||||
ahd_busy_tcl(ahd, BUILD_TCL(scb->hscb->scsiid, devinfo->lun),
|
||||
@ -5816,7 +5814,7 @@ ahd_reinitialize_dataptrs(struct ahd_softc *ahd)
|
||||
|
||||
AHD_ASSERT_MODES(ahd, AHD_MODE_DFF0_MSK|AHD_MODE_DFF1_MSK,
|
||||
AHD_MODE_DFF0_MSK|AHD_MODE_DFF1_MSK);
|
||||
|
||||
|
||||
scb_index = ahd_get_scbptr(ahd);
|
||||
scb = ahd_lookup_scb(ahd, scb_index);
|
||||
|
||||
@ -5924,7 +5922,7 @@ ahd_handle_devreset(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
|
||||
continue;
|
||||
|
||||
ahd_queue_lstate_event(ahd, lstate, devinfo->our_scsiid,
|
||||
MSG_BUS_DEV_RESET, /*arg*/0);
|
||||
TARGET_RESET, /*arg*/0);
|
||||
ahd_send_lstate_events(ahd, lstate);
|
||||
}
|
||||
}
|
||||
@ -5938,7 +5936,7 @@ ahd_handle_devreset(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
|
||||
ahd_set_syncrate(ahd, devinfo, /*period*/0, /*offset*/0,
|
||||
/*ppr_options*/0, AHD_TRANS_CUR,
|
||||
/*paused*/TRUE);
|
||||
|
||||
|
||||
if (status != CAM_SEL_TIMEOUT)
|
||||
ahd_send_async(ahd, devinfo->channel, devinfo->target,
|
||||
CAM_LUN_WILDCARD, AC_SENT_BDR);
|
||||
@ -5954,11 +5952,11 @@ ahd_setup_target_msgin(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
|
||||
struct scb *scb)
|
||||
{
|
||||
|
||||
/*
|
||||
/*
|
||||
* To facilitate adding multiple messages together,
|
||||
* each routine should increment the index and len
|
||||
* variables instead of setting them explicitly.
|
||||
*/
|
||||
*/
|
||||
ahd->msgout_index = 0;
|
||||
ahd->msgout_len = 0;
|
||||
|
||||
@ -6091,7 +6089,7 @@ ahd_softc_init(struct ahd_softc *ahd)
|
||||
{
|
||||
|
||||
ahd->unpause = 0;
|
||||
ahd->pause = PAUSE;
|
||||
ahd->pause = PAUSE;
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -6204,7 +6202,7 @@ ahd_reset(struct ahd_softc *ahd, int reinit)
|
||||
u_int sxfrctl1;
|
||||
int wait;
|
||||
uint32_t cmd;
|
||||
|
||||
|
||||
/*
|
||||
* Preserve the value of the SXFRCTL1 register for all channels.
|
||||
* It contains settings that affect termination and we don't want
|
||||
@ -6444,7 +6442,7 @@ ahd_init_scbdata(struct ahd_softc *ahd)
|
||||
/*
|
||||
* Note that we were successful
|
||||
*/
|
||||
return (0);
|
||||
return (0);
|
||||
|
||||
error_exit:
|
||||
|
||||
@ -6962,7 +6960,7 @@ ahd_controller_info(struct ahd_softc *ahd, char *buf)
|
||||
static const char *channel_strings[] = {
|
||||
"Primary Low",
|
||||
"Primary High",
|
||||
"Secondary Low",
|
||||
"Secondary Low",
|
||||
"Secondary High"
|
||||
};
|
||||
|
||||
@ -7234,7 +7232,7 @@ ahd_chip_init(struct ahd_softc *ahd)
|
||||
} else {
|
||||
sxfrctl1 |= ahd->seltime;
|
||||
}
|
||||
|
||||
|
||||
ahd_outb(ahd, SXFRCTL0, DFON);
|
||||
ahd_outb(ahd, SXFRCTL1, sxfrctl1|ahd->seltime|ENSTIMER|ACTNEGEN);
|
||||
ahd_outb(ahd, SIMODE1, ENSELTIMO|ENSCSIRST|ENSCSIPERR);
|
||||
@ -7490,7 +7488,7 @@ ahd_chip_init(struct ahd_softc *ahd)
|
||||
ahd_outb(ahd, CMDSIZE_TABLE + 5, 11);
|
||||
ahd_outb(ahd, CMDSIZE_TABLE + 6, 0);
|
||||
ahd_outb(ahd, CMDSIZE_TABLE + 7, 0);
|
||||
|
||||
|
||||
/* Tell the sequencer of our initial queue positions */
|
||||
ahd_set_modes(ahd, AHD_MODE_CCHAN, AHD_MODE_CCHAN);
|
||||
ahd_outb(ahd, QOFF_CTLSTA, SCB_QSIZE_512);
|
||||
@ -7884,7 +7882,7 @@ void __maybe_unused
|
||||
ahd_resume(struct ahd_softc *ahd)
|
||||
{
|
||||
ahd_reset(ahd, /*reinit*/TRUE);
|
||||
ahd_intr_enable(ahd, TRUE);
|
||||
ahd_intr_enable(ahd, TRUE);
|
||||
ahd_restart(ahd);
|
||||
}
|
||||
|
||||
@ -7925,7 +7923,7 @@ ahd_find_busy_tcl(struct ahd_softc *ahd, u_int tcl)
|
||||
u_int scbid;
|
||||
u_int scb_offset;
|
||||
u_int saved_scbptr;
|
||||
|
||||
|
||||
scb_offset = ahd_index_busy_tcl(ahd, &saved_scbptr, tcl);
|
||||
scbid = ahd_inw_scbram(ahd, scb_offset);
|
||||
ahd_set_scbptr(ahd, saved_scbptr);
|
||||
@ -7937,7 +7935,7 @@ ahd_busy_tcl(struct ahd_softc *ahd, u_int tcl, u_int scbid)
|
||||
{
|
||||
u_int scb_offset;
|
||||
u_int saved_scbptr;
|
||||
|
||||
|
||||
scb_offset = ahd_index_busy_tcl(ahd, &saved_scbptr, tcl);
|
||||
ahd_outw(ahd, scb_offset, scbid);
|
||||
ahd_set_scbptr(ahd, saved_scbptr);
|
||||
@ -7990,7 +7988,7 @@ ahd_freeze_devq(struct ahd_softc *ahd, struct scb *scb)
|
||||
target = SCB_GET_TARGET(ahd, scb);
|
||||
lun = SCB_GET_LUN(scb);
|
||||
channel = SCB_GET_CHANNEL(ahd, scb);
|
||||
|
||||
|
||||
ahd_search_qinfifo(ahd, target, channel, lun,
|
||||
/*tag*/SCB_LIST_NULL, ROLE_UNKNOWN,
|
||||
CAM_REQUEUE_REQ, SEARCH_COMPLETE);
|
||||
@ -8031,7 +8029,7 @@ ahd_qinfifo_requeue(struct ahd_softc *ahd, struct scb *prev_scb,
|
||||
ahd_outl(ahd, NEXT_QUEUED_SCB_ADDR, busaddr);
|
||||
} else {
|
||||
prev_scb->hscb->next_hscb_busaddr = scb->hscb->hscb_busaddr;
|
||||
ahd_sync_scb(ahd, prev_scb,
|
||||
ahd_sync_scb(ahd, prev_scb,
|
||||
BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
|
||||
}
|
||||
ahd->qinfifo[AHD_QIN_WRAP(ahd->qinfifonext)] = SCB_GET_TAG(scb);
|
||||
@ -8331,7 +8329,7 @@ ahd_search_qinfifo(struct ahd_softc *ahd, int target, char channel,
|
||||
static int
|
||||
ahd_search_scb_list(struct ahd_softc *ahd, int target, char channel,
|
||||
int lun, u_int tag, role_t role, uint32_t status,
|
||||
ahd_search_action action, u_int *list_head,
|
||||
ahd_search_action action, u_int *list_head,
|
||||
u_int *list_tail, u_int tid)
|
||||
{
|
||||
struct scb *scb;
|
||||
@ -8789,7 +8787,7 @@ ahd_stat_timer(struct timer_list *t)
|
||||
struct ahd_softc *ahd = from_timer(ahd, t, stat_timer);
|
||||
u_long s;
|
||||
int enint_coal;
|
||||
|
||||
|
||||
ahd_lock(ahd, &s);
|
||||
|
||||
enint_coal = ahd->hs_mailbox & ENINT_COALESCE;
|
||||
@ -8834,7 +8832,7 @@ ahd_handle_scsi_status(struct ahd_softc *ahd, struct scb *scb)
|
||||
* operations are on data structures that the sequencer
|
||||
* is not touching once the queue is frozen.
|
||||
*/
|
||||
hscb = scb->hscb;
|
||||
hscb = scb->hscb;
|
||||
|
||||
if (ahd_is_paused(ahd)) {
|
||||
paused = 1;
|
||||
@ -8913,7 +8911,7 @@ ahd_handle_scsi_status(struct ahd_softc *ahd, struct scb *scb)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (siu->status == SCSI_STATUS_OK)
|
||||
if (siu->status == SAM_STAT_GOOD)
|
||||
ahd_set_transaction_status(scb,
|
||||
CAM_REQ_CMP_ERR);
|
||||
}
|
||||
@ -8927,8 +8925,8 @@ ahd_handle_scsi_status(struct ahd_softc *ahd, struct scb *scb)
|
||||
ahd_done(ahd, scb);
|
||||
break;
|
||||
}
|
||||
case SCSI_STATUS_CMD_TERMINATED:
|
||||
case SCSI_STATUS_CHECK_COND:
|
||||
case SAM_STAT_COMMAND_TERMINATED:
|
||||
case SAM_STAT_CHECK_CONDITION:
|
||||
{
|
||||
struct ahd_devinfo devinfo;
|
||||
struct ahd_dma_seg *sg;
|
||||
@ -9018,7 +9016,7 @@ ahd_handle_scsi_status(struct ahd_softc *ahd, struct scb *scb)
|
||||
ahd_queue_scb(ahd, scb);
|
||||
break;
|
||||
}
|
||||
case SCSI_STATUS_OK:
|
||||
case SAM_STAT_GOOD:
|
||||
printk("%s: Interrupted for status of 0???\n",
|
||||
ahd_name(ahd));
|
||||
fallthrough;
|
||||
@ -9108,7 +9106,7 @@ ahd_calc_residual(struct ahd_softc *ahd, struct scb *scb)
|
||||
|
||||
/*
|
||||
* Remainder of the SG where the transfer
|
||||
* stopped.
|
||||
* stopped.
|
||||
*/
|
||||
resid = ahd_le32toh(spkt->residual_datacnt) & AHD_SG_LEN_MASK;
|
||||
sg = ahd_sg_bus_to_virt(ahd, scb, resid_sgptr & SG_PTR_MASK);
|
||||
@ -9160,7 +9158,7 @@ ahd_queue_lstate_event(struct ahd_softc *ahd, struct ahd_tmode_lstate *lstate,
|
||||
- (lstate->event_r_idx - lstate->event_w_idx);
|
||||
|
||||
if (event_type == EVENT_TYPE_BUS_RESET
|
||||
|| event_type == MSG_BUS_DEV_RESET) {
|
||||
|| event_type == TARGET_RESET) {
|
||||
/*
|
||||
* Any earlier events are irrelevant, so reset our buffer.
|
||||
* This has the effect of allowing us to deal with reset
|
||||
@ -9291,7 +9289,7 @@ ahd_loadseq(struct ahd_softc *ahd)
|
||||
|
||||
/*
|
||||
* Setup downloadable constant table.
|
||||
*
|
||||
*
|
||||
* The computation for the S/G prefetch variables is
|
||||
* a bit complicated. We would like to always fetch
|
||||
* in terms of cachelined sized increments. However,
|
||||
@ -9380,7 +9378,7 @@ ahd_loadseq(struct ahd_softc *ahd)
|
||||
if (begin_set[cs_count] == TRUE
|
||||
&& end_set[cs_count] == FALSE) {
|
||||
cs_table[cs_count].end = downloaded;
|
||||
end_set[cs_count] = TRUE;
|
||||
end_set[cs_count] = TRUE;
|
||||
cs_count++;
|
||||
}
|
||||
continue;
|
||||
@ -9615,7 +9613,7 @@ ahd_print_register(const ahd_reg_parse_entry_t *table, u_int num_entries,
|
||||
printed_mask == 0 ? ":(" : "|",
|
||||
table[entry].name);
|
||||
printed_mask |= table[entry].mask;
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
if (entry >= num_entries)
|
||||
@ -9652,7 +9650,7 @@ ahd_dump_card_state(struct ahd_softc *ahd)
|
||||
ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
|
||||
printk(">>>>>>>>>>>>>>>>>> Dump Card State Begins <<<<<<<<<<<<<<<<<\n"
|
||||
"%s: Dumping Card State at program address 0x%x Mode 0x%x\n",
|
||||
ahd_name(ahd),
|
||||
ahd_name(ahd),
|
||||
ahd_inw(ahd, CURADDR),
|
||||
ahd_build_mode_state(ahd, ahd->saved_src_mode,
|
||||
ahd->saved_dst_mode));
|
||||
@ -9768,7 +9766,6 @@ ahd_dump_card_state(struct ahd_softc *ahd)
|
||||
}
|
||||
printk("\n");
|
||||
|
||||
|
||||
printk("Sequencer DMA-Up and Complete list: ");
|
||||
scb_index = ahd_inw(ahd, COMPLETE_DMA_SCB_HEAD);
|
||||
i = 0;
|
||||
@ -9946,7 +9943,7 @@ ahd_read_seeprom(struct ahd_softc *ahd, uint16_t *buf,
|
||||
|
||||
ahd_outb(ahd, SEEADR, cur_addr);
|
||||
ahd_outb(ahd, SEECTL, SEEOP_READ | SEESTART);
|
||||
|
||||
|
||||
error = ahd_wait_seeprom(ahd);
|
||||
if (error)
|
||||
break;
|
||||
@ -10001,7 +9998,7 @@ ahd_write_seeprom(struct ahd_softc *ahd, uint16_t *buf,
|
||||
ahd_outw(ahd, SEEDAT, *buf++);
|
||||
ahd_outb(ahd, SEEADR, cur_addr);
|
||||
ahd_outb(ahd, SEECTL, SEEOP_WRITE | SEESTART);
|
||||
|
||||
|
||||
retval = ahd_wait_seeprom(ahd);
|
||||
if (retval)
|
||||
break;
|
||||
@ -10106,7 +10103,7 @@ ahd_acquire_seeprom(struct ahd_softc *ahd)
|
||||
|
||||
error = ahd_read_flexport(ahd, FLXADDR_ROMSTAT_CURSENSECTL, &seetype);
|
||||
if (error != 0
|
||||
|| ((seetype & FLX_ROMSTAT_SEECFG) == FLX_ROMSTAT_SEE_NONE))
|
||||
|| ((seetype & FLX_ROMSTAT_SEECFG) == FLX_ROMSTAT_SEE_NONE))
|
||||
return (0);
|
||||
return (1);
|
||||
#endif
|
||||
@ -10248,7 +10245,7 @@ ahd_handle_en_lun(struct ahd_softc *ahd, struct cam_sim *sim, union ccb *ccb)
|
||||
our_id = ahd->our_id;
|
||||
if (ccb->ccb_h.target_id != our_id) {
|
||||
if ((ahd->features & AHD_MULTI_TID) != 0
|
||||
&& (ahd->flags & AHD_INITIATORROLE) != 0) {
|
||||
&& (ahd->flags & AHD_INITIATORROLE) != 0) {
|
||||
/*
|
||||
* Only allow additional targets if
|
||||
* the initiator role is disabled.
|
||||
@ -10435,7 +10432,7 @@ ahd_handle_en_lun(struct ahd_softc *ahd, struct cam_sim *sim, union ccb *ccb)
|
||||
}
|
||||
|
||||
ahd_lock(ahd, &s);
|
||||
|
||||
|
||||
ccb->ccb_h.status = CAM_REQ_CMP;
|
||||
LIST_FOREACH(scb, &ahd->pending_scbs, pending_links) {
|
||||
struct ccb_hdr *ccbh;
|
||||
@ -10699,7 +10696,7 @@ ahd_handle_target_cmd(struct ahd_softc *ahd, struct target_cmd *cmd)
|
||||
printk("Reserved or VU command code type encountered\n");
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
memcpy(atio->cdb_io.cdb_bytes, byte, atio->cdb_len);
|
||||
|
||||
atio->ccb_h.status |= CAM_CDB_RECVD;
|
||||
|
@ -1602,10 +1602,10 @@ ahd_linux_run_command(struct ahd_softc *ahd, struct ahd_linux_device *dev,
|
||||
if ((dev->flags & (AHD_DEV_Q_TAGGED|AHD_DEV_Q_BASIC)) != 0) {
|
||||
if (dev->commands_since_idle_or_otag == AHD_OTAG_THRESH
|
||||
&& (dev->flags & AHD_DEV_Q_TAGGED) != 0) {
|
||||
hscb->control |= MSG_ORDERED_TASK;
|
||||
hscb->control |= ORDERED_QUEUE_TAG;
|
||||
dev->commands_since_idle_or_otag = 0;
|
||||
} else {
|
||||
hscb->control |= MSG_SIMPLE_TASK;
|
||||
hscb->control |= SIMPLE_QUEUE_TAG;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1834,7 +1834,7 @@ ahd_done(struct ahd_softc *ahd, struct scb *scb)
|
||||
|
||||
if (dev->openings == 1
|
||||
&& ahd_get_transaction_status(scb) == CAM_REQ_CMP
|
||||
&& ahd_get_scsi_status(scb) != SCSI_STATUS_QUEUE_FULL)
|
||||
&& ahd_get_scsi_status(scb) != SAM_STAT_TASK_SET_FULL)
|
||||
dev->tag_success_count++;
|
||||
/*
|
||||
* Some devices deal with temporary internal resource
|
||||
@ -1891,8 +1891,8 @@ ahd_linux_handle_scsi_status(struct ahd_softc *ahd,
|
||||
switch (ahd_get_scsi_status(scb)) {
|
||||
default:
|
||||
break;
|
||||
case SCSI_STATUS_CHECK_COND:
|
||||
case SCSI_STATUS_CMD_TERMINATED:
|
||||
case SAM_STAT_CHECK_CONDITION:
|
||||
case SAM_STAT_COMMAND_TERMINATED:
|
||||
{
|
||||
struct scsi_cmnd *cmd;
|
||||
|
||||
@ -1947,7 +1947,7 @@ ahd_linux_handle_scsi_status(struct ahd_softc *ahd,
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SCSI_STATUS_QUEUE_FULL:
|
||||
case SAM_STAT_TASK_SET_FULL:
|
||||
/*
|
||||
* By the time the core driver has returned this
|
||||
* command, all other commands that were queued
|
||||
@ -1993,7 +1993,7 @@ ahd_linux_handle_scsi_status(struct ahd_softc *ahd,
|
||||
dev->last_queuefull_same_count = 0;
|
||||
}
|
||||
ahd_set_transaction_status(scb, CAM_REQUEUE_REQ);
|
||||
ahd_set_scsi_status(scb, SCSI_STATUS_OK);
|
||||
ahd_set_scsi_status(scb, SAM_STAT_GOOD);
|
||||
ahd_platform_set_tags(ahd, sdev, &devinfo,
|
||||
(dev->flags & AHD_DEV_Q_BASIC)
|
||||
? AHD_QUEUE_BASIC : AHD_QUEUE_TAGGED);
|
||||
@ -2007,7 +2007,7 @@ ahd_linux_handle_scsi_status(struct ahd_softc *ahd,
|
||||
ahd_platform_set_tags(ahd, sdev, &devinfo,
|
||||
(dev->flags & AHD_DEV_Q_BASIC)
|
||||
? AHD_QUEUE_BASIC : AHD_QUEUE_TAGGED);
|
||||
ahd_set_scsi_status(scb, SCSI_STATUS_BUSY);
|
||||
ahd_set_scsi_status(scb, SAM_STAT_BUSY);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2039,8 +2039,8 @@ ahd_linux_queue_cmd_complete(struct ahd_softc *ahd, struct scsi_cmnd *cmd)
|
||||
scsi_status = ahd_cmd_get_scsi_status(cmd);
|
||||
|
||||
switch(scsi_status) {
|
||||
case SCSI_STATUS_CMD_TERMINATED:
|
||||
case SCSI_STATUS_CHECK_COND:
|
||||
case SAM_STAT_COMMAND_TERMINATED:
|
||||
case SAM_STAT_CHECK_CONDITION:
|
||||
if ((cmd->result >> 24) != DRIVER_SENSE) {
|
||||
do_fallback = 1;
|
||||
} else {
|
||||
|
@ -242,7 +242,7 @@ struct ahd_linux_device {
|
||||
int active;
|
||||
|
||||
/*
|
||||
* The currently allowed number of
|
||||
* The currently allowed number of
|
||||
* transactions that can be queued to
|
||||
* the device. Must be signed for
|
||||
* conversion from tagged to untagged
|
||||
@ -256,7 +256,7 @@ struct ahd_linux_device {
|
||||
* device's queue is halted.
|
||||
*/
|
||||
u_int qfrozen;
|
||||
|
||||
|
||||
/*
|
||||
* Cumulative command counter.
|
||||
*/
|
||||
@ -340,11 +340,11 @@ struct ahd_platform_data {
|
||||
/*
|
||||
* Fields accessed from interrupt context.
|
||||
*/
|
||||
struct scsi_target *starget[AHD_NUM_TARGETS];
|
||||
struct scsi_target *starget[AHD_NUM_TARGETS];
|
||||
|
||||
spinlock_t spin_lock;
|
||||
struct completion *eh_done;
|
||||
struct Scsi_Host *host; /* pointer to scsi host */
|
||||
struct Scsi_Host *host; /* pointer to scsi host */
|
||||
#define AHD_LINUX_NOIRQ ((uint32_t)~0)
|
||||
uint32_t irq; /* IRQ for this adapter */
|
||||
uint32_t bios_address;
|
||||
@ -497,29 +497,6 @@ int ahd_proc_write_seeprom(struct Scsi_Host *, char *, int);
|
||||
int ahd_linux_show_info(struct seq_file *,struct Scsi_Host *);
|
||||
|
||||
/*********************** Transaction Access Wrappers **************************/
|
||||
static inline void ahd_cmd_set_transaction_status(struct scsi_cmnd *, uint32_t);
|
||||
static inline void ahd_set_transaction_status(struct scb *, uint32_t);
|
||||
static inline void ahd_cmd_set_scsi_status(struct scsi_cmnd *, uint32_t);
|
||||
static inline void ahd_set_scsi_status(struct scb *, uint32_t);
|
||||
static inline uint32_t ahd_cmd_get_transaction_status(struct scsi_cmnd *cmd);
|
||||
static inline uint32_t ahd_get_transaction_status(struct scb *);
|
||||
static inline uint32_t ahd_cmd_get_scsi_status(struct scsi_cmnd *cmd);
|
||||
static inline uint32_t ahd_get_scsi_status(struct scb *);
|
||||
static inline void ahd_set_transaction_tag(struct scb *, int, u_int);
|
||||
static inline u_long ahd_get_transfer_length(struct scb *);
|
||||
static inline int ahd_get_transfer_dir(struct scb *);
|
||||
static inline void ahd_set_residual(struct scb *, u_long);
|
||||
static inline void ahd_set_sense_residual(struct scb *scb, u_long resid);
|
||||
static inline u_long ahd_get_residual(struct scb *);
|
||||
static inline u_long ahd_get_sense_residual(struct scb *);
|
||||
static inline int ahd_perform_autosense(struct scb *);
|
||||
static inline uint32_t ahd_get_sense_bufsize(struct ahd_softc *,
|
||||
struct scb *);
|
||||
static inline void ahd_notify_xfer_settings_change(struct ahd_softc *,
|
||||
struct ahd_devinfo *);
|
||||
static inline void ahd_platform_scb_free(struct ahd_softc *ahd,
|
||||
struct scb *scb);
|
||||
static inline void ahd_freeze_scb(struct scb *scb);
|
||||
|
||||
static inline
|
||||
void ahd_cmd_set_transaction_status(struct scsi_cmnd *cmd, uint32_t status)
|
||||
@ -655,9 +632,9 @@ static inline void
|
||||
ahd_freeze_scb(struct scb *scb)
|
||||
{
|
||||
if ((scb->io_ctx->result & (CAM_DEV_QFRZN << 16)) == 0) {
|
||||
scb->io_ctx->result |= CAM_DEV_QFRZN << 16;
|
||||
scb->platform_data->dev->qfrozen++;
|
||||
}
|
||||
scb->io_ctx->result |= CAM_DEV_QFRZN << 16;
|
||||
scb->platform_data->dev->qfrozen++;
|
||||
}
|
||||
}
|
||||
|
||||
void ahd_platform_set_tags(struct ahd_softc *ahd, struct scsi_device *sdev,
|
||||
|
@ -45,8 +45,8 @@
|
||||
|
||||
/* Define the macro locally since it's different for different class of chips.
|
||||
*/
|
||||
#define ID(x) \
|
||||
ID2C(x), \
|
||||
#define ID(x) \
|
||||
ID2C(x), \
|
||||
ID2C(IDIROC(x))
|
||||
|
||||
static const struct pci_device_id ahd_linux_pci_id_table[] = {
|
||||
@ -367,7 +367,7 @@ ahd_pci_map_int(struct ahd_softc *ahd)
|
||||
IRQF_SHARED, "aic79xx", ahd);
|
||||
if (!error)
|
||||
ahd->platform_data->irq = ahd->dev_softc->irq;
|
||||
|
||||
|
||||
return (-error);
|
||||
}
|
||||
|
||||
|
@ -100,17 +100,17 @@ ahd_format_transinfo(struct seq_file *m, struct ahd_transinfo *tinfo)
|
||||
seq_puts(m, "Renegotiation Pending\n");
|
||||
return;
|
||||
}
|
||||
speed = 3300;
|
||||
freq = 0;
|
||||
speed = 3300;
|
||||
freq = 0;
|
||||
if (tinfo->offset != 0) {
|
||||
freq = ahd_calc_syncsrate(tinfo->period);
|
||||
speed = freq;
|
||||
}
|
||||
speed *= (0x01 << tinfo->width);
|
||||
mb = speed / 1000;
|
||||
if (mb > 0)
|
||||
mb = speed / 1000;
|
||||
if (mb > 0)
|
||||
seq_printf(m, "%d.%03dMB/s transfers", mb, speed % 1000);
|
||||
else
|
||||
else
|
||||
seq_printf(m, "%dKB/s transfers", speed);
|
||||
|
||||
if (freq != 0) {
|
||||
@ -242,7 +242,8 @@ ahd_proc_write_seeprom(struct Scsi_Host *shost, char *buffer, int length)
|
||||
u_int start_addr;
|
||||
|
||||
if (ahd->seep_config == NULL) {
|
||||
ahd->seep_config = kmalloc(sizeof(*ahd->seep_config), GFP_ATOMIC);
|
||||
ahd->seep_config = kmalloc(sizeof(*ahd->seep_config),
|
||||
GFP_ATOMIC);
|
||||
if (ahd->seep_config == NULL) {
|
||||
printk("aic79xx: Unable to allocate serial "
|
||||
"eeprom buffer. Write failing\n");
|
||||
|
@ -73,8 +73,8 @@
|
||||
* add other 93Cx6 functions.
|
||||
*/
|
||||
struct seeprom_cmd {
|
||||
uint8_t len;
|
||||
uint8_t bits[11];
|
||||
uint8_t len;
|
||||
uint8_t bits[11];
|
||||
};
|
||||
|
||||
/* Short opcodes for the c46 */
|
||||
|
@ -66,7 +66,7 @@ static const char *const ahc_chip_names[] = {
|
||||
* Hardware error codes.
|
||||
*/
|
||||
struct ahc_hard_error_entry {
|
||||
uint8_t errno;
|
||||
uint8_t errno;
|
||||
const char *errmesg;
|
||||
};
|
||||
|
||||
@ -84,16 +84,16 @@ static const u_int num_errors = ARRAY_SIZE(ahc_hard_errors);
|
||||
|
||||
static const struct ahc_phase_table_entry ahc_phase_table[] =
|
||||
{
|
||||
{ P_DATAOUT, MSG_NOOP, "in Data-out phase" },
|
||||
{ P_DATAIN, MSG_INITIATOR_DET_ERR, "in Data-in phase" },
|
||||
{ P_DATAOUT_DT, MSG_NOOP, "in DT Data-out phase" },
|
||||
{ P_DATAIN_DT, MSG_INITIATOR_DET_ERR, "in DT Data-in phase" },
|
||||
{ P_COMMAND, MSG_NOOP, "in Command phase" },
|
||||
{ P_MESGOUT, MSG_NOOP, "in Message-out phase" },
|
||||
{ P_STATUS, MSG_INITIATOR_DET_ERR, "in Status phase" },
|
||||
{ P_DATAOUT, NOP, "in Data-out phase" },
|
||||
{ P_DATAIN, INITIATOR_ERROR, "in Data-in phase" },
|
||||
{ P_DATAOUT_DT, NOP, "in DT Data-out phase" },
|
||||
{ P_DATAIN_DT, INITIATOR_ERROR, "in DT Data-in phase" },
|
||||
{ P_COMMAND, NOP, "in Command phase" },
|
||||
{ P_MESGOUT, NOP, "in Message-out phase" },
|
||||
{ P_STATUS, INITIATOR_ERROR, "in Status phase" },
|
||||
{ P_MESGIN, MSG_PARITY_ERROR, "in Message-in phase" },
|
||||
{ P_BUSFREE, MSG_NOOP, "while idle" },
|
||||
{ 0, MSG_NOOP, "in unknown phase" }
|
||||
{ P_BUSFREE, NOP, "while idle" },
|
||||
{ 0, NOP, "in unknown phase" }
|
||||
};
|
||||
|
||||
/*
|
||||
@ -142,7 +142,7 @@ static void ahc_free_tstate(struct ahc_softc *ahc,
|
||||
#endif
|
||||
static const struct ahc_syncrate*
|
||||
ahc_devlimited_syncrate(struct ahc_softc *ahc,
|
||||
struct ahc_initiator_tinfo *,
|
||||
struct ahc_initiator_tinfo *,
|
||||
u_int *period,
|
||||
u_int *ppr_options,
|
||||
role_t role);
|
||||
@ -195,7 +195,7 @@ static void ahc_setup_target_msgin(struct ahc_softc *ahc,
|
||||
struct scb *scb);
|
||||
#endif
|
||||
|
||||
static bus_dmamap_callback_t ahc_dmamap_cb;
|
||||
static bus_dmamap_callback_t ahc_dmamap_cb;
|
||||
static void ahc_build_free_scb_list(struct ahc_softc *ahc);
|
||||
static int ahc_init_scbdata(struct ahc_softc *ahc);
|
||||
static void ahc_fini_scbdata(struct ahc_softc *ahc);
|
||||
@ -815,7 +815,7 @@ ahc_restart(struct ahc_softc *ahc)
|
||||
ahc_clear_msg_state(ahc);
|
||||
|
||||
ahc_outb(ahc, SCSISIGO, 0); /* De-assert BSY */
|
||||
ahc_outb(ahc, MSG_OUT, MSG_NOOP); /* No message to send */
|
||||
ahc_outb(ahc, MSG_OUT, NOP); /* No message to send */
|
||||
ahc_outb(ahc, SXFRCTL1, ahc_inb(ahc, SXFRCTL1) & ~BITBUCKET);
|
||||
ahc_outb(ahc, LASTPHASE, P_BUSFREE);
|
||||
ahc_outb(ahc, SAVED_SCSIID, 0xFF);
|
||||
@ -978,7 +978,7 @@ ahc_handle_seqint(struct ahc_softc *ahc, u_int intstat)
|
||||
{
|
||||
struct scb *scb;
|
||||
struct ahc_devinfo devinfo;
|
||||
|
||||
|
||||
ahc_fetch_devinfo(ahc, &devinfo);
|
||||
|
||||
/*
|
||||
@ -1022,7 +1022,7 @@ ahc_handle_seqint(struct ahc_softc *ahc, u_int intstat)
|
||||
goto unpause;
|
||||
}
|
||||
|
||||
hscb = scb->hscb;
|
||||
hscb = scb->hscb;
|
||||
|
||||
/* Don't want to clobber the original sense code */
|
||||
if ((scb->flags & SCB_SENSE) != 0) {
|
||||
@ -1041,12 +1041,12 @@ ahc_handle_seqint(struct ahc_softc *ahc, u_int intstat)
|
||||
ahc_freeze_scb(scb);
|
||||
ahc_set_scsi_status(scb, hscb->shared_data.status.scsi_status);
|
||||
switch (hscb->shared_data.status.scsi_status) {
|
||||
case SCSI_STATUS_OK:
|
||||
case SAM_STAT_GOOD:
|
||||
printk("%s: Interrupted for status of 0???\n",
|
||||
ahc_name(ahc));
|
||||
break;
|
||||
case SCSI_STATUS_CMD_TERMINATED:
|
||||
case SCSI_STATUS_CHECK_COND:
|
||||
case SAM_STAT_COMMAND_TERMINATED:
|
||||
case SAM_STAT_CHECK_CONDITION:
|
||||
{
|
||||
struct ahc_dma_seg *sg;
|
||||
struct scsi_sense *sc;
|
||||
@ -1071,7 +1071,7 @@ ahc_handle_seqint(struct ahc_softc *ahc, u_int intstat)
|
||||
&tstate);
|
||||
tinfo = &targ_info->curr;
|
||||
sg = scb->sg_list;
|
||||
sc = (struct scsi_sense *)(&hscb->shared_data.cdb);
|
||||
sc = (struct scsi_sense *)(&hscb->shared_data.cdb);
|
||||
/*
|
||||
* Save off the residual if there is one.
|
||||
*/
|
||||
@ -1117,8 +1117,8 @@ ahc_handle_seqint(struct ahc_softc *ahc, u_int intstat)
|
||||
* errors will be reported before any data
|
||||
* phases occur.
|
||||
*/
|
||||
if (ahc_get_residual(scb)
|
||||
== ahc_get_transfer_length(scb)) {
|
||||
if (ahc_get_residual(scb)
|
||||
== ahc_get_transfer_length(scb)) {
|
||||
ahc_update_neg_request(ahc, &devinfo,
|
||||
tstate, targ_info,
|
||||
AHC_NEG_IF_NON_ASYNC);
|
||||
@ -1129,7 +1129,7 @@ ahc_handle_seqint(struct ahc_softc *ahc, u_int intstat)
|
||||
scb->flags |= SCB_AUTO_NEGOTIATE;
|
||||
}
|
||||
hscb->cdb_len = sizeof(*sc);
|
||||
hscb->dataptr = sg->addr;
|
||||
hscb->dataptr = sg->addr;
|
||||
hscb->datacnt = sg->len;
|
||||
hscb->sgptr = scb->sg_list_phys | SG_FULL_RESID;
|
||||
hscb->sgptr = ahc_htole32(hscb->sgptr);
|
||||
@ -1179,7 +1179,7 @@ ahc_handle_seqint(struct ahc_softc *ahc, u_int intstat)
|
||||
printk("SXFRCTL0 == 0x%x\n", ahc_inb(ahc, SXFRCTL0));
|
||||
printk("SEQCTL == 0x%x\n", ahc_inb(ahc, SEQCTL));
|
||||
ahc_dump_card_state(ahc);
|
||||
ahc->msgout_buf[0] = MSG_BUS_DEV_RESET;
|
||||
ahc->msgout_buf[0] = TARGET_RESET;
|
||||
ahc->msgout_len = 1;
|
||||
ahc->msgout_index = 0;
|
||||
ahc->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
|
||||
@ -1187,13 +1187,13 @@ ahc_handle_seqint(struct ahc_softc *ahc, u_int intstat)
|
||||
ahc_assert_atn(ahc);
|
||||
break;
|
||||
}
|
||||
case SEND_REJECT:
|
||||
case SEND_REJECT:
|
||||
{
|
||||
u_int rejbyte = ahc_inb(ahc, ACCUM);
|
||||
printk("%s:%c:%d: Warning - unknown message received from "
|
||||
"target (0x%x). Rejecting\n",
|
||||
"target (0x%x). Rejecting\n",
|
||||
ahc_name(ahc), devinfo.channel, devinfo.target, rejbyte);
|
||||
break;
|
||||
break;
|
||||
}
|
||||
case PROTO_VIOLATION:
|
||||
{
|
||||
@ -1286,8 +1286,7 @@ ahc_handle_seqint(struct ahc_softc *ahc, u_int intstat)
|
||||
ahc->msg_type =
|
||||
MSG_TYPE_TARGET_MSGOUT;
|
||||
ahc->msgin_index = 0;
|
||||
}
|
||||
else
|
||||
} else
|
||||
ahc_setup_target_msgin(ahc,
|
||||
&devinfo,
|
||||
scb);
|
||||
@ -1359,7 +1358,7 @@ ahc_handle_seqint(struct ahc_softc *ahc, u_int intstat)
|
||||
if (scb != NULL)
|
||||
ahc_set_transaction_status(scb,
|
||||
CAM_UNCOR_PARITY);
|
||||
ahc_reset_channel(ahc, devinfo.channel,
|
||||
ahc_reset_channel(ahc, devinfo.channel,
|
||||
/*init reset*/TRUE);
|
||||
}
|
||||
} else {
|
||||
@ -1391,7 +1390,7 @@ ahc_handle_seqint(struct ahc_softc *ahc, u_int intstat)
|
||||
printk("data overrun detected %s."
|
||||
" Tag == 0x%x.\n",
|
||||
ahc_phase_table[i].phasemsg,
|
||||
scb->hscb->tag);
|
||||
scb->hscb->tag);
|
||||
ahc_print_path(ahc, scb);
|
||||
printk("%s seen Data Phase. Length = %ld. NumSGs = %d.\n",
|
||||
ahc_inb(ahc, SEQ_FLAGS) & DPHASE ? "Have" : "Haven't",
|
||||
@ -1402,7 +1401,7 @@ ahc_handle_seqint(struct ahc_softc *ahc, u_int intstat)
|
||||
printk("sg[%d] - Addr 0x%x%x : Length %d\n",
|
||||
i,
|
||||
(ahc_le32toh(scb->sg_list[i].len) >> 24
|
||||
& SG_HIGH_ADDR_BITS),
|
||||
& SG_HIGH_ADDR_BITS),
|
||||
ahc_le32toh(scb->sg_list[i].addr),
|
||||
ahc_le32toh(scb->sg_list[i].len)
|
||||
& AHC_SG_LEN_MASK);
|
||||
@ -1549,7 +1548,7 @@ ahc_handle_scsiint(struct ahc_softc *ahc, u_int intstat)
|
||||
if (status == 0 && status0 == 0) {
|
||||
if ((ahc->features & AHC_TWIN) != 0) {
|
||||
/* Try the other channel */
|
||||
ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) ^ SELBUSB);
|
||||
ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) ^ SELBUSB);
|
||||
status = ahc_inb(ahc, SSTAT1)
|
||||
& (SELTO|SCSIRSTI|BUSFREE|SCSIPERR);
|
||||
intr_channel = (cur_channel == 'A') ? 'B' : 'A';
|
||||
@ -1595,7 +1594,7 @@ ahc_handle_scsiint(struct ahc_softc *ahc, u_int intstat)
|
||||
printk("%s: Someone reset channel %c\n",
|
||||
ahc_name(ahc), intr_channel);
|
||||
if (intr_channel != cur_channel)
|
||||
ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) ^ SELBUSB);
|
||||
ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) ^ SELBUSB);
|
||||
ahc_reset_channel(ahc, intr_channel, /*Initiate Reset*/FALSE);
|
||||
} else if ((status & SCSIPERR) != 0) {
|
||||
/*
|
||||
@ -1684,17 +1683,17 @@ ahc_handle_scsiint(struct ahc_softc *ahc, u_int intstat)
|
||||
* data direction, so ignore the value
|
||||
* in the phase table.
|
||||
*/
|
||||
mesg_out = MSG_INITIATOR_DET_ERR;
|
||||
mesg_out = INITIATOR_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* We've set the hardware to assert ATN if we
|
||||
* get a parity error on "in" phases, so all we
|
||||
* We've set the hardware to assert ATN if we
|
||||
* get a parity error on "in" phases, so all we
|
||||
* need to do is stuff the message buffer with
|
||||
* the appropriate message. "In" phases have set
|
||||
* mesg_out to something other than MSG_NOP.
|
||||
*/
|
||||
if (mesg_out != MSG_NOOP) {
|
||||
if (mesg_out != NOP) {
|
||||
if (ahc->msg_type != MSG_TYPE_NONE)
|
||||
ahc->send_msg_perror = TRUE;
|
||||
else
|
||||
@ -1818,10 +1817,10 @@ ahc_handle_scsiint(struct ahc_softc *ahc, u_int intstat)
|
||||
u_int tag;
|
||||
|
||||
tag = SCB_LIST_NULL;
|
||||
if (ahc_sent_msg(ahc, AHCMSG_1B, MSG_ABORT_TAG, TRUE)
|
||||
|| ahc_sent_msg(ahc, AHCMSG_1B, MSG_ABORT, TRUE)) {
|
||||
if (ahc_sent_msg(ahc, AHCMSG_1B, ABORT_TASK, TRUE)
|
||||
|| ahc_sent_msg(ahc, AHCMSG_1B, ABORT_TASK_SET, TRUE)) {
|
||||
if (ahc->msgout_buf[ahc->msgout_index - 1]
|
||||
== MSG_ABORT_TAG)
|
||||
== ABORT_TASK)
|
||||
tag = scb->hscb->tag;
|
||||
ahc_print_path(ahc, scb);
|
||||
printk("SCB %d - Abort%s Completed.\n",
|
||||
@ -1833,7 +1832,7 @@ ahc_handle_scsiint(struct ahc_softc *ahc, u_int intstat)
|
||||
CAM_REQ_ABORTED);
|
||||
printerror = 0;
|
||||
} else if (ahc_sent_msg(ahc, AHCMSG_1B,
|
||||
MSG_BUS_DEV_RESET, TRUE)) {
|
||||
TARGET_RESET, TRUE)) {
|
||||
ahc_compile_devinfo(&devinfo,
|
||||
initiator_role_id,
|
||||
target,
|
||||
@ -1846,7 +1845,7 @@ ahc_handle_scsiint(struct ahc_softc *ahc, u_int intstat)
|
||||
/*verbose_level*/0);
|
||||
printerror = 0;
|
||||
} else if (ahc_sent_msg(ahc, AHCMSG_EXT,
|
||||
MSG_EXT_PPR, FALSE)) {
|
||||
EXTENDED_PPR, FALSE)) {
|
||||
struct ahc_initiator_tinfo *tinfo;
|
||||
struct ahc_tmode_tstate *tstate;
|
||||
|
||||
@ -1865,7 +1864,7 @@ ahc_handle_scsiint(struct ahc_softc *ahc, u_int intstat)
|
||||
ahc_qinfifo_requeue_tail(ahc, scb);
|
||||
printerror = 0;
|
||||
} else if (ahc_sent_msg(ahc, AHCMSG_EXT,
|
||||
MSG_EXT_WDTR, FALSE)) {
|
||||
EXTENDED_WDTR, FALSE)) {
|
||||
/*
|
||||
* Negotiation Rejected. Go-narrow and
|
||||
* retry command.
|
||||
@ -1877,7 +1876,7 @@ ahc_handle_scsiint(struct ahc_softc *ahc, u_int intstat)
|
||||
ahc_qinfifo_requeue_tail(ahc, scb);
|
||||
printerror = 0;
|
||||
} else if (ahc_sent_msg(ahc, AHCMSG_EXT,
|
||||
MSG_EXT_SDTR, FALSE)) {
|
||||
EXTENDED_SDTR, FALSE)) {
|
||||
/*
|
||||
* Negotiation Rejected. Go-async and
|
||||
* retry command.
|
||||
@ -1986,7 +1985,7 @@ ahc_clear_critical_section(struct ahc_softc *ahc)
|
||||
| (ahc_inb(ahc, SEQADDR1) << 8);
|
||||
|
||||
/*
|
||||
* Seqaddr represents the next instruction to execute,
|
||||
* Seqaddr represents the next instruction to execute,
|
||||
* so we are really executing the instruction just
|
||||
* before it.
|
||||
*/
|
||||
@ -1994,7 +1993,6 @@ ahc_clear_critical_section(struct ahc_softc *ahc)
|
||||
seqaddr -= 1;
|
||||
cs = ahc->critical_sections;
|
||||
for (i = 0; i < ahc->num_critical_sections; i++, cs++) {
|
||||
|
||||
if (cs->begin < seqaddr && cs->end >= seqaddr)
|
||||
break;
|
||||
}
|
||||
@ -2064,7 +2062,7 @@ ahc_clear_intstat(struct ahc_softc *ahc)
|
||||
CLRREQINIT);
|
||||
ahc_flush_device_writes(ahc);
|
||||
ahc_outb(ahc, CLRSINT0, CLRSELDO|CLRSELDI|CLRSELINGO);
|
||||
ahc_flush_device_writes(ahc);
|
||||
ahc_flush_device_writes(ahc);
|
||||
ahc_outb(ahc, CLRINT, CLRSCSIINT);
|
||||
ahc_flush_device_writes(ahc);
|
||||
}
|
||||
@ -2101,7 +2099,7 @@ ahc_print_scb(struct scb *scb)
|
||||
printk("sg[%d] - Addr 0x%x%x : Length %d\n",
|
||||
i,
|
||||
(ahc_le32toh(scb->sg_list[i].len) >> 24
|
||||
& SG_HIGH_ADDR_BITS),
|
||||
& SG_HIGH_ADDR_BITS),
|
||||
ahc_le32toh(scb->sg_list[i].addr),
|
||||
ahc_le32toh(scb->sg_list[i].len));
|
||||
}
|
||||
@ -2223,7 +2221,7 @@ ahc_devlimited_syncrate(struct ahc_softc *ahc,
|
||||
*/
|
||||
if (role == ROLE_TARGET)
|
||||
transinfo = &tinfo->user;
|
||||
else
|
||||
else
|
||||
transinfo = &tinfo->goal;
|
||||
*ppr_options &= transinfo->ppr_options;
|
||||
if (transinfo->width == MSG_EXT_WDTR_BUS_8_BIT) {
|
||||
@ -2655,9 +2653,9 @@ ahc_set_tags(struct ahc_softc *ahc, struct scsi_cmnd *cmd,
|
||||
{
|
||||
struct scsi_device *sdev = cmd->device;
|
||||
|
||||
ahc_platform_set_tags(ahc, sdev, devinfo, alg);
|
||||
ahc_send_async(ahc, devinfo->channel, devinfo->target,
|
||||
devinfo->lun, AC_TRANSFER_NEG);
|
||||
ahc_platform_set_tags(ahc, sdev, devinfo, alg);
|
||||
ahc_send_async(ahc, devinfo->channel, devinfo->target,
|
||||
devinfo->lun, AC_TRANSFER_NEG);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2756,9 +2754,9 @@ ahc_fetch_devinfo(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
|
||||
role = ROLE_INITIATOR;
|
||||
|
||||
if (role == ROLE_TARGET
|
||||
&& (ahc->features & AHC_MULTI_TID) != 0
|
||||
&& (ahc_inb(ahc, SEQ_FLAGS)
|
||||
& (CMDPHASE_PENDING|TARG_CMD_PENDING|NO_DISCONNECT)) != 0) {
|
||||
&& (ahc->features & AHC_MULTI_TID) != 0
|
||||
&& (ahc_inb(ahc, SEQ_FLAGS)
|
||||
& (CMDPHASE_PENDING|TARG_CMD_PENDING|NO_DISCONNECT)) != 0) {
|
||||
/* We were selected, so pull our id from TARGIDIN */
|
||||
our_id = ahc_inb(ahc, TARGIDIN) & OID;
|
||||
} else if ((ahc->features & AHC_ULTRA2) != 0)
|
||||
@ -2880,7 +2878,7 @@ ahc_setup_initiator_msgout(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
|
||||
}
|
||||
|
||||
if (scb->flags & SCB_DEVICE_RESET) {
|
||||
ahc->msgout_buf[ahc->msgout_index++] = MSG_BUS_DEV_RESET;
|
||||
ahc->msgout_buf[ahc->msgout_index++] = TARGET_RESET;
|
||||
ahc->msgout_len++;
|
||||
ahc_print_path(ahc, scb);
|
||||
printk("Bus Device Reset Message Sent\n");
|
||||
@ -2894,9 +2892,9 @@ ahc_setup_initiator_msgout(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
|
||||
ahc_outb(ahc, SCSISEQ, (ahc_inb(ahc, SCSISEQ) & ~ENSELO));
|
||||
} else if ((scb->flags & SCB_ABORT) != 0) {
|
||||
if ((scb->hscb->control & TAG_ENB) != 0)
|
||||
ahc->msgout_buf[ahc->msgout_index++] = MSG_ABORT_TAG;
|
||||
ahc->msgout_buf[ahc->msgout_index++] = ABORT_TASK;
|
||||
else
|
||||
ahc->msgout_buf[ahc->msgout_index++] = MSG_ABORT;
|
||||
ahc->msgout_buf[ahc->msgout_index++] = ABORT_TASK_SET;
|
||||
ahc->msgout_len++;
|
||||
ahc_print_path(ahc, scb);
|
||||
printk("Abort%s Message Sent\n",
|
||||
@ -3106,7 +3104,7 @@ ahc_clear_msg_state(struct ahc_softc *ahc)
|
||||
*/
|
||||
ahc_outb(ahc, CLRSINT1, CLRATNO);
|
||||
}
|
||||
ahc_outb(ahc, MSG_OUT, MSG_NOOP);
|
||||
ahc_outb(ahc, MSG_OUT, NOP);
|
||||
ahc_outb(ahc, SEQ_FLAGS2,
|
||||
ahc_inb(ahc, SEQ_FLAGS2) & ~TARGET_MSG_PENDING);
|
||||
}
|
||||
@ -3192,7 +3190,7 @@ ahc_handle_proto_violation(struct ahc_softc *ahc)
|
||||
ahc_outb(ahc, MSG_OUT, HOST_MSG);
|
||||
if (scb == NULL) {
|
||||
ahc_print_devinfo(ahc, &devinfo);
|
||||
ahc->msgout_buf[0] = MSG_ABORT_TASK;
|
||||
ahc->msgout_buf[0] = ABORT_TASK;
|
||||
ahc->msgout_len = 1;
|
||||
ahc->msgout_index = 0;
|
||||
ahc->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
|
||||
@ -3366,7 +3364,7 @@ ahc_handle_message_phase(struct ahc_softc *ahc)
|
||||
#endif
|
||||
ahc_assert_atn(ahc);
|
||||
}
|
||||
} else
|
||||
} else
|
||||
ahc->msgin_index++;
|
||||
|
||||
if (message_done == MSGLOOP_TERMINATED) {
|
||||
@ -3459,7 +3457,7 @@ ahc_handle_message_phase(struct ahc_softc *ahc)
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
ahc->msgin_index++;
|
||||
|
||||
/*
|
||||
@ -3520,7 +3518,7 @@ ahc_sent_msg(struct ahc_softc *ahc, ahc_msgtype type, u_int msgval, int full)
|
||||
index = 0;
|
||||
|
||||
while (index < ahc->msgout_len) {
|
||||
if (ahc->msgout_buf[index] == MSG_EXTENDED) {
|
||||
if (ahc->msgout_buf[index] == EXTENDED_MESSAGE) {
|
||||
u_int end_index;
|
||||
|
||||
end_index = index + 1 + ahc->msgout_buf[index + 1];
|
||||
@ -3534,8 +3532,8 @@ ahc_sent_msg(struct ahc_softc *ahc, ahc_msgtype type, u_int msgval, int full)
|
||||
found = TRUE;
|
||||
}
|
||||
index = end_index;
|
||||
} else if (ahc->msgout_buf[index] >= MSG_SIMPLE_TASK
|
||||
&& ahc->msgout_buf[index] <= MSG_IGN_WIDE_RESIDUE) {
|
||||
} else if (ahc->msgout_buf[index] >= SIMPLE_QUEUE_TAG
|
||||
&& ahc->msgout_buf[index] <= IGNORE_WIDE_RESIDUE) {
|
||||
|
||||
/* Skip tag type and tag id or residue param*/
|
||||
index += 2;
|
||||
@ -3586,37 +3584,37 @@ ahc_parse_msg(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
|
||||
* extended message type.
|
||||
*/
|
||||
switch (ahc->msgin_buf[0]) {
|
||||
case MSG_DISCONNECT:
|
||||
case MSG_SAVEDATAPOINTER:
|
||||
case MSG_CMDCOMPLETE:
|
||||
case MSG_RESTOREPOINTERS:
|
||||
case MSG_IGN_WIDE_RESIDUE:
|
||||
case DISCONNECT:
|
||||
case SAVE_POINTERS:
|
||||
case COMMAND_COMPLETE:
|
||||
case RESTORE_POINTERS:
|
||||
case IGNORE_WIDE_RESIDUE:
|
||||
/*
|
||||
* End our message loop as these are messages
|
||||
* the sequencer handles on its own.
|
||||
*/
|
||||
done = MSGLOOP_TERMINATED;
|
||||
break;
|
||||
case MSG_MESSAGE_REJECT:
|
||||
case MESSAGE_REJECT:
|
||||
response = ahc_handle_msg_reject(ahc, devinfo);
|
||||
fallthrough;
|
||||
case MSG_NOOP:
|
||||
case NOP:
|
||||
done = MSGLOOP_MSGCOMPLETE;
|
||||
break;
|
||||
case MSG_EXTENDED:
|
||||
case EXTENDED_MESSAGE:
|
||||
{
|
||||
/* Wait for enough of the message to begin validation */
|
||||
if (ahc->msgin_index < 2)
|
||||
break;
|
||||
switch (ahc->msgin_buf[2]) {
|
||||
case MSG_EXT_SDTR:
|
||||
case EXTENDED_SDTR:
|
||||
{
|
||||
const struct ahc_syncrate *syncrate;
|
||||
u_int period;
|
||||
u_int ppr_options;
|
||||
u_int offset;
|
||||
u_int saved_offset;
|
||||
|
||||
|
||||
if (ahc->msgin_buf[1] != MSG_EXT_SDTR_LEN) {
|
||||
reject = TRUE;
|
||||
break;
|
||||
@ -3650,7 +3648,7 @@ ahc_parse_msg(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
|
||||
ahc->msgin_buf[3], saved_offset,
|
||||
period, offset);
|
||||
}
|
||||
ahc_set_syncrate(ahc, devinfo,
|
||||
ahc_set_syncrate(ahc, devinfo,
|
||||
syncrate, period,
|
||||
offset, ppr_options,
|
||||
AHC_TRANS_ACTIVE|AHC_TRANS_GOAL,
|
||||
@ -3661,7 +3659,7 @@ ahc_parse_msg(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
|
||||
* and didn't have to fall down to async
|
||||
* transfers.
|
||||
*/
|
||||
if (ahc_sent_msg(ahc, AHCMSG_EXT, MSG_EXT_SDTR, TRUE)) {
|
||||
if (ahc_sent_msg(ahc, AHCMSG_EXT, EXTENDED_SDTR, TRUE)) {
|
||||
/* We started it */
|
||||
if (saved_offset != offset) {
|
||||
/* Went too low - force async */
|
||||
@ -3688,7 +3686,7 @@ ahc_parse_msg(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
|
||||
done = MSGLOOP_MSGCOMPLETE;
|
||||
break;
|
||||
}
|
||||
case MSG_EXT_WDTR:
|
||||
case EXTENDED_WDTR:
|
||||
{
|
||||
u_int bus_width;
|
||||
u_int saved_width;
|
||||
@ -3722,7 +3720,7 @@ ahc_parse_msg(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
|
||||
saved_width, bus_width);
|
||||
}
|
||||
|
||||
if (ahc_sent_msg(ahc, AHCMSG_EXT, MSG_EXT_WDTR, TRUE)) {
|
||||
if (ahc_sent_msg(ahc, AHCMSG_EXT, EXTENDED_WDTR, TRUE)) {
|
||||
/*
|
||||
* Don't send a WDTR back to the
|
||||
* target, since we asked first.
|
||||
@ -3784,7 +3782,7 @@ ahc_parse_msg(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
|
||||
done = MSGLOOP_MSGCOMPLETE;
|
||||
break;
|
||||
}
|
||||
case MSG_EXT_PPR:
|
||||
case EXTENDED_PPR:
|
||||
{
|
||||
const struct ahc_syncrate *syncrate;
|
||||
u_int period;
|
||||
@ -3844,7 +3842,7 @@ ahc_parse_msg(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
|
||||
&offset, bus_width,
|
||||
devinfo->role);
|
||||
|
||||
if (ahc_sent_msg(ahc, AHCMSG_EXT, MSG_EXT_PPR, TRUE)) {
|
||||
if (ahc_sent_msg(ahc, AHCMSG_EXT, EXTENDED_PPR, TRUE)) {
|
||||
/*
|
||||
* If we are unable to do any of the
|
||||
* requested options (we went too low),
|
||||
@ -3908,7 +3906,7 @@ ahc_parse_msg(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
|
||||
break;
|
||||
}
|
||||
#ifdef AHC_TARGET_MODE
|
||||
case MSG_BUS_DEV_RESET:
|
||||
case TARGET_RESET:
|
||||
ahc_handle_devreset(ahc, devinfo,
|
||||
CAM_BDR_SENT,
|
||||
"Bus Device Reset Received",
|
||||
@ -3916,9 +3914,9 @@ ahc_parse_msg(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
|
||||
ahc_restart(ahc);
|
||||
done = MSGLOOP_TERMINATED;
|
||||
break;
|
||||
case MSG_ABORT_TAG:
|
||||
case MSG_ABORT:
|
||||
case MSG_CLEAR_QUEUE:
|
||||
case ABORT_TASK:
|
||||
case ABORT_TASK_SET:
|
||||
case CLEAR_QUEUE_TASK_SET:
|
||||
{
|
||||
int tag;
|
||||
|
||||
@ -3928,7 +3926,7 @@ ahc_parse_msg(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
|
||||
break;
|
||||
}
|
||||
tag = SCB_LIST_NULL;
|
||||
if (ahc->msgin_buf[0] == MSG_ABORT_TAG)
|
||||
if (ahc->msgin_buf[0] == ABORT_TASK)
|
||||
tag = ahc_inb(ahc, INITIATOR_TAG);
|
||||
ahc_abort_scbs(ahc, devinfo->target, devinfo->channel,
|
||||
devinfo->lun, tag, ROLE_TARGET,
|
||||
@ -3952,7 +3950,7 @@ ahc_parse_msg(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case MSG_TERM_IO_PROC:
|
||||
case TERMINATE_IO_PROC:
|
||||
default:
|
||||
reject = TRUE;
|
||||
break;
|
||||
@ -3964,7 +3962,7 @@ ahc_parse_msg(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
|
||||
*/
|
||||
ahc->msgout_index = 0;
|
||||
ahc->msgout_len = 1;
|
||||
ahc->msgout_buf[0] = MSG_MESSAGE_REJECT;
|
||||
ahc->msgout_buf[0] = MESSAGE_REJECT;
|
||||
done = MSGLOOP_MSGCOMPLETE;
|
||||
response = TRUE;
|
||||
}
|
||||
@ -4003,7 +4001,7 @@ ahc_handle_msg_reject(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
|
||||
/* Might be necessary */
|
||||
last_msg = ahc_inb(ahc, LAST_MSG);
|
||||
|
||||
if (ahc_sent_msg(ahc, AHCMSG_EXT, MSG_EXT_PPR, /*full*/FALSE)) {
|
||||
if (ahc_sent_msg(ahc, AHCMSG_EXT, EXTENDED_PPR, /*full*/FALSE)) {
|
||||
/*
|
||||
* Target does not support the PPR message.
|
||||
* Attempt to negotiate SPI-2 style.
|
||||
@ -4022,7 +4020,7 @@ ahc_handle_msg_reject(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
|
||||
ahc_build_transfer_msg(ahc, devinfo);
|
||||
ahc->msgout_index = 0;
|
||||
response = 1;
|
||||
} else if (ahc_sent_msg(ahc, AHCMSG_EXT, MSG_EXT_WDTR, /*full*/FALSE)) {
|
||||
} else if (ahc_sent_msg(ahc, AHCMSG_EXT, EXTENDED_WDTR, /*full*/FALSE)) {
|
||||
|
||||
/* note 8bit xfers */
|
||||
printk("(%s:%c:%d:%d): refuses WIDE negotiation. Using "
|
||||
@ -4047,7 +4045,7 @@ ahc_handle_msg_reject(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
|
||||
ahc->msgout_index = 0;
|
||||
response = 1;
|
||||
}
|
||||
} else if (ahc_sent_msg(ahc, AHCMSG_EXT, MSG_EXT_SDTR, /*full*/FALSE)) {
|
||||
} else if (ahc_sent_msg(ahc, AHCMSG_EXT, EXTENDED_SDTR, /*full*/FALSE)) {
|
||||
/* note asynch xfers and clear flag */
|
||||
ahc_set_syncrate(ahc, devinfo, /*syncrate*/NULL, /*period*/0,
|
||||
/*offset*/0, /*ppr_options*/0,
|
||||
@ -4057,13 +4055,13 @@ ahc_handle_msg_reject(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
|
||||
"Using asynchronous transfers\n",
|
||||
ahc_name(ahc), devinfo->channel,
|
||||
devinfo->target, devinfo->lun);
|
||||
} else if ((scb->hscb->control & MSG_SIMPLE_TASK) != 0) {
|
||||
} else if ((scb->hscb->control & SIMPLE_QUEUE_TAG) != 0) {
|
||||
int tag_type;
|
||||
int mask;
|
||||
|
||||
tag_type = (scb->hscb->control & MSG_SIMPLE_TASK);
|
||||
tag_type = (scb->hscb->control & SIMPLE_QUEUE_TAG);
|
||||
|
||||
if (tag_type == MSG_SIMPLE_TASK) {
|
||||
if (tag_type == SIMPLE_QUEUE_TAG) {
|
||||
printk("(%s:%c:%d:%d): refuses tagged commands. "
|
||||
"Performing non-tagged I/O\n", ahc_name(ahc),
|
||||
devinfo->channel, devinfo->target, devinfo->lun);
|
||||
@ -4073,7 +4071,7 @@ ahc_handle_msg_reject(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
|
||||
printk("(%s:%c:%d:%d): refuses %s tagged commands. "
|
||||
"Performing simple queue tagged I/O only\n",
|
||||
ahc_name(ahc), devinfo->channel, devinfo->target,
|
||||
devinfo->lun, tag_type == MSG_ORDERED_TASK
|
||||
devinfo->lun, tag_type == ORDERED_QUEUE_TAG
|
||||
? "ordered" : "head of queue");
|
||||
ahc_set_tags(ahc, scb->io_ctx, devinfo, AHC_QUEUE_BASIC);
|
||||
mask = ~0x03;
|
||||
@ -4085,9 +4083,9 @@ ahc_handle_msg_reject(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
|
||||
*/
|
||||
ahc_outb(ahc, SCB_CONTROL,
|
||||
ahc_inb(ahc, SCB_CONTROL) & mask);
|
||||
scb->hscb->control &= mask;
|
||||
scb->hscb->control &= mask;
|
||||
ahc_set_transaction_tag(scb, /*enabled*/FALSE,
|
||||
/*type*/MSG_SIMPLE_TASK);
|
||||
/*type*/SIMPLE_QUEUE_TAG);
|
||||
ahc_outb(ahc, MSG_OUT, MSG_IDENTIFYFLAG);
|
||||
ahc_assert_atn(ahc);
|
||||
|
||||
@ -4324,7 +4322,7 @@ ahc_handle_devreset(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
|
||||
continue;
|
||||
|
||||
ahc_queue_lstate_event(ahc, lstate, devinfo->our_scsiid,
|
||||
MSG_BUS_DEV_RESET, /*arg*/0);
|
||||
TARGET_RESET, /*arg*/0);
|
||||
ahc_send_lstate_events(ahc, lstate);
|
||||
}
|
||||
}
|
||||
@ -4338,7 +4336,7 @@ ahc_handle_devreset(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
|
||||
ahc_set_syncrate(ahc, devinfo, /*syncrate*/NULL,
|
||||
/*period*/0, /*offset*/0, /*ppr_options*/0,
|
||||
AHC_TRANS_CUR, /*paused*/TRUE);
|
||||
|
||||
|
||||
if (status != CAM_SEL_TIMEOUT)
|
||||
ahc_send_async(ahc, devinfo->channel, devinfo->target,
|
||||
CAM_LUN_WILDCARD, AC_SENT_BDR);
|
||||
@ -4355,11 +4353,11 @@ ahc_setup_target_msgin(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
|
||||
struct scb *scb)
|
||||
{
|
||||
|
||||
/*
|
||||
/*
|
||||
* To facilitate adding multiple messages together,
|
||||
* each routine should increment the index and len
|
||||
* variables instead of setting them explicitly.
|
||||
*/
|
||||
*/
|
||||
ahc->msgout_index = 0;
|
||||
ahc->msgout_len = 0;
|
||||
|
||||
@ -4432,7 +4430,7 @@ ahc_softc_init(struct ahc_softc *ahc)
|
||||
ahc->unpause = ahc_inb(ahc, HCNTRL) & IRQMS;
|
||||
else
|
||||
ahc->unpause = 0;
|
||||
ahc->pause = ahc->unpause | PAUSE;
|
||||
ahc->pause = ahc->unpause | PAUSE;
|
||||
/* XXX The shared scb data stuff should be deprecated */
|
||||
if (ahc->scb_data == NULL) {
|
||||
ahc->scb_data = kzalloc(sizeof(*ahc->scb_data), GFP_ATOMIC);
|
||||
@ -4554,7 +4552,7 @@ ahc_reset(struct ahc_softc *ahc, int reinit)
|
||||
u_int sxfrctl1_a, sxfrctl1_b;
|
||||
int error;
|
||||
int wait;
|
||||
|
||||
|
||||
/*
|
||||
* Preserve the value of the SXFRCTL1 register for all channels.
|
||||
* It contains settings that affect termination and we don't want
|
||||
@ -4643,7 +4641,7 @@ ahc_reset(struct ahc_softc *ahc, int reinit)
|
||||
*/
|
||||
error = ahc->bus_chip_init(ahc);
|
||||
#ifdef AHC_DUMP_SEQ
|
||||
else
|
||||
else
|
||||
ahc_dumpseq(ahc);
|
||||
#endif
|
||||
|
||||
@ -4708,7 +4706,7 @@ ahc_build_free_scb_list(struct ahc_softc *ahc)
|
||||
/* Set the next pointer */
|
||||
if ((ahc->flags & AHC_PAGESCBS) != 0)
|
||||
ahc_outb(ahc, SCB_NEXT, i+1);
|
||||
else
|
||||
else
|
||||
ahc_outb(ahc, SCB_NEXT, SCB_LIST_NULL);
|
||||
|
||||
/* Make the tag number, SCSIID, and lun invalid */
|
||||
@ -4861,7 +4859,7 @@ ahc_init_scbdata(struct ahc_softc *ahc)
|
||||
/*
|
||||
* Note that we were successful
|
||||
*/
|
||||
return (0);
|
||||
return (0);
|
||||
|
||||
error_exit:
|
||||
|
||||
@ -5004,7 +5002,7 @@ ahc_controller_info(struct ahc_softc *ahc, char *buf)
|
||||
len = sprintf(buf, "%s: ", ahc_chip_names[ahc->chip & AHC_CHIPID_MASK]);
|
||||
buf += len;
|
||||
if ((ahc->features & AHC_TWIN) != 0)
|
||||
len = sprintf(buf, "Twin Channel, A SCSI Id=%d, "
|
||||
len = sprintf(buf, "Twin Channel, A SCSI Id=%d, "
|
||||
"B SCSI Id=%d, primary %c, ",
|
||||
ahc->our_id, ahc->our_id_b,
|
||||
(ahc->flags & AHC_PRIMARY_CHANNEL) + 'A');
|
||||
@ -5140,7 +5138,7 @@ ahc_chip_init(struct ahc_softc *ahc)
|
||||
ahc_outb(ahc, CMDSIZE_TABLE + 5, 11);
|
||||
ahc_outb(ahc, CMDSIZE_TABLE + 6, 0);
|
||||
ahc_outb(ahc, CMDSIZE_TABLE + 7, 0);
|
||||
|
||||
|
||||
if ((ahc->features & AHC_HS_MAILBOX) != 0)
|
||||
ahc_outb(ahc, HS_MAILBOX, 0);
|
||||
|
||||
@ -5170,7 +5168,7 @@ ahc_chip_init(struct ahc_softc *ahc)
|
||||
ahc_outb(ahc, DISCONNECTED_SCBH, SCB_LIST_NULL);
|
||||
|
||||
/* Message out buffer starts empty */
|
||||
ahc_outb(ahc, MSG_OUT, MSG_NOOP);
|
||||
ahc_outb(ahc, MSG_OUT, NOP);
|
||||
|
||||
/*
|
||||
* Setup the allowed SCSI Sequences based on operational mode.
|
||||
@ -5271,7 +5269,7 @@ ahc_init(struct ahc_softc *ahc)
|
||||
*/
|
||||
if ((ahc->flags & AHC_USEDEFAULTS) != 0)
|
||||
ahc->our_id = ahc->our_id_b = 7;
|
||||
|
||||
|
||||
/*
|
||||
* Default to allowing initiator operations.
|
||||
*/
|
||||
@ -5289,7 +5287,7 @@ ahc_init(struct ahc_softc *ahc)
|
||||
* DMA tag for our command fifos and other data in system memory
|
||||
* the card's sequencer must be able to access. For initiator
|
||||
* roles, we need to allocate space for the qinfifo and qoutfifo.
|
||||
* The qinfifo and qoutfifo are composed of 256 1 byte elements.
|
||||
* The qinfifo and qoutfifo are composed of 256 1 byte elements.
|
||||
* When providing for the target mode role, we must additionally
|
||||
* provide space for the incoming target command fifo and an extra
|
||||
* byte to deal with a dma bug in some chip versions.
|
||||
@ -5398,7 +5396,7 @@ ahc_init(struct ahc_softc *ahc)
|
||||
&& (ahc->flags & AHC_INITIATORROLE) != 0)
|
||||
ahc->flags |= AHC_RESET_BUS_A;
|
||||
|
||||
ultraenb = 0;
|
||||
ultraenb = 0;
|
||||
tagenable = ALL_TARGETS_MASK;
|
||||
|
||||
/* Grab the disconnection disable table and invert it for our needs */
|
||||
@ -5494,9 +5492,9 @@ ahc_init(struct ahc_softc *ahc)
|
||||
&& (ultraenb & mask) != 0) {
|
||||
/* Treat 10MHz as a non-ultra speed */
|
||||
scsirate &= ~SXFR;
|
||||
ultraenb &= ~mask;
|
||||
ultraenb &= ~mask;
|
||||
}
|
||||
tinfo->user.period =
|
||||
tinfo->user.period =
|
||||
ahc_find_period(ahc, scsirate,
|
||||
(ultraenb & mask)
|
||||
? AHC_SYNCRATE_ULTRA
|
||||
@ -5622,7 +5620,7 @@ ahc_resume(struct ahc_softc *ahc)
|
||||
{
|
||||
|
||||
ahc_reset(ahc, /*reinit*/TRUE);
|
||||
ahc_intr_enable(ahc, TRUE);
|
||||
ahc_intr_enable(ahc, TRUE);
|
||||
ahc_restart(ahc);
|
||||
return (0);
|
||||
}
|
||||
@ -5639,7 +5637,7 @@ ahc_index_busy_tcl(struct ahc_softc *ahc, u_int tcl)
|
||||
|
||||
if ((ahc->flags & AHC_SCB_BTT) != 0) {
|
||||
u_int saved_scbptr;
|
||||
|
||||
|
||||
saved_scbptr = ahc_inb(ahc, SCBPTR);
|
||||
ahc_outb(ahc, SCBPTR, TCL_LUN(tcl));
|
||||
scbid = ahc_inb(ahc, SCB_64_BTT + TCL_TARGET_OFFSET(tcl));
|
||||
@ -5659,7 +5657,7 @@ ahc_unbusy_tcl(struct ahc_softc *ahc, u_int tcl)
|
||||
|
||||
if ((ahc->flags & AHC_SCB_BTT) != 0) {
|
||||
u_int saved_scbptr;
|
||||
|
||||
|
||||
saved_scbptr = ahc_inb(ahc, SCBPTR);
|
||||
ahc_outb(ahc, SCBPTR, TCL_LUN(tcl));
|
||||
ahc_outb(ahc, SCB_64_BTT+TCL_TARGET_OFFSET(tcl), SCB_LIST_NULL);
|
||||
@ -5677,7 +5675,7 @@ ahc_busy_tcl(struct ahc_softc *ahc, u_int tcl, u_int scbid)
|
||||
|
||||
if ((ahc->flags & AHC_SCB_BTT) != 0) {
|
||||
u_int saved_scbptr;
|
||||
|
||||
|
||||
saved_scbptr = ahc_inb(ahc, SCBPTR);
|
||||
ahc_outb(ahc, SCBPTR, TCL_LUN(tcl));
|
||||
ahc_outb(ahc, SCB_64_BTT + TCL_TARGET_OFFSET(tcl), scbid);
|
||||
@ -5735,7 +5733,7 @@ ahc_freeze_devq(struct ahc_softc *ahc, struct scb *scb)
|
||||
target = SCB_GET_TARGET(ahc, scb);
|
||||
lun = SCB_GET_LUN(scb);
|
||||
channel = SCB_GET_CHANNEL(ahc, scb);
|
||||
|
||||
|
||||
ahc_search_qinfifo(ahc, target, channel, lun,
|
||||
/*tag*/SCB_LIST_NULL, ROLE_UNKNOWN,
|
||||
CAM_REQUEUE_REQ, SEARCH_COMPLETE);
|
||||
@ -5773,7 +5771,7 @@ ahc_qinfifo_requeue(struct ahc_softc *ahc, struct scb *prev_scb,
|
||||
ahc_outb(ahc, NEXT_QUEUED_SCB, scb->hscb->tag);
|
||||
} else {
|
||||
prev_scb->hscb->next = scb->hscb->tag;
|
||||
ahc_sync_scb(ahc, prev_scb,
|
||||
ahc_sync_scb(ahc, prev_scb,
|
||||
BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
|
||||
}
|
||||
ahc->qinfifo[ahc->qinfifonext++] = scb->hscb->tag;
|
||||
@ -5989,7 +5987,6 @@ ahc_search_qinfifo(struct ahc_softc *ahc, int target, char channel,
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
|
||||
prev = next;
|
||||
next = ahc_inb(ahc, SCB_NEXT);
|
||||
}
|
||||
@ -6235,7 +6232,7 @@ ahc_rem_wscb(struct ahc_softc *ahc, u_int scbpos, u_int prev)
|
||||
/* update the waiting list */
|
||||
if (prev == SCB_LIST_NULL) {
|
||||
/* First in the list */
|
||||
ahc_outb(ahc, WAITING_SCBH, next);
|
||||
ahc_outb(ahc, WAITING_SCBH, next);
|
||||
|
||||
/*
|
||||
* Ensure we aren't attempting to perform
|
||||
@ -6244,7 +6241,7 @@ ahc_rem_wscb(struct ahc_softc *ahc, u_int scbpos, u_int prev)
|
||||
ahc_outb(ahc, SCSISEQ, (ahc_inb(ahc, SCSISEQ) & ~ENSELO));
|
||||
} else {
|
||||
/*
|
||||
* Select the scb that pointed to us
|
||||
* Select the scb that pointed to us
|
||||
* and update its next pointer.
|
||||
*/
|
||||
ahc_outb(ahc, SCBPTR, prev);
|
||||
@ -6638,7 +6635,7 @@ ahc_calc_residual(struct ahc_softc *ahc, struct scb *scb)
|
||||
|
||||
/*
|
||||
* Remainder of the SG where the transfer
|
||||
* stopped.
|
||||
* stopped.
|
||||
*/
|
||||
resid = ahc_le32toh(spkt->residual_datacnt) & AHC_SG_LEN_MASK;
|
||||
sg = ahc_sg_bus_to_virt(scb, resid_sgptr & SG_PTR_MASK);
|
||||
@ -6690,7 +6687,7 @@ ahc_queue_lstate_event(struct ahc_softc *ahc, struct ahc_tmode_lstate *lstate,
|
||||
- (lstate->event_r_idx - lstate->event_w_idx);
|
||||
|
||||
if (event_type == EVENT_TYPE_BUS_RESET
|
||||
|| event_type == MSG_BUS_DEV_RESET) {
|
||||
|| event_type == TARGET_RESET) {
|
||||
/*
|
||||
* Any earlier events are irrelevant, so reset our buffer.
|
||||
* This has the effect of allowing us to deal with reset
|
||||
@ -6857,7 +6854,7 @@ ahc_loadseq(struct ahc_softc *ahc)
|
||||
if (begin_set[cs_count] == TRUE
|
||||
&& end_set[cs_count] == FALSE) {
|
||||
cs_table[cs_count].end = downloaded;
|
||||
end_set[cs_count] = TRUE;
|
||||
end_set[cs_count] = TRUE;
|
||||
cs_count++;
|
||||
}
|
||||
continue;
|
||||
@ -7085,7 +7082,6 @@ ahc_print_register(const ahc_reg_parse_entry_t *table, u_int num_entries,
|
||||
printed_mask == 0 ? ":(" : "|",
|
||||
table[entry].name);
|
||||
printed_mask |= table[entry].mask;
|
||||
|
||||
break;
|
||||
}
|
||||
if (entry >= num_entries)
|
||||
@ -7199,7 +7195,7 @@ ahc_dump_card_state(struct ahc_softc *ahc)
|
||||
scb_index = ahc_inb(ahc, SCB_NEXT);
|
||||
}
|
||||
printk("\n");
|
||||
|
||||
|
||||
ahc_sync_qoutfifo(ahc, BUS_DMASYNC_POSTREAD);
|
||||
printk("QOUTFIFO entries: ");
|
||||
qoutpos = ahc->qoutfifonext;
|
||||
@ -7376,7 +7372,7 @@ ahc_handle_en_lun(struct ahc_softc *ahc, struct cam_sim *sim, union ccb *ccb)
|
||||
if ((ahc->features & AHC_MULTIROLE) != 0) {
|
||||
|
||||
if ((ahc->features & AHC_MULTI_TID) != 0
|
||||
&& (ahc->flags & AHC_INITIATORROLE) != 0) {
|
||||
&& (ahc->flags & AHC_INITIATORROLE) != 0) {
|
||||
/*
|
||||
* Only allow additional targets if
|
||||
* the initiator role is disabled.
|
||||
@ -7527,7 +7523,6 @@ ahc_handle_en_lun(struct ahc_softc *ahc, struct cam_sim *sim, union ccb *ccb)
|
||||
targid_mask |= target_mask;
|
||||
ahc_outb(ahc, TARGID, targid_mask);
|
||||
ahc_outb(ahc, TARGID+1, (targid_mask >> 8));
|
||||
|
||||
ahc_update_scsiid(ahc, targid_mask);
|
||||
} else {
|
||||
u_int our_id;
|
||||
@ -7592,7 +7587,7 @@ ahc_handle_en_lun(struct ahc_softc *ahc, struct cam_sim *sim, union ccb *ccb)
|
||||
}
|
||||
|
||||
ahc_lock(ahc, &s);
|
||||
|
||||
|
||||
ccb->ccb_h.status = CAM_REQ_CMP;
|
||||
LIST_FOREACH(scb, &ahc->pending_scbs, pending_links) {
|
||||
struct ccb_hdr *ccbh;
|
||||
@ -7651,7 +7646,7 @@ ahc_handle_en_lun(struct ahc_softc *ahc, struct cam_sim *sim, union ccb *ccb)
|
||||
targid_mask &= ~target_mask;
|
||||
ahc_outb(ahc, TARGID, targid_mask);
|
||||
ahc_outb(ahc, TARGID+1,
|
||||
(targid_mask >> 8));
|
||||
(targid_mask >> 8));
|
||||
ahc_update_scsiid(ahc, targid_mask);
|
||||
}
|
||||
}
|
||||
@ -7780,7 +7775,7 @@ ahc_run_tqinfifo(struct ahc_softc *ahc, int paused)
|
||||
ahc_outb(ahc, HS_MAILBOX, hs_mailbox);
|
||||
} else {
|
||||
if (!paused)
|
||||
ahc_pause(ahc);
|
||||
ahc_pause(ahc);
|
||||
ahc_outb(ahc, KERNEL_TQINPOS,
|
||||
ahc->tqinfifonext & HOST_TQINPOS);
|
||||
if (!paused)
|
||||
@ -7879,7 +7874,7 @@ ahc_handle_target_cmd(struct ahc_softc *ahc, struct target_cmd *cmd)
|
||||
printk("Reserved or VU command code type encountered\n");
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
memcpy(atio->cdb_io.cdb_bytes, byte, atio->cdb_len);
|
||||
|
||||
atio->ccb_h.status |= CAM_CDB_RECVD;
|
||||
|
@ -1,3 +1,4 @@
|
||||
|
||||
/*
|
||||
* Adaptec AIC7xxx device driver for Linux.
|
||||
*
|
||||
@ -452,7 +453,7 @@ ahc_insb(struct ahc_softc * ahc, long port, uint8_t *array, int count)
|
||||
static void ahc_linux_unmap_scb(struct ahc_softc*, struct scb*);
|
||||
|
||||
static int ahc_linux_map_seg(struct ahc_softc *ahc, struct scb *scb,
|
||||
struct ahc_dma_seg *sg,
|
||||
struct ahc_dma_seg *sg,
|
||||
dma_addr_t addr, bus_size_t len);
|
||||
|
||||
static void
|
||||
@ -571,7 +572,7 @@ ahc_linux_target_alloc(struct scsi_target *starget)
|
||||
target_offset = starget->id;
|
||||
if (starget->channel != 0)
|
||||
target_offset += 8;
|
||||
|
||||
|
||||
if (starget->channel)
|
||||
our_id = ahc->our_id_b;
|
||||
|
||||
@ -597,18 +598,18 @@ ahc_linux_target_alloc(struct scsi_target *starget)
|
||||
ultra = 0;
|
||||
flags &= ~CFXFER;
|
||||
}
|
||||
|
||||
|
||||
if ((ahc->features & AHC_ULTRA2) != 0) {
|
||||
scsirate = (flags & CFXFER) | (ultra ? 0x8 : 0);
|
||||
} else {
|
||||
scsirate = (flags & CFXFER) << 4;
|
||||
maxsync = ultra ? AHC_SYNCRATE_ULTRA :
|
||||
maxsync = ultra ? AHC_SYNCRATE_ULTRA :
|
||||
AHC_SYNCRATE_FAST;
|
||||
}
|
||||
spi_max_width(starget) = (flags & CFWIDEB) ? 1 : 0;
|
||||
if (!(flags & CFSYNCH))
|
||||
spi_max_offset(starget) = 0;
|
||||
spi_min_period(starget) =
|
||||
spi_min_period(starget) =
|
||||
ahc_find_period(ahc, scsirate, maxsync);
|
||||
}
|
||||
ahc_compile_devinfo(&devinfo, our_id, starget->id,
|
||||
@ -657,7 +658,7 @@ ahc_linux_slave_alloc(struct scsi_device *sdev)
|
||||
* a tagged queuing capable device.
|
||||
*/
|
||||
dev->maxtags = 0;
|
||||
|
||||
|
||||
spi_period(starget) = 0;
|
||||
|
||||
return 0;
|
||||
@ -1219,8 +1220,8 @@ ahc_platform_free(struct ahc_softc *ahc)
|
||||
starget = ahc->platform_data->starget[i];
|
||||
if (starget != NULL) {
|
||||
ahc->platform_data->starget[i] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ahc->platform_data->irq != AHC_LINUX_NOIRQ)
|
||||
free_irq(ahc->platform_data->irq, ahc);
|
||||
@ -1267,7 +1268,7 @@ ahc_platform_set_tags(struct ahc_softc *ahc, struct scsi_device *sdev,
|
||||
default:
|
||||
case AHC_QUEUE_NONE:
|
||||
now_queuing = 0;
|
||||
break;
|
||||
break;
|
||||
case AHC_QUEUE_BASIC:
|
||||
now_queuing = AHC_DEV_Q_BASIC;
|
||||
break;
|
||||
@ -1468,10 +1469,10 @@ ahc_linux_run_command(struct ahc_softc *ahc, struct ahc_linux_device *dev,
|
||||
hscb->scsioffset = tinfo->curr.offset;
|
||||
if ((tstate->ultraenb & mask) != 0)
|
||||
hscb->control |= ULTRAENB;
|
||||
|
||||
|
||||
if ((ahc->user_discenable & mask) != 0)
|
||||
hscb->control |= DISCENB;
|
||||
|
||||
|
||||
if ((tstate->auto_negotiate & mask) != 0) {
|
||||
scb->flags |= SCB_AUTO_NEGOTIATE;
|
||||
scb->hscb->control |= MK_MESSAGE;
|
||||
@ -1480,10 +1481,10 @@ ahc_linux_run_command(struct ahc_softc *ahc, struct ahc_linux_device *dev,
|
||||
if ((dev->flags & (AHC_DEV_Q_TAGGED|AHC_DEV_Q_BASIC)) != 0) {
|
||||
if (dev->commands_since_idle_or_otag == AHC_OTAG_THRESH
|
||||
&& (dev->flags & AHC_DEV_Q_TAGGED) != 0) {
|
||||
hscb->control |= MSG_ORDERED_TASK;
|
||||
hscb->control |= ORDERED_QUEUE_TAG;
|
||||
dev->commands_since_idle_or_otag = 0;
|
||||
} else {
|
||||
hscb->control |= MSG_SIMPLE_TASK;
|
||||
hscb->control |= SIMPLE_QUEUE_TAG;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1531,7 +1532,7 @@ ahc_linux_run_command(struct ahc_softc *ahc, struct ahc_linux_device *dev,
|
||||
*/
|
||||
scb->hscb->sgptr =
|
||||
ahc_htole32(scb->sg_list_phys | SG_FULL_RESID);
|
||||
|
||||
|
||||
/*
|
||||
* Copy the first SG into the "current"
|
||||
* data pointer area.
|
||||
@ -1551,7 +1552,7 @@ ahc_linux_run_command(struct ahc_softc *ahc, struct ahc_linux_device *dev,
|
||||
dev->commands_issued++;
|
||||
if ((dev->flags & AHC_DEV_PERIODIC_OTAG) != 0)
|
||||
dev->commands_since_idle_or_otag++;
|
||||
|
||||
|
||||
scb->flags |= SCB_ACTIVE;
|
||||
if (untagged_q) {
|
||||
TAILQ_INSERT_TAIL(untagged_q, scb, links.tqe);
|
||||
@ -1572,7 +1573,7 @@ ahc_linux_isr(int irq, void *dev_id)
|
||||
int ours;
|
||||
|
||||
ahc = (struct ahc_softc *) dev_id;
|
||||
ahc_lock(ahc, &flags);
|
||||
ahc_lock(ahc, &flags);
|
||||
ours = ahc_intr(ahc);
|
||||
ahc_unlock(ahc, &flags);
|
||||
return IRQ_RETVAL(ours);
|
||||
@ -1647,22 +1648,22 @@ ahc_send_async(struct ahc_softc *ahc, char channel,
|
||||
spi_display_xfer_agreement(starget);
|
||||
break;
|
||||
}
|
||||
case AC_SENT_BDR:
|
||||
case AC_SENT_BDR:
|
||||
{
|
||||
WARN_ON(lun != CAM_LUN_WILDCARD);
|
||||
scsi_report_device_reset(ahc->platform_data->host,
|
||||
channel - 'A', target);
|
||||
break;
|
||||
}
|
||||
case AC_BUS_RESET:
|
||||
case AC_BUS_RESET:
|
||||
if (ahc->platform_data->host != NULL) {
|
||||
scsi_report_bus_reset(ahc->platform_data->host,
|
||||
channel - 'A');
|
||||
}
|
||||
break;
|
||||
default:
|
||||
panic("ahc_send_async: Unexpected async event");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
panic("ahc_send_async: Unexpected async event");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1759,7 +1760,7 @@ ahc_done(struct ahc_softc *ahc, struct scb *scb)
|
||||
|
||||
if (dev->openings == 1
|
||||
&& ahc_get_transaction_status(scb) == CAM_REQ_CMP
|
||||
&& ahc_get_scsi_status(scb) != SCSI_STATUS_QUEUE_FULL)
|
||||
&& ahc_get_scsi_status(scb) != SAM_STAT_TASK_SET_FULL)
|
||||
dev->tag_success_count++;
|
||||
/*
|
||||
* Some devices deal with temporary internal resource
|
||||
@ -1802,7 +1803,7 @@ ahc_linux_handle_scsi_status(struct ahc_softc *ahc,
|
||||
sdev->sdev_target->id, sdev->lun,
|
||||
sdev->sdev_target->channel == 0 ? 'A' : 'B',
|
||||
ROLE_INITIATOR);
|
||||
|
||||
|
||||
/*
|
||||
* We don't currently trust the mid-layer to
|
||||
* properly deal with queue full or busy. So,
|
||||
@ -1816,8 +1817,8 @@ ahc_linux_handle_scsi_status(struct ahc_softc *ahc,
|
||||
switch (ahc_get_scsi_status(scb)) {
|
||||
default:
|
||||
break;
|
||||
case SCSI_STATUS_CHECK_COND:
|
||||
case SCSI_STATUS_CMD_TERMINATED:
|
||||
case SAM_STAT_CHECK_CONDITION:
|
||||
case SAM_STAT_COMMAND_TERMINATED:
|
||||
{
|
||||
struct scsi_cmnd *cmd;
|
||||
|
||||
@ -1855,7 +1856,7 @@ ahc_linux_handle_scsi_status(struct ahc_softc *ahc,
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SCSI_STATUS_QUEUE_FULL:
|
||||
case SAM_STAT_TASK_SET_FULL:
|
||||
{
|
||||
/*
|
||||
* By the time the core driver has returned this
|
||||
@ -1899,7 +1900,7 @@ ahc_linux_handle_scsi_status(struct ahc_softc *ahc,
|
||||
dev->last_queuefull_same_count = 0;
|
||||
}
|
||||
ahc_set_transaction_status(scb, CAM_REQUEUE_REQ);
|
||||
ahc_set_scsi_status(scb, SCSI_STATUS_OK);
|
||||
ahc_set_scsi_status(scb, SAM_STAT_GOOD);
|
||||
ahc_platform_set_tags(ahc, sdev, &devinfo,
|
||||
(dev->flags & AHC_DEV_Q_BASIC)
|
||||
? AHC_QUEUE_BASIC : AHC_QUEUE_TAGGED);
|
||||
@ -1910,7 +1911,7 @@ ahc_linux_handle_scsi_status(struct ahc_softc *ahc,
|
||||
* as if the target returned BUSY SCSI status.
|
||||
*/
|
||||
dev->openings = 1;
|
||||
ahc_set_scsi_status(scb, SCSI_STATUS_BUSY);
|
||||
ahc_set_scsi_status(scb, SAM_STAT_BUSY);
|
||||
ahc_platform_set_tags(ahc, sdev, &devinfo,
|
||||
(dev->flags & AHC_DEV_Q_BASIC)
|
||||
? AHC_QUEUE_BASIC : AHC_QUEUE_TAGGED);
|
||||
@ -2108,7 +2109,7 @@ ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
|
||||
|
||||
/* Any SCB for this device will do for a target reset */
|
||||
LIST_FOREACH(pending_scb, &ahc->pending_scbs, pending_links) {
|
||||
if (ahc_match_scb(ahc, pending_scb, scmd_id(cmd),
|
||||
if (ahc_match_scb(ahc, pending_scb, scmd_id(cmd),
|
||||
scmd_channel(cmd) + 'A',
|
||||
CAM_LUN_WILDCARD,
|
||||
SCB_LIST_NULL, ROLE_INITIATOR))
|
||||
@ -2329,7 +2330,7 @@ static void ahc_linux_set_period(struct scsi_target *starget, int period)
|
||||
struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
|
||||
struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata);
|
||||
struct ahc_tmode_tstate *tstate;
|
||||
struct ahc_initiator_tinfo *tinfo
|
||||
struct ahc_initiator_tinfo *tinfo
|
||||
= ahc_fetch_transinfo(ahc,
|
||||
starget->channel + 'A',
|
||||
shost->this_id, starget->id, &tstate);
|
||||
@ -2361,7 +2362,8 @@ static void ahc_linux_set_period(struct scsi_target *starget, int period)
|
||||
ppr_options &= MSG_EXT_PPR_QAS_REQ;
|
||||
}
|
||||
|
||||
syncrate = ahc_find_syncrate(ahc, &period, &ppr_options, AHC_SYNCRATE_DT);
|
||||
syncrate = ahc_find_syncrate(ahc, &period, &ppr_options,
|
||||
AHC_SYNCRATE_DT);
|
||||
ahc_lock(ahc, &flags);
|
||||
ahc_set_syncrate(ahc, &devinfo, syncrate, period, offset,
|
||||
ppr_options, AHC_TRANS_GOAL, FALSE);
|
||||
@ -2373,7 +2375,7 @@ static void ahc_linux_set_offset(struct scsi_target *starget, int offset)
|
||||
struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
|
||||
struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata);
|
||||
struct ahc_tmode_tstate *tstate;
|
||||
struct ahc_initiator_tinfo *tinfo
|
||||
struct ahc_initiator_tinfo *tinfo
|
||||
= ahc_fetch_transinfo(ahc,
|
||||
starget->channel + 'A',
|
||||
shost->this_id, starget->id, &tstate);
|
||||
@ -2386,7 +2388,8 @@ static void ahc_linux_set_offset(struct scsi_target *starget, int offset)
|
||||
ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
|
||||
starget->channel + 'A', ROLE_INITIATOR);
|
||||
if (offset != 0) {
|
||||
syncrate = ahc_find_syncrate(ahc, &period, &ppr_options, AHC_SYNCRATE_DT);
|
||||
syncrate = ahc_find_syncrate(ahc, &period, &ppr_options,
|
||||
AHC_SYNCRATE_DT);
|
||||
period = tinfo->goal.period;
|
||||
ppr_options = tinfo->goal.ppr_options;
|
||||
}
|
||||
@ -2401,7 +2404,7 @@ static void ahc_linux_set_dt(struct scsi_target *starget, int dt)
|
||||
struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
|
||||
struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata);
|
||||
struct ahc_tmode_tstate *tstate;
|
||||
struct ahc_initiator_tinfo *tinfo
|
||||
struct ahc_initiator_tinfo *tinfo
|
||||
= ahc_fetch_transinfo(ahc,
|
||||
starget->channel + 'A',
|
||||
shost->this_id, starget->id, &tstate);
|
||||
@ -2422,7 +2425,8 @@ static void ahc_linux_set_dt(struct scsi_target *starget, int dt)
|
||||
|
||||
ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
|
||||
starget->channel + 'A', ROLE_INITIATOR);
|
||||
syncrate = ahc_find_syncrate(ahc, &period, &ppr_options,AHC_SYNCRATE_DT);
|
||||
syncrate = ahc_find_syncrate(ahc, &period, &ppr_options,
|
||||
AHC_SYNCRATE_DT);
|
||||
ahc_lock(ahc, &flags);
|
||||
ahc_set_syncrate(ahc, &devinfo, syncrate, period, tinfo->goal.offset,
|
||||
ppr_options, AHC_TRANS_GOAL, FALSE);
|
||||
@ -2439,7 +2443,7 @@ static void ahc_linux_set_qas(struct scsi_target *starget, int qas)
|
||||
struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
|
||||
struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata);
|
||||
struct ahc_tmode_tstate *tstate;
|
||||
struct ahc_initiator_tinfo *tinfo
|
||||
struct ahc_initiator_tinfo *tinfo
|
||||
= ahc_fetch_transinfo(ahc,
|
||||
starget->channel + 'A',
|
||||
shost->this_id, starget->id, &tstate);
|
||||
@ -2455,7 +2459,8 @@ static void ahc_linux_set_qas(struct scsi_target *starget, int qas)
|
||||
|
||||
ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
|
||||
starget->channel + 'A', ROLE_INITIATOR);
|
||||
syncrate = ahc_find_syncrate(ahc, &period, &ppr_options, AHC_SYNCRATE_DT);
|
||||
syncrate = ahc_find_syncrate(ahc, &period, &ppr_options,
|
||||
AHC_SYNCRATE_DT);
|
||||
ahc_lock(ahc, &flags);
|
||||
ahc_set_syncrate(ahc, &devinfo, syncrate, period, tinfo->goal.offset,
|
||||
ppr_options, AHC_TRANS_GOAL, FALSE);
|
||||
@ -2467,7 +2472,7 @@ static void ahc_linux_set_iu(struct scsi_target *starget, int iu)
|
||||
struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
|
||||
struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata);
|
||||
struct ahc_tmode_tstate *tstate;
|
||||
struct ahc_initiator_tinfo *tinfo
|
||||
struct ahc_initiator_tinfo *tinfo
|
||||
= ahc_fetch_transinfo(ahc,
|
||||
starget->channel + 'A',
|
||||
shost->this_id, starget->id, &tstate);
|
||||
@ -2483,7 +2488,8 @@ static void ahc_linux_set_iu(struct scsi_target *starget, int iu)
|
||||
|
||||
ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
|
||||
starget->channel + 'A', ROLE_INITIATOR);
|
||||
syncrate = ahc_find_syncrate(ahc, &period, &ppr_options, AHC_SYNCRATE_DT);
|
||||
syncrate = ahc_find_syncrate(ahc, &period, &ppr_options,
|
||||
AHC_SYNCRATE_DT);
|
||||
ahc_lock(ahc, &flags);
|
||||
ahc_set_syncrate(ahc, &devinfo, syncrate, period, tinfo->goal.offset,
|
||||
ppr_options, AHC_TRANS_GOAL, FALSE);
|
||||
@ -2499,7 +2505,7 @@ static void ahc_linux_get_signalling(struct Scsi_Host *shost)
|
||||
|
||||
if (!(ahc->features & AHC_ULTRA2)) {
|
||||
/* non-LVD chipset, may not have SBLKCTL reg */
|
||||
spi_signalling(shost) =
|
||||
spi_signalling(shost) =
|
||||
ahc->features & AHC_HVD ?
|
||||
SPI_SIGNAL_HVD :
|
||||
SPI_SIGNAL_SE;
|
||||
|
@ -258,7 +258,7 @@ struct ahc_linux_device {
|
||||
int active;
|
||||
|
||||
/*
|
||||
* The currently allowed number of
|
||||
* The currently allowed number of
|
||||
* transactions that can be queued to
|
||||
* the device. Must be signed for
|
||||
* conversion from tagged to untagged
|
||||
@ -272,7 +272,7 @@ struct ahc_linux_device {
|
||||
* device's queue is halted.
|
||||
*/
|
||||
u_int qfrozen;
|
||||
|
||||
|
||||
/*
|
||||
* Cumulative command counter.
|
||||
*/
|
||||
@ -351,16 +351,16 @@ struct ahc_platform_data {
|
||||
/*
|
||||
* Fields accessed from interrupt context.
|
||||
*/
|
||||
struct scsi_target *starget[AHC_NUM_TARGETS];
|
||||
struct scsi_target *starget[AHC_NUM_TARGETS];
|
||||
|
||||
spinlock_t spin_lock;
|
||||
u_int qfrozen;
|
||||
struct completion *eh_done;
|
||||
struct Scsi_Host *host; /* pointer to scsi host */
|
||||
struct Scsi_Host *host; /* pointer to scsi host */
|
||||
#define AHC_LINUX_NOIRQ ((uint32_t)~0)
|
||||
uint32_t irq; /* IRQ for this adapter */
|
||||
uint32_t bios_address;
|
||||
resource_size_t mem_busaddr; /* Mem Base Addr */
|
||||
resource_size_t mem_busaddr; /* Mem Base Addr */
|
||||
};
|
||||
|
||||
void ahc_delay(long);
|
||||
@ -515,29 +515,6 @@ int ahc_linux_show_info(struct seq_file *, struct Scsi_Host *);
|
||||
|
||||
/*************************** Domain Validation ********************************/
|
||||
/*********************** Transaction Access Wrappers *************************/
|
||||
static inline void ahc_cmd_set_transaction_status(struct scsi_cmnd *, uint32_t);
|
||||
static inline void ahc_set_transaction_status(struct scb *, uint32_t);
|
||||
static inline void ahc_cmd_set_scsi_status(struct scsi_cmnd *, uint32_t);
|
||||
static inline void ahc_set_scsi_status(struct scb *, uint32_t);
|
||||
static inline uint32_t ahc_cmd_get_transaction_status(struct scsi_cmnd *cmd);
|
||||
static inline uint32_t ahc_get_transaction_status(struct scb *);
|
||||
static inline uint32_t ahc_cmd_get_scsi_status(struct scsi_cmnd *cmd);
|
||||
static inline uint32_t ahc_get_scsi_status(struct scb *);
|
||||
static inline void ahc_set_transaction_tag(struct scb *, int, u_int);
|
||||
static inline u_long ahc_get_transfer_length(struct scb *);
|
||||
static inline int ahc_get_transfer_dir(struct scb *);
|
||||
static inline void ahc_set_residual(struct scb *, u_long);
|
||||
static inline void ahc_set_sense_residual(struct scb *scb, u_long resid);
|
||||
static inline u_long ahc_get_residual(struct scb *);
|
||||
static inline u_long ahc_get_sense_residual(struct scb *);
|
||||
static inline int ahc_perform_autosense(struct scb *);
|
||||
static inline uint32_t ahc_get_sense_bufsize(struct ahc_softc *,
|
||||
struct scb *);
|
||||
static inline void ahc_notify_xfer_settings_change(struct ahc_softc *,
|
||||
struct ahc_devinfo *);
|
||||
static inline void ahc_platform_scb_free(struct ahc_softc *ahc,
|
||||
struct scb *scb);
|
||||
static inline void ahc_freeze_scb(struct scb *scb);
|
||||
|
||||
static inline
|
||||
void ahc_cmd_set_transaction_status(struct scsi_cmnd *cmd, uint32_t status)
|
||||
@ -671,9 +648,9 @@ static inline void
|
||||
ahc_freeze_scb(struct scb *scb)
|
||||
{
|
||||
if ((scb->io_ctx->result & (CAM_DEV_QFRZN << 16)) == 0) {
|
||||
scb->io_ctx->result |= CAM_DEV_QFRZN << 16;
|
||||
scb->platform_data->dev->qfrozen++;
|
||||
}
|
||||
scb->io_ctx->result |= CAM_DEV_QFRZN << 16;
|
||||
scb->platform_data->dev->qfrozen++;
|
||||
}
|
||||
}
|
||||
|
||||
void ahc_platform_set_tags(struct ahc_softc *ahc, struct scsi_device *sdev,
|
||||
|
@ -97,17 +97,17 @@ ahc_format_transinfo(struct seq_file *m, struct ahc_transinfo *tinfo)
|
||||
u_int freq;
|
||||
u_int mb;
|
||||
|
||||
speed = 3300;
|
||||
freq = 0;
|
||||
speed = 3300;
|
||||
freq = 0;
|
||||
if (tinfo->offset != 0) {
|
||||
freq = ahc_calc_syncsrate(tinfo->period);
|
||||
speed = freq;
|
||||
}
|
||||
speed *= (0x01 << tinfo->width);
|
||||
mb = speed / 1000;
|
||||
if (mb > 0)
|
||||
mb = speed / 1000;
|
||||
if (mb > 0)
|
||||
seq_printf(m, "%d.%03dMB/s transfers", mb, speed % 1000);
|
||||
else
|
||||
else
|
||||
seq_printf(m, "%dKB/s transfers", speed);
|
||||
|
||||
if (freq != 0) {
|
||||
@ -234,7 +234,7 @@ ahc_proc_write_seeprom(struct Scsi_Host *shost, char *buffer, int length)
|
||||
if ((ahc->chip & AHC_VL) != 0) {
|
||||
sd.sd_control_offset = SEECTL_2840;
|
||||
sd.sd_status_offset = STATUS_2840;
|
||||
sd.sd_dataout_offset = STATUS_2840;
|
||||
sd.sd_dataout_offset = STATUS_2840;
|
||||
sd.sd_chip = C46;
|
||||
sd.sd_MS = 0;
|
||||
sd.sd_RDY = EEPROM_TF;
|
||||
@ -255,7 +255,8 @@ ahc_proc_write_seeprom(struct Scsi_Host *shost, char *buffer, int length)
|
||||
u_int start_addr;
|
||||
|
||||
if (ahc->seep_config == NULL) {
|
||||
ahc->seep_config = kmalloc(sizeof(*ahc->seep_config), GFP_ATOMIC);
|
||||
ahc->seep_config = kmalloc(sizeof(*ahc->seep_config),
|
||||
GFP_ATOMIC);
|
||||
if (ahc->seep_config == NULL) {
|
||||
printk("aic7xxx: Unable to allocate serial "
|
||||
"eeprom buffer. Write failing\n");
|
||||
|
@ -117,21 +117,6 @@ struct scsi_sense_data
|
||||
#define SSD_FULL_SIZE sizeof(struct scsi_sense_data)
|
||||
};
|
||||
|
||||
/*
|
||||
* Status Byte
|
||||
*/
|
||||
#define SCSI_STATUS_OK 0x00
|
||||
#define SCSI_STATUS_CHECK_COND 0x02
|
||||
#define SCSI_STATUS_COND_MET 0x04
|
||||
#define SCSI_STATUS_BUSY 0x08
|
||||
#define SCSI_STATUS_INTERMED 0x10
|
||||
#define SCSI_STATUS_INTERMED_COND_MET 0x14
|
||||
#define SCSI_STATUS_RESERV_CONFLICT 0x18
|
||||
#define SCSI_STATUS_CMD_TERMINATED 0x22 /* Obsolete in SAM-2 */
|
||||
#define SCSI_STATUS_QUEUE_FULL 0x28
|
||||
#define SCSI_STATUS_ACA_ACTIVE 0x30
|
||||
#define SCSI_STATUS_TASK_ABORTED 0x40
|
||||
|
||||
/************************* Large Disk Handling ********************************/
|
||||
static inline int
|
||||
aic_sector_div(sector_t capacity, int heads, int sectors)
|
||||
|
@ -3,44 +3,6 @@
|
||||
* $FreeBSD: src/sys/cam/scsi/scsi_message.h,v 1.2 2000/05/01 20:21:29 peter Exp $
|
||||
*/
|
||||
|
||||
/* Messages (1 byte) */ /* I/T (M)andatory or (O)ptional */
|
||||
#define MSG_CMDCOMPLETE 0x00 /* M/M */
|
||||
#define MSG_TASK_COMPLETE 0x00 /* M/M */ /* SPI3 Terminology */
|
||||
#define MSG_EXTENDED 0x01 /* O/O */
|
||||
#define MSG_SAVEDATAPOINTER 0x02 /* O/O */
|
||||
#define MSG_RESTOREPOINTERS 0x03 /* O/O */
|
||||
#define MSG_DISCONNECT 0x04 /* O/O */
|
||||
#define MSG_INITIATOR_DET_ERR 0x05 /* M/M */
|
||||
#define MSG_ABORT 0x06 /* O/M */
|
||||
#define MSG_ABORT_TASK_SET 0x06 /* O/M */ /* SPI3 Terminology */
|
||||
#define MSG_MESSAGE_REJECT 0x07 /* M/M */
|
||||
#define MSG_NOOP 0x08 /* M/M */
|
||||
#define MSG_PARITY_ERROR 0x09 /* M/M */
|
||||
#define MSG_LINK_CMD_COMPLETE 0x0a /* O/O */
|
||||
#define MSG_LINK_CMD_COMPLETEF 0x0b /* O/O */
|
||||
#define MSG_BUS_DEV_RESET 0x0c /* O/M */
|
||||
#define MSG_TARGET_RESET 0x0c /* O/M */ /* SPI3 Terminology */
|
||||
#define MSG_ABORT_TAG 0x0d /* O/O */
|
||||
#define MSG_ABORT_TASK 0x0d /* O/O */ /* SPI3 Terminology */
|
||||
#define MSG_CLEAR_QUEUE 0x0e /* O/O */
|
||||
#define MSG_CLEAR_TASK_SET 0x0e /* O/O */ /* SPI3 Terminology */
|
||||
#define MSG_INIT_RECOVERY 0x0f /* O/O */ /* Deprecated in SPI3 */
|
||||
#define MSG_REL_RECOVERY 0x10 /* O/O */ /* Deprecated in SPI3 */
|
||||
#define MSG_TERM_IO_PROC 0x11 /* O/O */ /* Deprecated in SPI3 */
|
||||
#define MSG_CLEAR_ACA 0x16 /* O/O */ /* SPI3 */
|
||||
#define MSG_LOGICAL_UNIT_RESET 0x17 /* O/O */ /* SPI3 */
|
||||
#define MSG_QAS_REQUEST 0x55 /* O/O */ /* SPI3 */
|
||||
|
||||
/* Messages (2 byte) */
|
||||
#define MSG_SIMPLE_Q_TAG 0x20 /* O/O */
|
||||
#define MSG_SIMPLE_TASK 0x20 /* O/O */ /* SPI3 Terminology */
|
||||
#define MSG_HEAD_OF_Q_TAG 0x21 /* O/O */
|
||||
#define MSG_HEAD_OF_QUEUE_TASK 0x21 /* O/O */ /* SPI3 Terminology */
|
||||
#define MSG_ORDERED_Q_TAG 0x22 /* O/O */
|
||||
#define MSG_ORDERED_TASK 0x22 /* O/O */ /* SPI3 Terminology */
|
||||
#define MSG_IGN_WIDE_RESIDUE 0x23 /* O/O */
|
||||
#define MSG_ACA_TASK 0x24 /* 0/0 */ /* SPI3 */
|
||||
|
||||
/* Identify message */ /* M/M */
|
||||
#define MSG_IDENTIFYFLAG 0x80
|
||||
#define MSG_IDENTIFY_DISCFLAG 0x40
|
||||
@ -49,16 +11,13 @@
|
||||
#define MSG_IDENTIFY_LUNMASK 0x3F
|
||||
|
||||
/* Extended messages (opcode and length) */
|
||||
#define MSG_EXT_SDTR 0x01
|
||||
#define MSG_EXT_SDTR_LEN 0x03
|
||||
|
||||
#define MSG_EXT_WDTR 0x03
|
||||
#define MSG_EXT_WDTR_LEN 0x02
|
||||
#define MSG_EXT_WDTR_BUS_8_BIT 0x00
|
||||
#define MSG_EXT_WDTR_BUS_16_BIT 0x01
|
||||
#define MSG_EXT_WDTR_BUS_32_BIT 0x02 /* Deprecated in SPI3 */
|
||||
|
||||
#define MSG_EXT_PPR 0x04 /* SPI3 */
|
||||
#define MSG_EXT_PPR_LEN 0x06
|
||||
#define MSG_EXT_PPR_PCOMP_EN 0x80
|
||||
#define MSG_EXT_PPR_RTI 0x40
|
||||
|
@ -68,7 +68,6 @@ static void asd_phy_event_tasklet(struct asd_ascb *ascb,
|
||||
struct done_list_struct *dl)
|
||||
{
|
||||
struct asd_ha_struct *asd_ha = ascb->ha;
|
||||
struct sas_ha_struct *sas_ha = &asd_ha->sas_ha;
|
||||
int phy_id = dl->status_block[0] & DL_PHY_MASK;
|
||||
struct asd_phy *phy = &asd_ha->phys[phy_id];
|
||||
|
||||
@ -81,7 +80,8 @@ static void asd_phy_event_tasklet(struct asd_ascb *ascb,
|
||||
ASD_DPRINTK("phy%d: device unplugged\n", phy_id);
|
||||
asd_turn_led(asd_ha, phy_id, 0);
|
||||
sas_phy_disconnected(&phy->sas_phy);
|
||||
sas_ha->notify_phy_event(&phy->sas_phy, PHYE_LOSS_OF_SIGNAL);
|
||||
sas_notify_phy_event(&phy->sas_phy, PHYE_LOSS_OF_SIGNAL,
|
||||
GFP_ATOMIC);
|
||||
break;
|
||||
case CURRENT_OOB_DONE:
|
||||
/* hot plugged device */
|
||||
@ -89,12 +89,13 @@ static void asd_phy_event_tasklet(struct asd_ascb *ascb,
|
||||
get_lrate_mode(phy, oob_mode);
|
||||
ASD_DPRINTK("phy%d device plugged: lrate:0x%x, proto:0x%x\n",
|
||||
phy_id, phy->sas_phy.linkrate, phy->sas_phy.iproto);
|
||||
sas_ha->notify_phy_event(&phy->sas_phy, PHYE_OOB_DONE);
|
||||
sas_notify_phy_event(&phy->sas_phy, PHYE_OOB_DONE, GFP_ATOMIC);
|
||||
break;
|
||||
case CURRENT_SPINUP_HOLD:
|
||||
/* hot plug SATA, no COMWAKE sent */
|
||||
asd_turn_led(asd_ha, phy_id, 1);
|
||||
sas_ha->notify_phy_event(&phy->sas_phy, PHYE_SPINUP_HOLD);
|
||||
sas_notify_phy_event(&phy->sas_phy, PHYE_SPINUP_HOLD,
|
||||
GFP_ATOMIC);
|
||||
break;
|
||||
case CURRENT_GTO_TIMEOUT:
|
||||
case CURRENT_OOB_ERROR:
|
||||
@ -102,7 +103,7 @@ static void asd_phy_event_tasklet(struct asd_ascb *ascb,
|
||||
dl->status_block[1]);
|
||||
asd_turn_led(asd_ha, phy_id, 0);
|
||||
sas_phy_disconnected(&phy->sas_phy);
|
||||
sas_ha->notify_phy_event(&phy->sas_phy, PHYE_OOB_ERROR);
|
||||
sas_notify_phy_event(&phy->sas_phy, PHYE_OOB_ERROR, GFP_ATOMIC);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -222,7 +223,6 @@ static void asd_bytes_dmaed_tasklet(struct asd_ascb *ascb,
|
||||
int edb_el = edb_id + ascb->edb_index;
|
||||
struct asd_dma_tok *edb = ascb->ha->seq.edb_arr[edb_el];
|
||||
struct asd_phy *phy = &ascb->ha->phys[phy_id];
|
||||
struct sas_ha_struct *sas_ha = phy->sas_phy.ha;
|
||||
u16 size = ((dl->status_block[3] & 7) << 8) | dl->status_block[2];
|
||||
|
||||
size = min(size, (u16) sizeof(phy->frame_rcvd));
|
||||
@ -234,7 +234,7 @@ static void asd_bytes_dmaed_tasklet(struct asd_ascb *ascb,
|
||||
spin_unlock_irqrestore(&phy->sas_phy.frame_rcvd_lock, flags);
|
||||
asd_dump_frame_rcvd(phy, dl);
|
||||
asd_form_port(ascb->ha, phy);
|
||||
sas_ha->notify_port_event(&phy->sas_phy, PORTE_BYTES_DMAED);
|
||||
sas_notify_port_event(&phy->sas_phy, PORTE_BYTES_DMAED, GFP_ATOMIC);
|
||||
}
|
||||
|
||||
static void asd_link_reset_err_tasklet(struct asd_ascb *ascb,
|
||||
@ -270,7 +270,7 @@ static void asd_link_reset_err_tasklet(struct asd_ascb *ascb,
|
||||
asd_turn_led(asd_ha, phy_id, 0);
|
||||
sas_phy_disconnected(sas_phy);
|
||||
asd_deform_port(asd_ha, phy);
|
||||
sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR);
|
||||
sas_notify_port_event(sas_phy, PORTE_LINK_RESET_ERR, GFP_ATOMIC);
|
||||
|
||||
if (retries_left == 0) {
|
||||
int num = 1;
|
||||
@ -315,7 +315,8 @@ static void asd_primitive_rcvd_tasklet(struct asd_ascb *ascb,
|
||||
spin_lock_irqsave(&sas_phy->sas_prim_lock, flags);
|
||||
sas_phy->sas_prim = ffs(cont);
|
||||
spin_unlock_irqrestore(&sas_phy->sas_prim_lock, flags);
|
||||
sas_ha->notify_port_event(sas_phy,PORTE_BROADCAST_RCVD);
|
||||
sas_notify_port_event(sas_phy, PORTE_BROADCAST_RCVD,
|
||||
GFP_ATOMIC);
|
||||
break;
|
||||
|
||||
case LmUNKNOWNP:
|
||||
@ -336,7 +337,8 @@ static void asd_primitive_rcvd_tasklet(struct asd_ascb *ascb,
|
||||
/* The sequencer disables all phys on that port.
|
||||
* We have to re-enable the phys ourselves. */
|
||||
asd_deform_port(asd_ha, phy);
|
||||
sas_ha->notify_port_event(sas_phy, PORTE_HARD_RESET);
|
||||
sas_notify_port_event(sas_phy, PORTE_HARD_RESET,
|
||||
GFP_ATOMIC);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -567,7 +569,7 @@ static void escb_tasklet_complete(struct asd_ascb *ascb,
|
||||
/* the device is gone */
|
||||
sas_phy_disconnected(sas_phy);
|
||||
asd_deform_port(asd_ha, phy);
|
||||
sas_ha->notify_port_event(sas_phy, PORTE_TIMER_EVENT);
|
||||
sas_notify_port_event(sas_phy, PORTE_TIMER_EVENT, GFP_ATOMIC);
|
||||
break;
|
||||
default:
|
||||
ASD_DPRINTK("%s: phy%d: unknown event:0x%x\n", __func__,
|
||||
|
@ -144,12 +144,6 @@
|
||||
#define VER_MINOR 0
|
||||
#define VER_PATCH 6
|
||||
|
||||
#ifndef ABORT_TAG
|
||||
#define ABORT_TAG 0xd
|
||||
#else
|
||||
#error "Yippee! ABORT TAG is now defined! Remove this error!"
|
||||
#endif
|
||||
|
||||
#ifdef USE_DMAC
|
||||
/*
|
||||
* DMAC setup parameters
|
||||
@ -1490,8 +1484,8 @@ void acornscsi_message(AS_Host *host)
|
||||
}
|
||||
|
||||
switch (message[0]) {
|
||||
case ABORT:
|
||||
case ABORT_TAG:
|
||||
case ABORT_TASK_SET:
|
||||
case ABORT_TASK:
|
||||
case COMMAND_COMPLETE:
|
||||
if (host->scsi.phase != PHASE_STATUSIN) {
|
||||
printk(KERN_ERR "scsi%d.%c: command complete following non-status in phase?\n",
|
||||
@ -1596,10 +1590,6 @@ void acornscsi_message(AS_Host *host)
|
||||
}
|
||||
break;
|
||||
|
||||
case QUEUE_FULL:
|
||||
/* TODO: target queue is full */
|
||||
break;
|
||||
|
||||
case SIMPLE_QUEUE_TAG:
|
||||
/* tag queue reconnect... message[1] = queue tag. Print something to indicate something happened! */
|
||||
printk("scsi%d.%c: reconnect queue tag %02X\n",
|
||||
|
@ -42,7 +42,8 @@
|
||||
|
||||
static struct scsi_host_template atp870u_template;
|
||||
static void send_s870(struct atp_unit *dev,unsigned char c);
|
||||
static void atp_is(struct atp_unit *dev, unsigned char c, bool wide_chip, unsigned char lvdmode);
|
||||
static void atp_is(struct atp_unit *dev, unsigned char c, bool wide_chip,
|
||||
unsigned char lvdmode);
|
||||
|
||||
static inline void atp_writeb_base(struct atp_unit *atp, u8 reg, u8 val)
|
||||
{
|
||||
@ -137,16 +138,17 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id)
|
||||
}
|
||||
if ((j & 0x80) == 0)
|
||||
return IRQ_NONE;
|
||||
#ifdef ED_DBGP
|
||||
#ifdef ED_DBGP
|
||||
printk("atp870u_intr_handle enter\n");
|
||||
#endif
|
||||
#endif
|
||||
dev->in_int[c] = 1;
|
||||
cmdp = atp_readb_io(dev, c, 0x10);
|
||||
if (dev->working[c] != 0) {
|
||||
if (is885(dev)) {
|
||||
if ((atp_readb_io(dev, c, 0x16) & 0x80) == 0)
|
||||
atp_writeb_io(dev, c, 0x16, (atp_readb_io(dev, c, 0x16) | 0x80));
|
||||
}
|
||||
atp_writeb_io(dev, c, 0x16,
|
||||
(atp_readb_io(dev, c, 0x16) | 0x80));
|
||||
}
|
||||
if ((atp_readb_pci(dev, c, 0x00) & 0x08) != 0)
|
||||
{
|
||||
for (k=0; k < 1000; k++) {
|
||||
@ -157,9 +159,9 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id)
|
||||
}
|
||||
}
|
||||
atp_writeb_pci(dev, c, 0, 0x00);
|
||||
|
||||
|
||||
i = atp_readb_io(dev, c, 0x17);
|
||||
|
||||
|
||||
if (is885(dev))
|
||||
atp_writeb_pci(dev, c, 2, 0x06);
|
||||
|
||||
@ -185,44 +187,51 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id)
|
||||
dev->r1f[c][target_id] |= j;
|
||||
#ifdef ED_DBGP
|
||||
printk("atp870u_intr_handle status = %x\n",i);
|
||||
#endif
|
||||
#endif
|
||||
if (i == 0x85) {
|
||||
if ((dev->last_cmd[c] & 0xf0) != 0x40) {
|
||||
dev->last_cmd[c] = 0xff;
|
||||
}
|
||||
if (is885(dev)) {
|
||||
adrcnt = 0;
|
||||
((unsigned char *) &adrcnt)[2] = atp_readb_io(dev, c, 0x12);
|
||||
((unsigned char *) &adrcnt)[1] = atp_readb_io(dev, c, 0x13);
|
||||
((unsigned char *) &adrcnt)[0] = atp_readb_io(dev, c, 0x14);
|
||||
((unsigned char *) &adrcnt)[2] =
|
||||
atp_readb_io(dev, c, 0x12);
|
||||
((unsigned char *) &adrcnt)[1] =
|
||||
atp_readb_io(dev, c, 0x13);
|
||||
((unsigned char *) &adrcnt)[0] =
|
||||
atp_readb_io(dev, c, 0x14);
|
||||
if (dev->id[c][target_id].last_len != adrcnt) {
|
||||
k = dev->id[c][target_id].last_len;
|
||||
k -= adrcnt;
|
||||
dev->id[c][target_id].tran_len = k;
|
||||
k -= adrcnt;
|
||||
dev->id[c][target_id].tran_len = k;
|
||||
dev->id[c][target_id].last_len = adrcnt;
|
||||
}
|
||||
#ifdef ED_DBGP
|
||||
printk("dev->id[c][target_id].last_len = %d dev->id[c][target_id].tran_len = %d\n",dev->id[c][target_id].last_len,dev->id[c][target_id].tran_len);
|
||||
#endif
|
||||
printk("dev->id[c][target_id].last_len = %d "
|
||||
"dev->id[c][target_id].tran_len = %d\n",
|
||||
dev->id[c][target_id].last_len,
|
||||
dev->id[c][target_id].tran_len);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Flip wide
|
||||
*/
|
||||
*/
|
||||
if (dev->wide_id[c] != 0) {
|
||||
atp_writeb_io(dev, c, 0x1b, 0x01);
|
||||
while ((atp_readb_io(dev, c, 0x1b) & 0x01) != 0x01)
|
||||
atp_writeb_io(dev, c, 0x1b, 0x01);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Issue more commands
|
||||
*/
|
||||
spin_lock_irqsave(dev->host->host_lock, flags);
|
||||
if (((dev->quhd[c] != dev->quend[c]) || (dev->last_cmd[c] != 0xff)) &&
|
||||
spin_lock_irqsave(dev->host->host_lock, flags);
|
||||
if (((dev->quhd[c] != dev->quend[c]) ||
|
||||
(dev->last_cmd[c] != 0xff)) &&
|
||||
(dev->in_snd[c] == 0)) {
|
||||
#ifdef ED_DBGP
|
||||
printk("Call sent_s870\n");
|
||||
#endif
|
||||
#endif
|
||||
send_s870(dev,c);
|
||||
}
|
||||
spin_unlock_irqrestore(dev->host->host_lock, flags);
|
||||
@ -232,7 +241,7 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id)
|
||||
dev->in_int[c] = 0;
|
||||
#ifdef ED_DBGP
|
||||
printk("Status 0x85 return\n");
|
||||
#endif
|
||||
#endif
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
@ -247,9 +256,12 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id)
|
||||
dev->last_cmd[c] = 0xff;
|
||||
}
|
||||
adrcnt = 0;
|
||||
((unsigned char *) &adrcnt)[2] = atp_readb_io(dev, c, 0x12);
|
||||
((unsigned char *) &adrcnt)[1] = atp_readb_io(dev, c, 0x13);
|
||||
((unsigned char *) &adrcnt)[0] = atp_readb_io(dev, c, 0x14);
|
||||
((unsigned char *) &adrcnt)[2] =
|
||||
atp_readb_io(dev, c, 0x12);
|
||||
((unsigned char *) &adrcnt)[1] =
|
||||
atp_readb_io(dev, c, 0x13);
|
||||
((unsigned char *) &adrcnt)[0] =
|
||||
atp_readb_io(dev, c, 0x14);
|
||||
k = dev->id[c][target_id].last_len;
|
||||
k -= adrcnt;
|
||||
dev->id[c][target_id].tran_len = k;
|
||||
@ -262,17 +274,16 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id)
|
||||
|
||||
if (is885(dev)) {
|
||||
if ((i == 0x4c) || (i == 0x4d) || (i == 0x8c) || (i == 0x8d)) {
|
||||
if ((i == 0x4c) || (i == 0x8c))
|
||||
i=0x48;
|
||||
else
|
||||
i=0x49;
|
||||
}
|
||||
|
||||
if ((i == 0x4c) || (i == 0x8c))
|
||||
i=0x48;
|
||||
else
|
||||
i=0x49;
|
||||
}
|
||||
}
|
||||
if ((i == 0x80) || (i == 0x8f)) {
|
||||
#ifdef ED_DBGP
|
||||
printk(KERN_DEBUG "Device reselect\n");
|
||||
#endif
|
||||
#endif
|
||||
lun = 0;
|
||||
if (cmdp == 0x44 || i == 0x80)
|
||||
lun = atp_readb_io(dev, c, 0x1d) & 0x07;
|
||||
@ -283,11 +294,14 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id)
|
||||
if (cmdp == 0x41) {
|
||||
#ifdef ED_DBGP
|
||||
printk("cmdp = 0x41\n");
|
||||
#endif
|
||||
#endif
|
||||
adrcnt = 0;
|
||||
((unsigned char *) &adrcnt)[2] = atp_readb_io(dev, c, 0x12);
|
||||
((unsigned char *) &adrcnt)[1] = atp_readb_io(dev, c, 0x13);
|
||||
((unsigned char *) &adrcnt)[0] = atp_readb_io(dev, c, 0x14);
|
||||
((unsigned char *) &adrcnt)[2] =
|
||||
atp_readb_io(dev, c, 0x12);
|
||||
((unsigned char *) &adrcnt)[1] =
|
||||
atp_readb_io(dev, c, 0x13);
|
||||
((unsigned char *) &adrcnt)[0] =
|
||||
atp_readb_io(dev, c, 0x14);
|
||||
k = dev->id[c][target_id].last_len;
|
||||
k -= adrcnt;
|
||||
dev->id[c][target_id].tran_len = k;
|
||||
@ -298,7 +312,7 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id)
|
||||
} else {
|
||||
#ifdef ED_DBGP
|
||||
printk("cmdp != 0x41\n");
|
||||
#endif
|
||||
#endif
|
||||
atp_writeb_io(dev, c, 0x10, 0x46);
|
||||
dev->id[c][target_id].dirct = 0x00;
|
||||
atp_writeb_io(dev, c, 0x12, 0x00);
|
||||
@ -330,13 +344,13 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id)
|
||||
if (is885(dev))
|
||||
atp_writeb_io(dev, c, 0x10, 0x45);
|
||||
workreq = dev->id[c][target_id].curr_req;
|
||||
#ifdef ED_DBGP
|
||||
#ifdef ED_DBGP
|
||||
scmd_printk(KERN_DEBUG, workreq, "CDB");
|
||||
for (l = 0; l < workreq->cmd_len; l++)
|
||||
printk(KERN_DEBUG " %x",workreq->cmnd[l]);
|
||||
printk("\n");
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
atp_writeb_io(dev, c, 0x0f, lun);
|
||||
atp_writeb_io(dev, c, 0x11, dev->id[c][target_id].devsp);
|
||||
adrcnt = dev->id[c][target_id].tran_len;
|
||||
@ -345,9 +359,12 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id)
|
||||
atp_writeb_io(dev, c, 0x12, ((unsigned char *) &k)[2]);
|
||||
atp_writeb_io(dev, c, 0x13, ((unsigned char *) &k)[1]);
|
||||
atp_writeb_io(dev, c, 0x14, ((unsigned char *) &k)[0]);
|
||||
#ifdef ED_DBGP
|
||||
printk("k %x, k[0] 0x%x k[1] 0x%x k[2] 0x%x\n", k, atp_readb_io(dev, c, 0x14), atp_readb_io(dev, c, 0x13), atp_readb_io(dev, c, 0x12));
|
||||
#endif
|
||||
#ifdef ED_DBGP
|
||||
printk("k %x, k[0] 0x%x k[1] 0x%x k[2] 0x%x\n", k,
|
||||
atp_readb_io(dev, c, 0x14),
|
||||
atp_readb_io(dev, c, 0x13),
|
||||
atp_readb_io(dev, c, 0x12));
|
||||
#endif
|
||||
/* Remap wide */
|
||||
j = target_id;
|
||||
if (target_id > 7) {
|
||||
@ -357,26 +374,39 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id)
|
||||
j |= dev->id[c][target_id].dirct;
|
||||
atp_writeb_io(dev, c, 0x15, j);
|
||||
atp_writeb_io(dev, c, 0x16, 0x80);
|
||||
|
||||
/* enable 32 bit fifo transfer */
|
||||
|
||||
/* enable 32 bit fifo transfer */
|
||||
if (is885(dev)) {
|
||||
i = atp_readb_pci(dev, c, 1) & 0xf3;
|
||||
//j=workreq->cmnd[0];
|
||||
if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) {
|
||||
//j=workreq->cmnd[0];
|
||||
if ((workreq->cmnd[0] == READ_6) ||
|
||||
(workreq->cmnd[0] == READ_10) ||
|
||||
(workreq->cmnd[0] == WRITE_6) ||
|
||||
(workreq->cmnd[0] == WRITE_10)) {
|
||||
i |= 0x0c;
|
||||
}
|
||||
atp_writeb_pci(dev, c, 1, i);
|
||||
} else if (is880(dev)) {
|
||||
if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a))
|
||||
atp_writeb_base(dev, 0x3b, (atp_readb_base(dev, 0x3b) & 0x3f) | 0xc0);
|
||||
if ((workreq->cmnd[0] == READ_6) ||
|
||||
(workreq->cmnd[0] == READ_10) ||
|
||||
(workreq->cmnd[0] == WRITE_6) ||
|
||||
(workreq->cmnd[0] == WRITE_10))
|
||||
atp_writeb_base(dev, 0x3b,
|
||||
(atp_readb_base(dev, 0x3b) & 0x3f) | 0xc0);
|
||||
else
|
||||
atp_writeb_base(dev, 0x3b, atp_readb_base(dev, 0x3b) & 0x3f);
|
||||
} else {
|
||||
if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a))
|
||||
atp_writeb_base(dev, 0x3a, (atp_readb_base(dev, 0x3a) & 0xf3) | 0x08);
|
||||
atp_writeb_base(dev, 0x3b,
|
||||
atp_readb_base(dev, 0x3b) & 0x3f);
|
||||
} else {
|
||||
if ((workreq->cmnd[0] == READ_6) ||
|
||||
(workreq->cmnd[0] == READ_10) ||
|
||||
(workreq->cmnd[0] == WRITE_6) ||
|
||||
(workreq->cmnd[0] == WRITE_10))
|
||||
atp_writeb_base(dev, 0x3a,
|
||||
(atp_readb_base(dev, 0x3a) & 0xf3) | 0x08);
|
||||
else
|
||||
atp_writeb_base(dev, 0x3a, atp_readb_base(dev, 0x3a) & 0xf3);
|
||||
}
|
||||
atp_writeb_base(dev, 0x3a,
|
||||
atp_readb_base(dev, 0x3a) & 0xf3);
|
||||
}
|
||||
j = 0;
|
||||
id = 1;
|
||||
id = id << target_id;
|
||||
@ -394,12 +424,12 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id)
|
||||
dev->in_int[c] = 0;
|
||||
#ifdef ED_DBGP
|
||||
printk("dev->id[c][target_id].last_len = 0\n");
|
||||
#endif
|
||||
#endif
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
#ifdef ED_DBGP
|
||||
printk("target_id = %d adrcnt = %d\n",target_id,adrcnt);
|
||||
#endif
|
||||
#endif
|
||||
prd = dev->id[c][target_id].prd_pos;
|
||||
while (adrcnt != 0) {
|
||||
id = ((unsigned short int *)prd)[2];
|
||||
@ -409,8 +439,8 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id)
|
||||
k = id;
|
||||
}
|
||||
if (k > adrcnt) {
|
||||
((unsigned short int *)prd)[2] = (unsigned short int)
|
||||
(k - adrcnt);
|
||||
((unsigned short int *)prd)[2] =
|
||||
(unsigned short int)(k - adrcnt);
|
||||
((unsigned long *)prd)[0] += adrcnt;
|
||||
adrcnt = 0;
|
||||
dev->id[c][target_id].prd_pos = prd;
|
||||
@ -421,11 +451,12 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id)
|
||||
if (adrcnt == 0) {
|
||||
dev->id[c][target_id].prd_pos = prd;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
atp_writel_pci(dev, c, 0x04, dev->id[c][target_id].prdaddr);
|
||||
#ifdef ED_DBGP
|
||||
printk("dev->id[%d][%d].prdaddr 0x%8x\n", c, target_id, dev->id[c][target_id].prdaddr);
|
||||
printk("dev->id[%d][%d].prdaddr 0x%8x\n",
|
||||
c, target_id, dev->id[c][target_id].prdaddr);
|
||||
#endif
|
||||
if (!is885(dev)) {
|
||||
atp_writeb_pci(dev, c, 2, 0x06);
|
||||
@ -440,7 +471,7 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id)
|
||||
dev->in_int[c] = 0;
|
||||
#ifdef ED_DBGP
|
||||
printk("status 0x80 return dirct != 0\n");
|
||||
#endif
|
||||
#endif
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
atp_writeb_io(dev, c, 0x18, 0x08);
|
||||
@ -448,7 +479,7 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id)
|
||||
dev->in_int[c] = 0;
|
||||
#ifdef ED_DBGP
|
||||
printk("status 0x80 return dirct = 0\n");
|
||||
#endif
|
||||
#endif
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
@ -466,10 +497,10 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id)
|
||||
workreq->result = atp_readb_io(dev, c, 0x0f);
|
||||
if (((dev->r1f[c][target_id] & 0x10) != 0) && is885(dev)) {
|
||||
printk(KERN_WARNING "AEC67162 CRC ERROR !\n");
|
||||
workreq->result = 0x02;
|
||||
workreq->result = SAM_STAT_CHECK_CONDITION;
|
||||
}
|
||||
} else
|
||||
workreq->result = 0x02;
|
||||
workreq->result = SAM_STAT_CHECK_CONDITION;
|
||||
|
||||
if (is885(dev)) {
|
||||
j = atp_readb_base(dev, 0x29) | 0x01;
|
||||
@ -484,7 +515,7 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id)
|
||||
(*workreq->scsi_done) (workreq);
|
||||
#ifdef ED_DBGP
|
||||
printk("workreq->scsi_done\n");
|
||||
#endif
|
||||
#endif
|
||||
/*
|
||||
* Clear it off the queue
|
||||
*/
|
||||
@ -498,16 +529,17 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id)
|
||||
atp_writeb_io(dev, c, 0x1b, 0x01);
|
||||
while ((atp_readb_io(dev, c, 0x1b) & 0x01) != 0x01)
|
||||
atp_writeb_io(dev, c, 0x1b, 0x01);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* If there is stuff to send and nothing going then send it
|
||||
*/
|
||||
spin_lock_irqsave(dev->host->host_lock, flags);
|
||||
if (((dev->last_cmd[c] != 0xff) || (dev->quhd[c] != dev->quend[c])) &&
|
||||
if (((dev->last_cmd[c] != 0xff) ||
|
||||
(dev->quhd[c] != dev->quend[c])) &&
|
||||
(dev->in_snd[c] == 0)) {
|
||||
#ifdef ED_DBGP
|
||||
printk("Call sent_s870(scsi_done)\n");
|
||||
#endif
|
||||
#endif
|
||||
send_s870(dev,c);
|
||||
}
|
||||
spin_unlock_irqrestore(dev->host->host_lock, flags);
|
||||
@ -528,9 +560,12 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id)
|
||||
atp_writeb_io(dev, c, 0x10, 0x41);
|
||||
if (is885(dev)) {
|
||||
k = dev->id[c][target_id].last_len;
|
||||
atp_writeb_io(dev, c, 0x12, ((unsigned char *) (&k))[2]);
|
||||
atp_writeb_io(dev, c, 0x13, ((unsigned char *) (&k))[1]);
|
||||
atp_writeb_io(dev, c, 0x14, ((unsigned char *) (&k))[0]);
|
||||
atp_writeb_io(dev, c, 0x12,
|
||||
((unsigned char *) (&k))[2]);
|
||||
atp_writeb_io(dev, c, 0x13,
|
||||
((unsigned char *) (&k))[1]);
|
||||
atp_writeb_io(dev, c, 0x14,
|
||||
((unsigned char *) (&k))[0]);
|
||||
dev->id[c][target_id].dirct = 0x00;
|
||||
} else {
|
||||
dev->id[c][target_id].dirct = 0x00;
|
||||
@ -547,11 +582,15 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id)
|
||||
atp_writeb_io(dev, c, 0x10, 0x41);
|
||||
if (is885(dev)) {
|
||||
k = dev->id[c][target_id].last_len;
|
||||
atp_writeb_io(dev, c, 0x12, ((unsigned char *) (&k))[2]);
|
||||
atp_writeb_io(dev, c, 0x13, ((unsigned char *) (&k))[1]);
|
||||
atp_writeb_io(dev, c, 0x14, ((unsigned char *) (&k))[0]);
|
||||
atp_writeb_io(dev, c, 0x12,
|
||||
((unsigned char *) (&k))[2]);
|
||||
atp_writeb_io(dev, c, 0x13,
|
||||
((unsigned char *) (&k))[1]);
|
||||
atp_writeb_io(dev, c, 0x14,
|
||||
((unsigned char *) (&k))[0]);
|
||||
}
|
||||
atp_writeb_io(dev, c, 0x15, atp_readb_io(dev, c, 0x15) | 0x20);
|
||||
atp_writeb_io(dev, c, 0x15,
|
||||
atp_readb_io(dev, c, 0x15) | 0x20);
|
||||
dev->id[c][target_id].dirct = 0x20;
|
||||
atp_writeb_io(dev, c, 0x18, 0x08);
|
||||
atp_writeb_pci(dev, c, 0, 0x01);
|
||||
@ -591,19 +630,17 @@ static int atp870u_queuecommand_lck(struct scsi_cmnd *req_p,
|
||||
req_p->sense_buffer[0]=0;
|
||||
scsi_set_resid(req_p, 0);
|
||||
if (scmd_channel(req_p) > 1) {
|
||||
req_p->result = 0x00040000;
|
||||
req_p->result = DID_BAD_TARGET << 16;
|
||||
done(req_p);
|
||||
#ifdef ED_DBGP
|
||||
printk("atp870u_queuecommand : req_p->device->channel > 1\n");
|
||||
#endif
|
||||
#ifdef ED_DBGP
|
||||
printk("atp870u_queuecommand : req_p->device->channel > 1\n");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
host = req_p->device->host;
|
||||
dev = (struct atp_unit *)&host->hostdata;
|
||||
|
||||
|
||||
|
||||
m = 1;
|
||||
m = m << scmd_id(req_p);
|
||||
|
||||
@ -612,7 +649,7 @@ static int atp870u_queuecommand_lck(struct scsi_cmnd *req_p,
|
||||
*/
|
||||
|
||||
if ((m & dev->active_id[c]) == 0) {
|
||||
req_p->result = 0x00040000;
|
||||
req_p->result = DID_BAD_TARGET << 16;
|
||||
done(req_p);
|
||||
return 0;
|
||||
}
|
||||
@ -620,14 +657,14 @@ static int atp870u_queuecommand_lck(struct scsi_cmnd *req_p,
|
||||
if (done) {
|
||||
req_p->scsi_done = done;
|
||||
} else {
|
||||
#ifdef ED_DBGP
|
||||
#ifdef ED_DBGP
|
||||
printk( "atp870u_queuecommand: done can't be NULL\n");
|
||||
#endif
|
||||
#endif
|
||||
req_p->result = 0;
|
||||
done(req_p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Count new command
|
||||
*/
|
||||
@ -635,7 +672,7 @@ static int atp870u_queuecommand_lck(struct scsi_cmnd *req_p,
|
||||
if (dev->quend[c] >= qcnt) {
|
||||
dev->quend[c] = 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Check queue state
|
||||
*/
|
||||
@ -643,27 +680,32 @@ static int atp870u_queuecommand_lck(struct scsi_cmnd *req_p,
|
||||
if (dev->quend[c] == 0) {
|
||||
dev->quend[c] = qcnt;
|
||||
}
|
||||
#ifdef ED_DBGP
|
||||
#ifdef ED_DBGP
|
||||
printk("atp870u_queuecommand : dev->quhd[c] == dev->quend[c]\n");
|
||||
#endif
|
||||
#endif
|
||||
dev->quend[c]--;
|
||||
req_p->result = 0x00020000;
|
||||
done(req_p);
|
||||
req_p->result = DID_BUS_BUSY << 16;
|
||||
done(req_p);
|
||||
return 0;
|
||||
}
|
||||
dev->quereq[c][dev->quend[c]] = req_p;
|
||||
#ifdef ED_DBGP
|
||||
printk("dev->ioport[c] = %x atp_readb_io(dev, c, 0x1c) = %x dev->in_int[%d] = %d dev->in_snd[%d] = %d\n",dev->ioport[c],atp_readb_io(dev, c, 0x1c),c,dev->in_int[c],c,dev->in_snd[c]);
|
||||
#ifdef ED_DBGP
|
||||
printk("dev->ioport[c] = %x atp_readb_io(dev, c, 0x1c) = %x "
|
||||
"dev->in_int[%d] = %d dev->in_snd[%d] = %d\n",
|
||||
dev->ioport[c], atp_readb_io(dev, c, 0x1c), c,
|
||||
dev->in_int[c],c,dev->in_snd[c]);
|
||||
#endif
|
||||
if ((atp_readb_io(dev, c, 0x1c) == 0) && (dev->in_int[c] == 0) && (dev->in_snd[c] == 0)) {
|
||||
if ((atp_readb_io(dev, c, 0x1c) == 0) &&
|
||||
(dev->in_int[c] == 0) &&
|
||||
(dev->in_snd[c] == 0)) {
|
||||
#ifdef ED_DBGP
|
||||
printk("Call sent_s870(atp870u_queuecommand)\n");
|
||||
#endif
|
||||
#endif
|
||||
send_s870(dev,c);
|
||||
}
|
||||
#ifdef ED_DBGP
|
||||
#ifdef ED_DBGP
|
||||
printk("atp870u_queuecommand : exit\n");
|
||||
#endif
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -674,7 +716,7 @@ static DEF_SCSI_QCMD(atp870u_queuecommand)
|
||||
* @host: host
|
||||
*
|
||||
* On entry there is work queued to be done. We move some of that work to the
|
||||
* controller itself.
|
||||
* controller itself.
|
||||
*
|
||||
* Caller holds the host lock.
|
||||
*/
|
||||
@ -689,7 +731,7 @@ static void send_s870(struct atp_unit *dev,unsigned char c)
|
||||
unsigned long sg_count;
|
||||
|
||||
if (dev->in_snd[c] != 0) {
|
||||
#ifdef ED_DBGP
|
||||
#ifdef ED_DBGP
|
||||
printk("cmnd in_snd\n");
|
||||
#endif
|
||||
return;
|
||||
@ -729,7 +771,8 @@ static void send_s870(struct atp_unit *dev,unsigned char c)
|
||||
dev->id[c][scmd_id(workreq)].curr_req = workreq;
|
||||
dev->last_cmd[c] = scmd_id(workreq);
|
||||
}
|
||||
if ((atp_readb_io(dev, c, 0x1f) & 0xb0) != 0 || atp_readb_io(dev, c, 0x1c) != 0) {
|
||||
if ((atp_readb_io(dev, c, 0x1f) & 0xb0) != 0 ||
|
||||
atp_readb_io(dev, c, 0x1c) != 0) {
|
||||
#ifdef ED_DBGP
|
||||
printk("Abort to Send\n");
|
||||
#endif
|
||||
@ -744,7 +787,7 @@ static void send_s870(struct atp_unit *dev,unsigned char c)
|
||||
printk(" %x",workreq->cmnd[i]);
|
||||
}
|
||||
printk("\n");
|
||||
#endif
|
||||
#endif
|
||||
l = scsi_bufflen(workreq);
|
||||
|
||||
if (is885(dev)) {
|
||||
@ -752,12 +795,12 @@ static void send_s870(struct atp_unit *dev,unsigned char c)
|
||||
atp_writeb_base(dev, 0x29, j);
|
||||
dev->r1f[c][scmd_id(workreq)] = 0;
|
||||
}
|
||||
|
||||
|
||||
if (workreq->cmnd[0] == READ_CAPACITY) {
|
||||
if (l > 8)
|
||||
l = 8;
|
||||
}
|
||||
if (workreq->cmnd[0] == 0x00) {
|
||||
if (workreq->cmnd[0] == TEST_UNIT_READY) {
|
||||
l = 0;
|
||||
}
|
||||
|
||||
@ -796,8 +839,9 @@ static void send_s870(struct atp_unit *dev,unsigned char c)
|
||||
* Write the target
|
||||
*/
|
||||
atp_writeb_io(dev, c, 0x11, dev->id[c][target_id].devsp);
|
||||
#ifdef ED_DBGP
|
||||
printk("dev->id[%d][%d].devsp = %2x\n",c,target_id,dev->id[c][target_id].devsp);
|
||||
#ifdef ED_DBGP
|
||||
printk("dev->id[%d][%d].devsp = %2x\n",c,target_id,
|
||||
dev->id[c][target_id].devsp);
|
||||
#endif
|
||||
|
||||
sg_count = scsi_dma_map(workreq);
|
||||
@ -807,12 +851,12 @@ static void send_s870(struct atp_unit *dev,unsigned char c)
|
||||
atp_writeb_io(dev, c, 0x12, ((unsigned char *) (&l))[2]);
|
||||
atp_writeb_io(dev, c, 0x13, ((unsigned char *) (&l))[1]);
|
||||
atp_writeb_io(dev, c, 0x14, ((unsigned char *) (&l))[0]);
|
||||
j = target_id;
|
||||
j = target_id;
|
||||
dev->id[c][j].last_len = l;
|
||||
dev->id[c][j].tran_len = 0;
|
||||
#ifdef ED_DBGP
|
||||
#ifdef ED_DBGP
|
||||
printk("dev->id[%2d][%2d].last_len = %d\n",c,j,dev->id[c][j].last_len);
|
||||
#endif
|
||||
#endif
|
||||
/*
|
||||
* Flip the wide bits
|
||||
*/
|
||||
@ -832,8 +876,8 @@ static void send_s870(struct atp_unit *dev,unsigned char c)
|
||||
if (l == 0) {
|
||||
if (atp_readb_io(dev, c, 0x1c) == 0) {
|
||||
#ifdef ED_DBGP
|
||||
printk("change SCSI_CMD_REG 0x08\n");
|
||||
#endif
|
||||
printk("change SCSI_CMD_REG 0x08\n");
|
||||
#endif
|
||||
atp_writeb_io(dev, c, 0x18, 0x08);
|
||||
} else
|
||||
dev->last_cmd[c] |= 0x40;
|
||||
@ -854,9 +898,9 @@ static void send_s870(struct atp_unit *dev,unsigned char c)
|
||||
scsi_for_each_sg(workreq, sgpnt, sg_count, j) {
|
||||
bttl = sg_dma_address(sgpnt);
|
||||
l=sg_dma_len(sgpnt);
|
||||
#ifdef ED_DBGP
|
||||
#ifdef ED_DBGP
|
||||
printk("1. bttl %x, l %x\n",bttl, l);
|
||||
#endif
|
||||
#endif
|
||||
while (l > 0x10000) {
|
||||
(((u16 *) (prd))[i + 3]) = 0x0000;
|
||||
(((u16 *) (prd))[i + 2]) = 0x0000;
|
||||
@ -868,48 +912,65 @@ static void send_s870(struct atp_unit *dev,unsigned char c)
|
||||
(((u32 *) (prd))[i >> 1]) = cpu_to_le32(bttl);
|
||||
(((u16 *) (prd))[i + 2]) = cpu_to_le16(l);
|
||||
(((u16 *) (prd))[i + 3]) = 0;
|
||||
i += 0x04;
|
||||
i += 0x04;
|
||||
}
|
||||
(((u16 *) (prd))[i - 1]) = cpu_to_le16(0x8000);
|
||||
#ifdef ED_DBGP
|
||||
printk("prd %4x %4x %4x %4x\n",(((unsigned short int *)prd)[0]),(((unsigned short int *)prd)[1]),(((unsigned short int *)prd)[2]),(((unsigned short int *)prd)[3]));
|
||||
(((u16 *) (prd))[i - 1]) = cpu_to_le16(0x8000);
|
||||
#ifdef ED_DBGP
|
||||
printk("prd %4x %4x %4x %4x\n",
|
||||
(((unsigned short int *)prd)[0]),
|
||||
(((unsigned short int *)prd)[1]),
|
||||
(((unsigned short int *)prd)[2]),
|
||||
(((unsigned short int *)prd)[3]));
|
||||
printk("2. bttl %x, l %x\n",bttl, l);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
#ifdef ED_DBGP
|
||||
printk("send_s870: prdaddr_2 0x%8x target_id %d\n", dev->id[c][target_id].prdaddr,target_id);
|
||||
#endif
|
||||
#ifdef ED_DBGP
|
||||
printk("send_s870: prdaddr_2 0x%8x target_id %d\n",
|
||||
dev->id[c][target_id].prdaddr,target_id);
|
||||
#endif
|
||||
dev->id[c][target_id].prdaddr = dev->id[c][target_id].prd_bus;
|
||||
atp_writel_pci(dev, c, 4, dev->id[c][target_id].prdaddr);
|
||||
atp_writeb_pci(dev, c, 2, 0x06);
|
||||
atp_writeb_pci(dev, c, 2, 0x00);
|
||||
if (is885(dev)) {
|
||||
j = atp_readb_pci(dev, c, 1) & 0xf3;
|
||||
if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) ||
|
||||
(workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) {
|
||||
j |= 0x0c;
|
||||
if ((workreq->cmnd[0] == READ_6) ||
|
||||
(workreq->cmnd[0] == READ_10) ||
|
||||
(workreq->cmnd[0] == WRITE_6) ||
|
||||
(workreq->cmnd[0] == WRITE_10)) {
|
||||
j |= 0x0c;
|
||||
}
|
||||
atp_writeb_pci(dev, c, 1, j);
|
||||
} else if (is880(dev)) {
|
||||
if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a))
|
||||
atp_writeb_base(dev, 0x3b, (atp_readb_base(dev, 0x3b) & 0x3f) | 0xc0);
|
||||
if ((workreq->cmnd[0] == READ_6) ||
|
||||
(workreq->cmnd[0] == READ_10) ||
|
||||
(workreq->cmnd[0] == WRITE_6) ||
|
||||
(workreq->cmnd[0] == WRITE_10))
|
||||
atp_writeb_base(dev, 0x3b,
|
||||
(atp_readb_base(dev, 0x3b) & 0x3f) | 0xc0);
|
||||
else
|
||||
atp_writeb_base(dev, 0x3b, atp_readb_base(dev, 0x3b) & 0x3f);
|
||||
} else {
|
||||
if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a))
|
||||
atp_writeb_base(dev, 0x3a, (atp_readb_base(dev, 0x3a) & 0xf3) | 0x08);
|
||||
atp_writeb_base(dev, 0x3b,
|
||||
atp_readb_base(dev, 0x3b) & 0x3f);
|
||||
} else {
|
||||
if ((workreq->cmnd[0] == READ_6) ||
|
||||
(workreq->cmnd[0] == READ_10) ||
|
||||
(workreq->cmnd[0] == WRITE_6) ||
|
||||
(workreq->cmnd[0] == WRITE_10))
|
||||
atp_writeb_base(dev, 0x3a,
|
||||
(atp_readb_base(dev, 0x3a) & 0xf3) | 0x08);
|
||||
else
|
||||
atp_writeb_base(dev, 0x3a, atp_readb_base(dev, 0x3a) & 0xf3);
|
||||
}
|
||||
atp_writeb_base(dev, 0x3a,
|
||||
atp_readb_base(dev, 0x3a) & 0xf3);
|
||||
}
|
||||
|
||||
if(workreq->sc_data_direction == DMA_TO_DEVICE) {
|
||||
dev->id[c][target_id].dirct = 0x20;
|
||||
if (atp_readb_io(dev, c, 0x1c) == 0) {
|
||||
atp_writeb_io(dev, c, 0x18, 0x08);
|
||||
atp_writeb_pci(dev, c, 0, 0x01);
|
||||
#ifdef ED_DBGP
|
||||
#ifdef ED_DBGP
|
||||
printk( "start DMA(to target)\n");
|
||||
#endif
|
||||
#endif
|
||||
} else {
|
||||
dev->last_cmd[c] |= 0x40;
|
||||
}
|
||||
@ -919,9 +980,9 @@ static void send_s870(struct atp_unit *dev,unsigned char c)
|
||||
if (atp_readb_io(dev, c, 0x1c) == 0) {
|
||||
atp_writeb_io(dev, c, 0x18, 0x08);
|
||||
atp_writeb_pci(dev, c, 0, 0x09);
|
||||
#ifdef ED_DBGP
|
||||
#ifdef ED_DBGP
|
||||
printk( "start DMA(to host)\n");
|
||||
#endif
|
||||
#endif
|
||||
} else {
|
||||
dev->last_cmd[c] |= 0x40;
|
||||
}
|
||||
@ -1193,7 +1254,9 @@ static void atp870u_free_tables(struct Scsi_Host *host)
|
||||
for (k = 0; k < 16; k++) {
|
||||
if (!atp_dev->id[j][k].prd_table)
|
||||
continue;
|
||||
dma_free_coherent(&atp_dev->pdev->dev, 1024, atp_dev->id[j][k].prd_table, atp_dev->id[j][k].prd_bus);
|
||||
dma_free_coherent(&atp_dev->pdev->dev, 1024,
|
||||
atp_dev->id[j][k].prd_table,
|
||||
atp_dev->id[j][k].prd_bus);
|
||||
atp_dev->id[j][k].prd_table = NULL;
|
||||
}
|
||||
}
|
||||
@ -1204,35 +1267,38 @@ static int atp870u_init_tables(struct Scsi_Host *host)
|
||||
struct atp_unit *atp_dev = (struct atp_unit *)&host->hostdata;
|
||||
int c,k;
|
||||
for(c=0;c < 2;c++) {
|
||||
for(k=0;k<16;k++) {
|
||||
atp_dev->id[c][k].prd_table = dma_alloc_coherent(&atp_dev->pdev->dev, 1024, &(atp_dev->id[c][k].prd_bus), GFP_KERNEL);
|
||||
if (!atp_dev->id[c][k].prd_table) {
|
||||
printk("atp870u_init_tables fail\n");
|
||||
for(k=0;k<16;k++) {
|
||||
atp_dev->id[c][k].prd_table =
|
||||
dma_alloc_coherent(&atp_dev->pdev->dev, 1024,
|
||||
&(atp_dev->id[c][k].prd_bus),
|
||||
GFP_KERNEL);
|
||||
if (!atp_dev->id[c][k].prd_table) {
|
||||
printk("atp870u_init_tables fail\n");
|
||||
atp870u_free_tables(host);
|
||||
return -ENOMEM;
|
||||
}
|
||||
atp_dev->id[c][k].prdaddr = atp_dev->id[c][k].prd_bus;
|
||||
atp_dev->id[c][k].devsp=0x20;
|
||||
atp_dev->id[c][k].devtype = 0x7f;
|
||||
atp_dev->id[c][k].curr_req = NULL;
|
||||
}
|
||||
|
||||
atp_dev->active_id[c] = 0;
|
||||
atp_dev->wide_id[c] = 0;
|
||||
atp_dev->host_id[c] = 0x07;
|
||||
atp_dev->quhd[c] = 0;
|
||||
atp_dev->quend[c] = 0;
|
||||
atp_dev->last_cmd[c] = 0xff;
|
||||
atp_dev->in_snd[c] = 0;
|
||||
atp_dev->in_int[c] = 0;
|
||||
|
||||
for (k = 0; k < qcnt; k++) {
|
||||
atp_dev->quereq[c][k] = NULL;
|
||||
}
|
||||
for (k = 0; k < 16; k++) {
|
||||
atp_dev->id[c][k].curr_req = NULL;
|
||||
}
|
||||
|
||||
atp_dev->active_id[c] = 0;
|
||||
atp_dev->wide_id[c] = 0;
|
||||
atp_dev->host_id[c] = 0x07;
|
||||
atp_dev->quhd[c] = 0;
|
||||
atp_dev->quend[c] = 0;
|
||||
atp_dev->last_cmd[c] = 0xff;
|
||||
atp_dev->in_snd[c] = 0;
|
||||
atp_dev->in_int[c] = 0;
|
||||
|
||||
for (k = 0; k < qcnt; k++) {
|
||||
atp_dev->quereq[c][k] = NULL;
|
||||
}
|
||||
for (k = 0; k < 16; k++) {
|
||||
atp_dev->id[c][k].curr_req = NULL;
|
||||
atp_dev->sp[c][k] = 0x04;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -1263,7 +1329,8 @@ static void atp870_init(struct Scsi_Host *shpnt)
|
||||
|
||||
pci_read_config_byte(pdev, 0x49, &host_id);
|
||||
|
||||
dev_info(&pdev->dev, "ACARD AEC-671X PCI Ultra/W SCSI-2/3 Host Adapter: IO:%lx, IRQ:%d.\n",
|
||||
dev_info(&pdev->dev, "ACARD AEC-671X PCI Ultra/W SCSI-2/3 "
|
||||
"Host Adapter: IO:%lx, IRQ:%d.\n",
|
||||
shpnt->io_port, shpnt->irq);
|
||||
|
||||
atpdev->ioport[0] = shpnt->io_port;
|
||||
@ -1314,7 +1381,8 @@ static void atp880_init(struct Scsi_Host *shpnt)
|
||||
|
||||
host_id = atp_readb_base(atpdev, 0x39) >> 4;
|
||||
|
||||
dev_info(&pdev->dev, "ACARD AEC-67160 PCI Ultra3 LVD Host Adapter: IO:%lx, IRQ:%d.\n",
|
||||
dev_info(&pdev->dev, "ACARD AEC-67160 PCI Ultra3 LVD "
|
||||
"Host Adapter: IO:%lx, IRQ:%d.\n",
|
||||
shpnt->io_port, shpnt->irq);
|
||||
atpdev->host_id[0] = host_id;
|
||||
|
||||
@ -1393,7 +1461,8 @@ static void atp885_init(struct Scsi_Host *shpnt)
|
||||
unsigned int n;
|
||||
unsigned char setupdata[2][16];
|
||||
|
||||
dev_info(&pdev->dev, "ACARD AEC-67162 PCI Ultra3 LVD Host Adapter: IO:%lx, IRQ:%d.\n",
|
||||
dev_info(&pdev->dev, "ACARD AEC-67162 PCI Ultra3 LVD "
|
||||
"Host Adapter: IO:%lx, IRQ:%d.\n",
|
||||
shpnt->io_port, shpnt->irq);
|
||||
|
||||
atpdev->ioport[0] = shpnt->io_port + 0x80;
|
||||
@ -1413,11 +1482,13 @@ static void atp885_init(struct Scsi_Host *shpnt)
|
||||
atpdev->global_map[m] = 0;
|
||||
for (k = 0; k < 4; k++) {
|
||||
atp_writew_base(atpdev, 0x3c, n++);
|
||||
((u32 *)&setupdata[m][0])[k] = atp_readl_base(atpdev, 0x38);
|
||||
((u32 *)&setupdata[m][0])[k] =
|
||||
atp_readl_base(atpdev, 0x38);
|
||||
}
|
||||
for (k = 0; k < 4; k++) {
|
||||
atp_writew_base(atpdev, 0x3c, n++);
|
||||
((u32 *)&atpdev->sp[m][0])[k] = atp_readl_base(atpdev, 0x38);
|
||||
((u32 *)&atpdev->sp[m][0])[k] =
|
||||
atp_readl_base(atpdev, 0x38);
|
||||
}
|
||||
n += 8;
|
||||
}
|
||||
@ -1510,17 +1581,17 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
goto fail;
|
||||
|
||||
if (dma_set_mask(&pdev->dev, DMA_BIT_MASK(32))) {
|
||||
printk(KERN_ERR "atp870u: DMA mask required but not available.\n");
|
||||
err = -EIO;
|
||||
goto disable_device;
|
||||
}
|
||||
printk(KERN_ERR "atp870u: DMA mask required but not available.\n");
|
||||
err = -EIO;
|
||||
goto disable_device;
|
||||
}
|
||||
|
||||
err = pci_request_regions(pdev, "atp870u");
|
||||
if (err)
|
||||
goto disable_device;
|
||||
pci_set_master(pdev);
|
||||
|
||||
err = -ENOMEM;
|
||||
err = -ENOMEM;
|
||||
shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit));
|
||||
if (!shpnt)
|
||||
goto release_region;
|
||||
@ -1586,7 +1657,7 @@ static int atp870u_abort(struct scsi_cmnd * SCpnt)
|
||||
{
|
||||
unsigned char j, k, c;
|
||||
struct scsi_cmnd *workrequ;
|
||||
struct atp_unit *dev;
|
||||
struct atp_unit *dev;
|
||||
struct Scsi_Host *host;
|
||||
host = SCpnt->device->host;
|
||||
|
||||
@ -1655,11 +1726,10 @@ static int atp870u_biosparam(struct scsi_device *disk, struct block_device *dev,
|
||||
}
|
||||
|
||||
static void atp870u_remove (struct pci_dev *pdev)
|
||||
{
|
||||
{
|
||||
struct atp_unit *devext = pci_get_drvdata(pdev);
|
||||
struct Scsi_Host *pshost = devext->host;
|
||||
|
||||
|
||||
|
||||
scsi_remove_host(pshost);
|
||||
free_irq(pshost->irq, pshost);
|
||||
pci_release_regions(pdev);
|
||||
@ -1671,23 +1741,23 @@ MODULE_LICENSE("GPL");
|
||||
|
||||
static struct scsi_host_template atp870u_template = {
|
||||
.module = THIS_MODULE,
|
||||
.name = "atp870u" /* name */,
|
||||
.name = "atp870u" /* name */,
|
||||
.proc_name = "atp870u",
|
||||
.show_info = atp870u_show_info,
|
||||
.info = atp870u_info /* info */,
|
||||
.queuecommand = atp870u_queuecommand /* queuecommand */,
|
||||
.eh_abort_handler = atp870u_abort /* abort */,
|
||||
.bios_param = atp870u_biosparam /* biosparm */,
|
||||
.can_queue = qcnt /* can_queue */,
|
||||
.this_id = 7 /* SCSI ID */,
|
||||
.sg_tablesize = ATP870U_SCATTER /*SG_ALL*/,
|
||||
.info = atp870u_info /* info */,
|
||||
.queuecommand = atp870u_queuecommand /* queuecommand */,
|
||||
.eh_abort_handler = atp870u_abort /* abort */,
|
||||
.bios_param = atp870u_biosparam /* biosparm */,
|
||||
.can_queue = qcnt /* can_queue */,
|
||||
.this_id = 7 /* SCSI ID */,
|
||||
.sg_tablesize = ATP870U_SCATTER /*SG_ALL*/,
|
||||
.max_sectors = ATP870U_MAX_SECTORS,
|
||||
};
|
||||
|
||||
static struct pci_device_id atp870u_id_table[] = {
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_ARTOP, ATP885_DEVID) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_ARTOP, ATP880_DEVID1) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_ARTOP, ATP880_DEVID2) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_ARTOP, ATP880_DEVID1) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_ARTOP, ATP880_DEVID2) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_AEC7610) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_AEC7612UW) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_AEC7612U) },
|
||||
@ -1709,7 +1779,8 @@ static struct pci_driver atp870u_driver = {
|
||||
|
||||
module_pci_driver(atp870u_driver);
|
||||
|
||||
static void atp_is(struct atp_unit *dev, unsigned char c, bool wide_chip, unsigned char lvdmode)
|
||||
static void atp_is(struct atp_unit *dev, unsigned char c, bool wide_chip,
|
||||
unsigned char lvdmode)
|
||||
{
|
||||
unsigned char i, j, k, rmb, n;
|
||||
unsigned short int m;
|
||||
@ -1982,8 +2053,9 @@ static void atp_is(struct atp_unit *dev, unsigned char c, bool wide_chip, unsign
|
||||
m = m << i;
|
||||
dev->wide_id[c] |= m;
|
||||
dev->id[c][i].devsp = 0xce;
|
||||
#ifdef ED_DBGP
|
||||
printk("dev->id[%2d][%2d].devsp = %2x\n",c,i,dev->id[c][i].devsp);
|
||||
#ifdef ED_DBGP
|
||||
printk("dev->id[%2d][%2d].devsp = %2x\n",
|
||||
c, i, dev->id[c][i].devsp);
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
@ -2005,7 +2077,8 @@ static void atp_is(struct atp_unit *dev, unsigned char c, bool wide_chip, unsign
|
||||
while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00)
|
||||
cpu_relax();
|
||||
|
||||
if (atp_readb_io(dev, c, 0x17) != 0x11 && atp_readb_io(dev, c, 0x17) != 0x8e)
|
||||
if (atp_readb_io(dev, c, 0x17) != 0x11 &&
|
||||
atp_readb_io(dev, c, 0x17) != 0x8e)
|
||||
continue;
|
||||
|
||||
while (atp_readb_io(dev, c, 0x17) != 0x8e)
|
||||
@ -2109,7 +2182,9 @@ static void atp_is(struct atp_unit *dev, unsigned char c, bool wide_chip, unsign
|
||||
m = m << i;
|
||||
dev->wide_id[c] |= m;
|
||||
not_wide:
|
||||
if ((dev->id[c][i].devtype == 0x00) || (dev->id[c][i].devtype == 0x07) || ((dev->id[c][i].devtype == 0x05) && ((n & 0x10) != 0))) {
|
||||
if ((dev->id[c][i].devtype == 0x00) ||
|
||||
(dev->id[c][i].devtype == 0x07) ||
|
||||
((dev->id[c][i].devtype == 0x05) && ((n & 0x10) != 0))) {
|
||||
m = 1;
|
||||
m = m << i;
|
||||
if ((dev->async[c] & m) != 0) {
|
||||
@ -2148,7 +2223,8 @@ static void atp_is(struct atp_unit *dev, unsigned char c, bool wide_chip, unsign
|
||||
while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00)
|
||||
cpu_relax();
|
||||
|
||||
if (atp_readb_io(dev, c, 0x17) != 0x11 && atp_readb_io(dev, c, 0x17) != 0x8e)
|
||||
if (atp_readb_io(dev, c, 0x17) != 0x11 &&
|
||||
atp_readb_io(dev, c, 0x17) != 0x8e)
|
||||
continue;
|
||||
|
||||
while (atp_readb_io(dev, c, 0x17) != 0x8e)
|
||||
@ -2310,7 +2386,8 @@ static void atp_is(struct atp_unit *dev, unsigned char c, bool wide_chip, unsign
|
||||
set_syn_ok:
|
||||
dev->id[c][i].devsp = (dev->id[c][i].devsp & 0x0f) | j;
|
||||
#ifdef ED_DBGP
|
||||
printk("dev->id[%2d][%2d].devsp = %2x\n",c,i,dev->id[c][i].devsp);
|
||||
printk("dev->id[%2d][%2d].devsp = %2x\n",
|
||||
c,i,dev->id[c][i].devsp);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -7,10 +7,10 @@
|
||||
|
||||
/* I/O Port */
|
||||
|
||||
#define MAX_CDB 12
|
||||
#define MAX_SENSE 14
|
||||
#define qcnt 32
|
||||
#define ATP870U_SCATTER 128
|
||||
#define MAX_CDB 12
|
||||
#define MAX_SENSE 14
|
||||
#define qcnt 32
|
||||
#define ATP870U_SCATTER 128
|
||||
|
||||
#define MAX_ADAPTER 8
|
||||
#define MAX_SCSI_ID 16
|
||||
@ -40,7 +40,7 @@ struct atp_unit
|
||||
unsigned short ultra_map[2];
|
||||
unsigned short async[2];
|
||||
unsigned char sp[2][16];
|
||||
unsigned char r1f[2][16];
|
||||
unsigned char r1f[2][16];
|
||||
struct scsi_cmnd *quereq[2][qcnt];
|
||||
struct atp_id
|
||||
{
|
||||
@ -55,8 +55,8 @@ struct atp_unit
|
||||
dma_addr_t prdaddr; /* Dynamically updated in driver */
|
||||
struct scsi_cmnd *curr_req;
|
||||
} id[2][16];
|
||||
struct Scsi_Host *host;
|
||||
struct pci_dev *pdev;
|
||||
struct Scsi_Host *host;
|
||||
struct pci_dev *pdev;
|
||||
unsigned int unit;
|
||||
};
|
||||
|
||||
|
@ -33,21 +33,6 @@ struct scsi_cdb_s {
|
||||
u8 scsi_cdb[SCSI_MAX_CDBLEN];
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------
|
||||
* SCSI status byte values
|
||||
* ------------------------------------------------------------
|
||||
*/
|
||||
#define SCSI_STATUS_GOOD 0x00
|
||||
#define SCSI_STATUS_CHECK_CONDITION 0x02
|
||||
#define SCSI_STATUS_CONDITION_MET 0x04
|
||||
#define SCSI_STATUS_BUSY 0x08
|
||||
#define SCSI_STATUS_INTERMEDIATE 0x10
|
||||
#define SCSI_STATUS_ICM 0x14 /* intermediate condition met */
|
||||
#define SCSI_STATUS_RESERVATION_CONFLICT 0x18
|
||||
#define SCSI_STATUS_COMMAND_TERMINATED 0x22
|
||||
#define SCSI_STATUS_QUEUE_FULL 0x28
|
||||
#define SCSI_STATUS_ACA_ACTIVE 0x30
|
||||
|
||||
#define SCSI_MAX_ALLOC_LEN 0xFF /* maximum allocarion length */
|
||||
|
||||
/*
|
||||
|
@ -2146,7 +2146,7 @@ __bfa_cb_ioim_comp(void *cbarg, bfa_boolean_t complete)
|
||||
/*
|
||||
* setup sense information, if present
|
||||
*/
|
||||
if ((m->scsi_status == SCSI_STATUS_CHECK_CONDITION) &&
|
||||
if ((m->scsi_status == SAM_STAT_CHECK_CONDITION) &&
|
||||
m->sns_len) {
|
||||
sns_len = m->sns_len;
|
||||
snsinfo = BFA_SNSINFO_FROM_TAG(ioim->fcpim->fcp,
|
||||
|
@ -106,7 +106,7 @@ bfa_cb_ioim_good_comp(void *drv, struct bfad_ioim_s *dio)
|
||||
struct bfad_itnim_data_s *itnim_data;
|
||||
struct bfad_itnim_s *itnim;
|
||||
|
||||
cmnd->result = DID_OK << 16 | SCSI_STATUS_GOOD;
|
||||
cmnd->result = DID_OK << 16 | SAM_STAT_GOOD;
|
||||
|
||||
/* Unmap DMA, if host is NULL, it means a scsi passthru cmd */
|
||||
if (cmnd->device->host != NULL)
|
||||
|
@ -64,6 +64,7 @@
|
||||
#include <scsi/scsi_cmnd.h>
|
||||
#include <scsi/scsi_device.h>
|
||||
#include <scsi/scsi_host.h>
|
||||
#include <scsi/scsi_transport_spi.h>
|
||||
|
||||
#include "dc395x.h"
|
||||
|
||||
@ -1281,12 +1282,8 @@ static void build_sdtr(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb,
|
||||
} else if (dcb->sync_offset == 0)
|
||||
dcb->sync_offset = SYNC_NEGO_OFFSET;
|
||||
|
||||
*ptr++ = MSG_EXTENDED; /* (01h) */
|
||||
*ptr++ = 3; /* length */
|
||||
*ptr++ = EXTENDED_SDTR; /* (01h) */
|
||||
*ptr++ = dcb->min_nego_period; /* Transfer period (in 4ns) */
|
||||
*ptr++ = dcb->sync_offset; /* Transfer period (max. REQ/ACK dist) */
|
||||
srb->msg_count += 5;
|
||||
srb->msg_count += spi_populate_sync_msg(ptr, dcb->min_nego_period,
|
||||
dcb->sync_offset);
|
||||
srb->state |= SRB_DO_SYNC_NEGO;
|
||||
}
|
||||
|
||||
@ -1305,11 +1302,7 @@ static void build_wdtr(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb,
|
||||
srb->msgout_buf[1]);
|
||||
return;
|
||||
}
|
||||
*ptr++ = MSG_EXTENDED; /* (01h) */
|
||||
*ptr++ = 2; /* length */
|
||||
*ptr++ = EXTENDED_WDTR; /* (03h) */
|
||||
*ptr++ = wide;
|
||||
srb->msg_count += 4;
|
||||
srb->msg_count += spi_populate_width_msg(ptr, wide);
|
||||
srb->state |= SRB_DO_WIDE_NEGO;
|
||||
}
|
||||
|
||||
@ -1476,7 +1469,7 @@ static u8 start_scsi(struct AdapterCtlBlk* acb, struct DeviceCtlBlk* dcb,
|
||||
return 1;
|
||||
}
|
||||
/* Send Tag id */
|
||||
DC395x_write8(acb, TRM_S1040_SCSI_FIFO, MSG_SIMPLE_QTAG);
|
||||
DC395x_write8(acb, TRM_S1040_SCSI_FIFO, SIMPLE_QUEUE_TAG);
|
||||
DC395x_write8(acb, TRM_S1040_SCSI_FIFO, tag_number);
|
||||
dcb->tag_mask |= tag_mask;
|
||||
srb->tag_number = tag_number;
|
||||
@ -1732,8 +1725,9 @@ static void msgout_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
|
||||
if (!srb->msg_count) {
|
||||
dprintkdbg(DBG_0, "msgout_phase1: (0x%p) NOP msg\n",
|
||||
srb->cmd);
|
||||
DC395x_write8(acb, TRM_S1040_SCSI_FIFO, MSG_NOP);
|
||||
DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_DATALATCH); /* it's important for atn stop */
|
||||
DC395x_write8(acb, TRM_S1040_SCSI_FIFO, NOP);
|
||||
DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_DATALATCH);
|
||||
/* it's important for atn stop */
|
||||
DC395x_write8(acb, TRM_S1040_SCSI_COMMAND, SCMD_FIFO_OUT);
|
||||
return;
|
||||
}
|
||||
@ -1741,7 +1735,7 @@ static void msgout_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
|
||||
for (i = 0; i < srb->msg_count; i++)
|
||||
DC395x_write8(acb, TRM_S1040_SCSI_FIFO, *ptr++);
|
||||
srb->msg_count = 0;
|
||||
if (srb->msgout_buf[0] == MSG_ABORT)
|
||||
if (srb->msgout_buf[0] == ABORT_TASK_SET)
|
||||
srb->state = SRB_ABORT_SENT;
|
||||
|
||||
DC395x_write8(acb, TRM_S1040_SCSI_COMMAND, SCMD_FIFO_OUT);
|
||||
@ -2538,7 +2532,7 @@ static struct ScsiReqBlk *msgin_qtag(struct AdapterCtlBlk *acb,
|
||||
srb = acb->tmp_srb;
|
||||
srb->state = SRB_UNEXPECT_RESEL;
|
||||
dcb->active_srb = srb;
|
||||
srb->msgout_buf[0] = MSG_ABORT_TAG;
|
||||
srb->msgout_buf[0] = ABORT_TASK;
|
||||
srb->msg_count = 1;
|
||||
DC395x_ENABLE_MSGOUT;
|
||||
dprintkl(KERN_DEBUG, "msgin_qtag: Unknown tag %i - abort\n", tag);
|
||||
@ -2780,7 +2774,7 @@ static void msgin_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
|
||||
msgin_reject(acb, srb);
|
||||
break;
|
||||
|
||||
case MSG_IGNOREWIDE:
|
||||
case IGNORE_WIDE_RESIDUE:
|
||||
/* Discard wide residual */
|
||||
dprintkdbg(DBG_0, "msgin_phase0: Ignore Wide Residual!\n");
|
||||
break;
|
||||
|
@ -156,15 +156,6 @@
|
||||
#define H_ABORT 0x0FF
|
||||
|
||||
/* SCSI BUS Status byte codes */
|
||||
#define SCSI_STAT_GOOD 0x0 /* Good status */
|
||||
#define SCSI_STAT_CHECKCOND 0x02 /* SCSI Check Condition */
|
||||
#define SCSI_STAT_CONDMET 0x04 /* Condition Met */
|
||||
#define SCSI_STAT_BUSY 0x08 /* Target busy status */
|
||||
#define SCSI_STAT_INTER 0x10 /* Intermediate status */
|
||||
#define SCSI_STAT_INTERCONDMET 0x14 /* Intermediate condition met */
|
||||
#define SCSI_STAT_RESCONFLICT 0x18 /* Reservation conflict */
|
||||
#define SCSI_STAT_CMDTERM 0x22 /* Command Terminated */
|
||||
#define SCSI_STAT_QUEUEFULL 0x28 /* Queue Full */
|
||||
#define SCSI_STAT_UNEXP_BUS_F 0xFD /* Unexpect Bus Free */
|
||||
#define SCSI_STAT_BUS_RST_DETECT 0xFE /* Scsi Bus Reset detected */
|
||||
#define SCSI_STAT_SEL_TIMEOUT 0xFF /* Selection Time out */
|
||||
@ -181,35 +172,6 @@
|
||||
|
||||
#define SYNC_NEGO_OFFSET 15
|
||||
|
||||
/* SCSI MSG BYTE */
|
||||
#define MSG_COMPLETE 0x00
|
||||
#define MSG_EXTENDED 0x01
|
||||
#define MSG_SAVE_PTR 0x02
|
||||
#define MSG_RESTORE_PTR 0x03
|
||||
#define MSG_DISCONNECT 0x04
|
||||
#define MSG_INITIATOR_ERROR 0x05
|
||||
#define MSG_ABORT 0x06
|
||||
#define MSG_REJECT_ 0x07
|
||||
#define MSG_NOP 0x08
|
||||
#define MSG_PARITY_ERROR 0x09
|
||||
#define MSG_LINK_CMD_COMPL 0x0A
|
||||
#define MSG_LINK_CMD_COMPL_FLG 0x0B
|
||||
#define MSG_BUS_RESET 0x0C
|
||||
#define MSG_ABORT_TAG 0x0D
|
||||
#define MSG_SIMPLE_QTAG 0x20
|
||||
#define MSG_HEAD_QTAG 0x21
|
||||
#define MSG_ORDER_QTAG 0x22
|
||||
#define MSG_IGNOREWIDE 0x23
|
||||
#define MSG_IDENTIFY 0x80
|
||||
#define MSG_HOST_ID 0xC0
|
||||
|
||||
/* SCSI STATUS BYTE */
|
||||
#define STATUS_GOOD 0x00
|
||||
#define CHECK_CONDITION_ 0x02
|
||||
#define STATUS_BUSY 0x08
|
||||
#define STATUS_INTERMEDIATE 0x10
|
||||
#define RESERVE_CONFLICT 0x18
|
||||
|
||||
/* cmd->result */
|
||||
#define STATUS_MASK_ 0xFF
|
||||
#define MSG_MASK 0xFF00
|
||||
|
@ -2226,7 +2226,7 @@ static s32 adpt_scsi_to_i2o(adpt_hba* pHba, struct scsi_cmnd* cmd, struct adpt_d
|
||||
default:
|
||||
printk(KERN_WARNING"%s: scsi opcode 0x%x not supported.\n",
|
||||
pHba->name, cmd->cmnd[0]);
|
||||
cmd->result = (DID_OK <<16) | (INITIATOR_ERROR << 8);
|
||||
cmd->result = (DID_ERROR <<16);
|
||||
cmd->scsi_done(cmd);
|
||||
return 0;
|
||||
}
|
||||
|
@ -896,7 +896,7 @@ static void esp_put_ent(struct esp *esp, struct esp_cmd_entry *ent)
|
||||
}
|
||||
|
||||
static void esp_cmd_is_done(struct esp *esp, struct esp_cmd_entry *ent,
|
||||
struct scsi_cmnd *cmd, unsigned int result)
|
||||
struct scsi_cmnd *cmd, unsigned char host_byte)
|
||||
{
|
||||
struct scsi_device *dev = cmd->device;
|
||||
int tgt = dev->id;
|
||||
@ -905,7 +905,10 @@ static void esp_cmd_is_done(struct esp *esp, struct esp_cmd_entry *ent,
|
||||
esp->active_cmd = NULL;
|
||||
esp_unmap_dma(esp, cmd);
|
||||
esp_free_lun_tag(ent, dev->hostdata);
|
||||
cmd->result = result;
|
||||
cmd->result = 0;
|
||||
set_host_byte(cmd, host_byte);
|
||||
if (host_byte == DID_OK)
|
||||
set_status_byte(cmd, ent->status);
|
||||
|
||||
if (ent->eh_done) {
|
||||
complete(ent->eh_done);
|
||||
@ -921,7 +924,6 @@ static void esp_cmd_is_done(struct esp *esp, struct esp_cmd_entry *ent,
|
||||
*/
|
||||
cmd->result = ((DRIVER_SENSE << 24) |
|
||||
(DID_OK << 16) |
|
||||
(COMMAND_COMPLETE << 8) |
|
||||
(SAM_STAT_CHECK_CONDITION << 0));
|
||||
|
||||
ent->flags &= ~ESP_CMD_FLAG_AUTOSENSE;
|
||||
@ -944,12 +946,6 @@ static void esp_cmd_is_done(struct esp *esp, struct esp_cmd_entry *ent,
|
||||
esp_maybe_execute_command(esp);
|
||||
}
|
||||
|
||||
static unsigned int compose_result(unsigned int status, unsigned int message,
|
||||
unsigned int driver_code)
|
||||
{
|
||||
return (status | (message << 8) | (driver_code << 16));
|
||||
}
|
||||
|
||||
static void esp_event_queue_full(struct esp *esp, struct esp_cmd_entry *ent)
|
||||
{
|
||||
struct scsi_device *dev = ent->cmd->device;
|
||||
@ -1244,7 +1240,7 @@ static int esp_finish_select(struct esp *esp)
|
||||
* all bets are off.
|
||||
*/
|
||||
esp_schedule_reset(esp);
|
||||
esp_cmd_is_done(esp, ent, cmd, (DID_ERROR << 16));
|
||||
esp_cmd_is_done(esp, ent, cmd, DID_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1289,7 +1285,7 @@ static int esp_finish_select(struct esp *esp)
|
||||
esp->target[dev->id].flags |= ESP_TGT_CHECK_NEGO;
|
||||
|
||||
scsi_esp_cmd(esp, ESP_CMD_ESEL);
|
||||
esp_cmd_is_done(esp, ent, cmd, (DID_BAD_TARGET << 16));
|
||||
esp_cmd_is_done(esp, ent, cmd, DID_BAD_TARGET);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -1874,10 +1870,7 @@ static int esp_process_event(struct esp *esp)
|
||||
ent->flags |= ESP_CMD_FLAG_AUTOSENSE;
|
||||
esp_autosense(esp, ent);
|
||||
} else {
|
||||
esp_cmd_is_done(esp, ent, cmd,
|
||||
compose_result(ent->status,
|
||||
ent->message,
|
||||
DID_OK));
|
||||
esp_cmd_is_done(esp, ent, cmd, DID_OK);
|
||||
}
|
||||
} else if (ent->message == DISCONNECT) {
|
||||
esp_log_disconnect("Disconnecting tgt[%d] tag[%x:%x]\n",
|
||||
|
4322
drivers/scsi/gdth.c
4322
drivers/scsi/gdth.c
File diff suppressed because it is too large
Load Diff
@ -1,981 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _GDTH_H
|
||||
#define _GDTH_H
|
||||
|
||||
/*
|
||||
* Header file for the GDT Disk Array/Storage RAID controllers driver for Linux
|
||||
*
|
||||
* gdth.h Copyright (C) 1995-06 ICP vortex, Achim Leubner
|
||||
* See gdth.c for further informations and
|
||||
* below for supported controller types
|
||||
*
|
||||
* <achim_leubner@adaptec.com>
|
||||
*
|
||||
* $Id: gdth.h,v 1.58 2006/01/11 16:14:09 achim Exp $
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
/* defines, macros */
|
||||
|
||||
/* driver version */
|
||||
#define GDTH_VERSION_STR "3.05"
|
||||
#define GDTH_VERSION 3
|
||||
#define GDTH_SUBVERSION 5
|
||||
|
||||
/* protocol version */
|
||||
#define PROTOCOL_VERSION 1
|
||||
|
||||
/* OEM IDs */
|
||||
#define OEM_ID_ICP 0x941c
|
||||
#define OEM_ID_INTEL 0x8000
|
||||
|
||||
/* controller classes */
|
||||
#define GDT_PCI 0x03 /* PCI controller */
|
||||
#define GDT_PCINEW 0x04 /* new PCI controller */
|
||||
#define GDT_PCIMPR 0x05 /* PCI MPR controller */
|
||||
|
||||
#ifndef PCI_DEVICE_ID_VORTEX_GDT60x0
|
||||
/* GDT_PCI */
|
||||
#define PCI_DEVICE_ID_VORTEX_GDT60x0 0 /* GDT6000/6020/6050 */
|
||||
#define PCI_DEVICE_ID_VORTEX_GDT6000B 1 /* GDT6000B/6010 */
|
||||
/* GDT_PCINEW */
|
||||
#define PCI_DEVICE_ID_VORTEX_GDT6x10 2 /* GDT6110/6510 */
|
||||
#define PCI_DEVICE_ID_VORTEX_GDT6x20 3 /* GDT6120/6520 */
|
||||
#define PCI_DEVICE_ID_VORTEX_GDT6530 4 /* GDT6530 */
|
||||
#define PCI_DEVICE_ID_VORTEX_GDT6550 5 /* GDT6550 */
|
||||
/* GDT_PCINEW, wide/ultra SCSI controllers */
|
||||
#define PCI_DEVICE_ID_VORTEX_GDT6x17 6 /* GDT6117/6517 */
|
||||
#define PCI_DEVICE_ID_VORTEX_GDT6x27 7 /* GDT6127/6527 */
|
||||
#define PCI_DEVICE_ID_VORTEX_GDT6537 8 /* GDT6537 */
|
||||
#define PCI_DEVICE_ID_VORTEX_GDT6557 9 /* GDT6557/6557-ECC */
|
||||
/* GDT_PCINEW, wide SCSI controllers */
|
||||
#define PCI_DEVICE_ID_VORTEX_GDT6x15 10 /* GDT6115/6515 */
|
||||
#define PCI_DEVICE_ID_VORTEX_GDT6x25 11 /* GDT6125/6525 */
|
||||
#define PCI_DEVICE_ID_VORTEX_GDT6535 12 /* GDT6535 */
|
||||
#define PCI_DEVICE_ID_VORTEX_GDT6555 13 /* GDT6555/6555-ECC */
|
||||
#endif
|
||||
|
||||
#ifndef PCI_DEVICE_ID_VORTEX_GDT6x17RP
|
||||
/* GDT_MPR, RP series, wide/ultra SCSI */
|
||||
#define PCI_DEVICE_ID_VORTEX_GDT6x17RP 0x100 /* GDT6117RP/GDT6517RP */
|
||||
#define PCI_DEVICE_ID_VORTEX_GDT6x27RP 0x101 /* GDT6127RP/GDT6527RP */
|
||||
#define PCI_DEVICE_ID_VORTEX_GDT6537RP 0x102 /* GDT6537RP */
|
||||
#define PCI_DEVICE_ID_VORTEX_GDT6557RP 0x103 /* GDT6557RP */
|
||||
/* GDT_MPR, RP series, narrow/ultra SCSI */
|
||||
#define PCI_DEVICE_ID_VORTEX_GDT6x11RP 0x104 /* GDT6111RP/GDT6511RP */
|
||||
#define PCI_DEVICE_ID_VORTEX_GDT6x21RP 0x105 /* GDT6121RP/GDT6521RP */
|
||||
#endif
|
||||
#ifndef PCI_DEVICE_ID_VORTEX_GDT6x17RD
|
||||
/* GDT_MPR, RD series, wide/ultra SCSI */
|
||||
#define PCI_DEVICE_ID_VORTEX_GDT6x17RD 0x110 /* GDT6117RD/GDT6517RD */
|
||||
#define PCI_DEVICE_ID_VORTEX_GDT6x27RD 0x111 /* GDT6127RD/GDT6527RD */
|
||||
#define PCI_DEVICE_ID_VORTEX_GDT6537RD 0x112 /* GDT6537RD */
|
||||
#define PCI_DEVICE_ID_VORTEX_GDT6557RD 0x113 /* GDT6557RD */
|
||||
/* GDT_MPR, RD series, narrow/ultra SCSI */
|
||||
#define PCI_DEVICE_ID_VORTEX_GDT6x11RD 0x114 /* GDT6111RD/GDT6511RD */
|
||||
#define PCI_DEVICE_ID_VORTEX_GDT6x21RD 0x115 /* GDT6121RD/GDT6521RD */
|
||||
/* GDT_MPR, RD series, wide/ultra2 SCSI */
|
||||
#define PCI_DEVICE_ID_VORTEX_GDT6x18RD 0x118 /* GDT6118RD/GDT6518RD/
|
||||
GDT6618RD */
|
||||
#define PCI_DEVICE_ID_VORTEX_GDT6x28RD 0x119 /* GDT6128RD/GDT6528RD/
|
||||
GDT6628RD */
|
||||
#define PCI_DEVICE_ID_VORTEX_GDT6x38RD 0x11A /* GDT6538RD/GDT6638RD */
|
||||
#define PCI_DEVICE_ID_VORTEX_GDT6x58RD 0x11B /* GDT6558RD/GDT6658RD */
|
||||
/* GDT_MPR, RN series (64-bit PCI), wide/ultra2 SCSI */
|
||||
#define PCI_DEVICE_ID_VORTEX_GDT7x18RN 0x168 /* GDT7118RN/GDT7518RN/
|
||||
GDT7618RN */
|
||||
#define PCI_DEVICE_ID_VORTEX_GDT7x28RN 0x169 /* GDT7128RN/GDT7528RN/
|
||||
GDT7628RN */
|
||||
#define PCI_DEVICE_ID_VORTEX_GDT7x38RN 0x16A /* GDT7538RN/GDT7638RN */
|
||||
#define PCI_DEVICE_ID_VORTEX_GDT7x58RN 0x16B /* GDT7558RN/GDT7658RN */
|
||||
#endif
|
||||
|
||||
#ifndef PCI_DEVICE_ID_VORTEX_GDT6x19RD
|
||||
/* GDT_MPR, RD series, Fibre Channel */
|
||||
#define PCI_DEVICE_ID_VORTEX_GDT6x19RD 0x210 /* GDT6519RD/GDT6619RD */
|
||||
#define PCI_DEVICE_ID_VORTEX_GDT6x29RD 0x211 /* GDT6529RD/GDT6629RD */
|
||||
/* GDT_MPR, RN series (64-bit PCI), Fibre Channel */
|
||||
#define PCI_DEVICE_ID_VORTEX_GDT7x19RN 0x260 /* GDT7519RN/GDT7619RN */
|
||||
#define PCI_DEVICE_ID_VORTEX_GDT7x29RN 0x261 /* GDT7529RN/GDT7629RN */
|
||||
#endif
|
||||
|
||||
#ifndef PCI_DEVICE_ID_VORTEX_GDTMAXRP
|
||||
/* GDT_MPR, last device ID */
|
||||
#define PCI_DEVICE_ID_VORTEX_GDTMAXRP 0x2ff
|
||||
#endif
|
||||
|
||||
#ifndef PCI_DEVICE_ID_VORTEX_GDTNEWRX
|
||||
/* new GDT Rx Controller */
|
||||
#define PCI_DEVICE_ID_VORTEX_GDTNEWRX 0x300
|
||||
#endif
|
||||
|
||||
#ifndef PCI_DEVICE_ID_VORTEX_GDTNEWRX2
|
||||
/* new(2) GDT Rx Controller */
|
||||
#define PCI_DEVICE_ID_VORTEX_GDTNEWRX2 0x301
|
||||
#endif
|
||||
|
||||
#ifndef PCI_DEVICE_ID_INTEL_SRC
|
||||
/* Intel Storage RAID Controller */
|
||||
#define PCI_DEVICE_ID_INTEL_SRC 0x600
|
||||
#endif
|
||||
|
||||
#ifndef PCI_DEVICE_ID_INTEL_SRC_XSCALE
|
||||
/* Intel Storage RAID Controller */
|
||||
#define PCI_DEVICE_ID_INTEL_SRC_XSCALE 0x601
|
||||
#endif
|
||||
|
||||
/* limits */
|
||||
#define GDTH_SCRATCH PAGE_SIZE /* 4KB scratch buffer */
|
||||
#define GDTH_MAXCMDS 120
|
||||
#define GDTH_MAXC_P_L 16 /* max. cmds per lun */
|
||||
#define GDTH_MAX_RAW 2 /* max. cmds per raw device */
|
||||
#define MAXOFFSETS 128
|
||||
#define MAXHA 16
|
||||
#define MAXID 127
|
||||
#define MAXLUN 8
|
||||
#define MAXBUS 6
|
||||
#define MAX_EVENTS 100 /* event buffer count */
|
||||
#define MAX_RES_ARGS 40 /* device reservation,
|
||||
must be a multiple of 4 */
|
||||
#define MAXCYLS 1024
|
||||
#define HEADS 64
|
||||
#define SECS 32 /* mapping 64*32 */
|
||||
#define MEDHEADS 127
|
||||
#define MEDSECS 63 /* mapping 127*63 */
|
||||
#define BIGHEADS 255
|
||||
#define BIGSECS 63 /* mapping 255*63 */
|
||||
|
||||
/* special command ptr. */
|
||||
#define UNUSED_CMND ((struct scsi_cmnd *)-1)
|
||||
#define INTERNAL_CMND ((struct scsi_cmnd *)-2)
|
||||
#define SCREEN_CMND ((struct scsi_cmnd *)-3)
|
||||
#define SPECIAL_SCP(p) (p==UNUSED_CMND || p==INTERNAL_CMND || p==SCREEN_CMND)
|
||||
|
||||
/* controller services */
|
||||
#define SCSIRAWSERVICE 3
|
||||
#define CACHESERVICE 9
|
||||
#define SCREENSERVICE 11
|
||||
|
||||
/* screenservice defines */
|
||||
#define MSG_INV_HANDLE -1 /* special message handle */
|
||||
#define MSGLEN 16 /* size of message text */
|
||||
#define MSG_SIZE 34 /* size of message structure */
|
||||
#define MSG_REQUEST 0 /* async. event: message */
|
||||
|
||||
/* DPMEM constants */
|
||||
#define DPMEM_MAGIC 0xC0FFEE11
|
||||
#define IC_HEADER_BYTES 48
|
||||
#define IC_QUEUE_BYTES 4
|
||||
#define DPMEM_COMMAND_OFFSET IC_HEADER_BYTES+IC_QUEUE_BYTES*MAXOFFSETS
|
||||
|
||||
/* cluster_type constants */
|
||||
#define CLUSTER_DRIVE 1
|
||||
#define CLUSTER_MOUNTED 2
|
||||
#define CLUSTER_RESERVED 4
|
||||
#define CLUSTER_RESERVE_STATE (CLUSTER_DRIVE|CLUSTER_MOUNTED|CLUSTER_RESERVED)
|
||||
|
||||
/* commands for all services, cache service */
|
||||
#define GDT_INIT 0 /* service initialization */
|
||||
#define GDT_READ 1 /* read command */
|
||||
#define GDT_WRITE 2 /* write command */
|
||||
#define GDT_INFO 3 /* information about devices */
|
||||
#define GDT_FLUSH 4 /* flush dirty cache buffers */
|
||||
#define GDT_IOCTL 5 /* ioctl command */
|
||||
#define GDT_DEVTYPE 9 /* additional information */
|
||||
#define GDT_MOUNT 10 /* mount cache device */
|
||||
#define GDT_UNMOUNT 11 /* unmount cache device */
|
||||
#define GDT_SET_FEAT 12 /* set feat. (scatter/gather) */
|
||||
#define GDT_GET_FEAT 13 /* get features */
|
||||
#define GDT_WRITE_THR 16 /* write through */
|
||||
#define GDT_READ_THR 17 /* read through */
|
||||
#define GDT_EXT_INFO 18 /* extended info */
|
||||
#define GDT_RESET 19 /* controller reset */
|
||||
#define GDT_RESERVE_DRV 20 /* reserve host drive */
|
||||
#define GDT_RELEASE_DRV 21 /* release host drive */
|
||||
#define GDT_CLUST_INFO 22 /* cluster info */
|
||||
#define GDT_RW_ATTRIBS 23 /* R/W attribs (write thru,..)*/
|
||||
#define GDT_CLUST_RESET 24 /* releases the cluster drives*/
|
||||
#define GDT_FREEZE_IO 25 /* freezes all IOs */
|
||||
#define GDT_UNFREEZE_IO 26 /* unfreezes all IOs */
|
||||
#define GDT_X_INIT_HOST 29 /* ext. init: 64 bit support */
|
||||
#define GDT_X_INFO 30 /* ext. info for drives>2TB */
|
||||
|
||||
/* raw service commands */
|
||||
#define GDT_RESERVE 14 /* reserve dev. to raw serv. */
|
||||
#define GDT_RELEASE 15 /* release device */
|
||||
#define GDT_RESERVE_ALL 16 /* reserve all devices */
|
||||
#define GDT_RELEASE_ALL 17 /* release all devices */
|
||||
#define GDT_RESET_BUS 18 /* reset bus */
|
||||
#define GDT_SCAN_START 19 /* start device scan */
|
||||
#define GDT_SCAN_END 20 /* stop device scan */
|
||||
#define GDT_X_INIT_RAW 21 /* ext. init: 64 bit support */
|
||||
|
||||
/* screen service commands */
|
||||
#define GDT_REALTIME 3 /* realtime clock to screens. */
|
||||
#define GDT_X_INIT_SCR 4 /* ext. init: 64 bit support */
|
||||
|
||||
/* IOCTL command defines */
|
||||
#define SCSI_DR_INFO 0x00 /* SCSI drive info */
|
||||
#define SCSI_CHAN_CNT 0x05 /* SCSI channel count */
|
||||
#define SCSI_DR_LIST 0x06 /* SCSI drive list */
|
||||
#define SCSI_DEF_CNT 0x15 /* grown/primary defects */
|
||||
#define DSK_STATISTICS 0x4b /* SCSI disk statistics */
|
||||
#define IOCHAN_DESC 0x5d /* description of IO channel */
|
||||
#define IOCHAN_RAW_DESC 0x5e /* description of raw IO chn. */
|
||||
#define L_CTRL_PATTERN 0x20000000L /* SCSI IOCTL mask */
|
||||
#define ARRAY_INFO 0x12 /* array drive info */
|
||||
#define ARRAY_DRV_LIST 0x0f /* array drive list */
|
||||
#define ARRAY_DRV_LIST2 0x34 /* array drive list (new) */
|
||||
#define LA_CTRL_PATTERN 0x10000000L /* array IOCTL mask */
|
||||
#define CACHE_DRV_CNT 0x01 /* cache drive count */
|
||||
#define CACHE_DRV_LIST 0x02 /* cache drive list */
|
||||
#define CACHE_INFO 0x04 /* cache info */
|
||||
#define CACHE_CONFIG 0x05 /* cache configuration */
|
||||
#define CACHE_DRV_INFO 0x07 /* cache drive info */
|
||||
#define BOARD_FEATURES 0x15 /* controller features */
|
||||
#define BOARD_INFO 0x28 /* controller info */
|
||||
#define SET_PERF_MODES 0x82 /* set mode (coalescing,..) */
|
||||
#define GET_PERF_MODES 0x83 /* get mode */
|
||||
#define CACHE_READ_OEM_STRING_RECORD 0x84 /* read OEM string record */
|
||||
#define HOST_GET 0x10001L /* get host drive list */
|
||||
#define IO_CHANNEL 0x00020000L /* default IO channel */
|
||||
#define INVALID_CHANNEL 0x0000ffffL /* invalid channel */
|
||||
|
||||
/* service errors */
|
||||
#define S_OK 1 /* no error */
|
||||
#define S_GENERR 6 /* general error */
|
||||
#define S_BSY 7 /* controller busy */
|
||||
#define S_CACHE_UNKNOWN 12 /* cache serv.: drive unknown */
|
||||
#define S_RAW_SCSI 12 /* raw serv.: target error */
|
||||
#define S_RAW_ILL 0xff /* raw serv.: illegal */
|
||||
#define S_NOFUNC -2 /* unknown function */
|
||||
#define S_CACHE_RESERV -24 /* cache: reserv. conflict */
|
||||
|
||||
/* timeout values */
|
||||
#define INIT_RETRIES 100000 /* 100000 * 1ms = 100s */
|
||||
#define INIT_TIMEOUT 100000 /* 100000 * 1ms = 100s */
|
||||
#define POLL_TIMEOUT 10000 /* 10000 * 1ms = 10s */
|
||||
|
||||
/* priorities */
|
||||
#define DEFAULT_PRI 0x20
|
||||
#define IOCTL_PRI 0x10
|
||||
#define HIGH_PRI 0x08
|
||||
|
||||
/* data directions */
|
||||
#define GDTH_DATA_IN 0x01000000L /* data from target */
|
||||
#define GDTH_DATA_OUT 0x00000000L /* data to target */
|
||||
|
||||
/* other defines */
|
||||
#define LINUX_OS 8 /* used for cache optim. */
|
||||
#define SECS32 0x1f /* round capacity */
|
||||
#define BIOS_ID_OFFS 0x10 /* offset contr-ID in ISABIOS */
|
||||
#define LOCALBOARD 0 /* board node always 0 */
|
||||
#define ASYNCINDEX 0 /* cmd index async. event */
|
||||
#define SPEZINDEX 1 /* cmd index unknown service */
|
||||
#define COALINDEX (GDTH_MAXCMDS + 2)
|
||||
|
||||
/* features */
|
||||
#define SCATTER_GATHER 1 /* s/g feature */
|
||||
#define GDT_WR_THROUGH 0x100 /* WRITE_THROUGH supported */
|
||||
#define GDT_64BIT 0x200 /* 64bit / drv>2TB support */
|
||||
|
||||
#include "gdth_ioctl.h"
|
||||
|
||||
/* screenservice message */
|
||||
typedef struct {
|
||||
u32 msg_handle; /* message handle */
|
||||
u32 msg_len; /* size of message */
|
||||
u32 msg_alen; /* answer length */
|
||||
u8 msg_answer; /* answer flag */
|
||||
u8 msg_ext; /* more messages */
|
||||
u8 msg_reserved[2];
|
||||
char msg_text[MSGLEN+2]; /* the message text */
|
||||
} __attribute__((packed)) gdth_msg_str;
|
||||
|
||||
|
||||
/* IOCTL data structures */
|
||||
|
||||
/* Status coalescing buffer for returning multiple requests per interrupt */
|
||||
typedef struct {
|
||||
u32 status;
|
||||
u32 ext_status;
|
||||
u32 info0;
|
||||
u32 info1;
|
||||
} __attribute__((packed)) gdth_coal_status;
|
||||
|
||||
/* performance mode data structure */
|
||||
typedef struct {
|
||||
u32 version; /* The version of this IOCTL structure. */
|
||||
u32 st_mode; /* 0=dis., 1=st_buf_addr1 valid, 2=both */
|
||||
u32 st_buff_addr1; /* physical address of status buffer 1 */
|
||||
u32 st_buff_u_addr1; /* reserved for 64 bit addressing */
|
||||
u32 st_buff_indx1; /* reserved command idx. for this buffer */
|
||||
u32 st_buff_addr2; /* physical address of status buffer 1 */
|
||||
u32 st_buff_u_addr2; /* reserved for 64 bit addressing */
|
||||
u32 st_buff_indx2; /* reserved command idx. for this buffer */
|
||||
u32 st_buff_size; /* size of each buffer in bytes */
|
||||
u32 cmd_mode; /* 0 = mode disabled, 1 = cmd_buff_addr1 */
|
||||
u32 cmd_buff_addr1; /* physical address of cmd buffer 1 */
|
||||
u32 cmd_buff_u_addr1; /* reserved for 64 bit addressing */
|
||||
u32 cmd_buff_indx1; /* cmd buf addr1 unique identifier */
|
||||
u32 cmd_buff_addr2; /* physical address of cmd buffer 1 */
|
||||
u32 cmd_buff_u_addr2; /* reserved for 64 bit addressing */
|
||||
u32 cmd_buff_indx2; /* cmd buf addr1 unique identifier */
|
||||
u32 cmd_buff_size; /* size of each cmd buffer in bytes */
|
||||
u32 reserved1;
|
||||
u32 reserved2;
|
||||
} __attribute__((packed)) gdth_perf_modes;
|
||||
|
||||
/* SCSI drive info */
|
||||
typedef struct {
|
||||
u8 vendor[8]; /* vendor string */
|
||||
u8 product[16]; /* product string */
|
||||
u8 revision[4]; /* revision */
|
||||
u32 sy_rate; /* current rate for sync. tr. */
|
||||
u32 sy_max_rate; /* max. rate for sync. tr. */
|
||||
u32 no_ldrive; /* belongs to this log. drv.*/
|
||||
u32 blkcnt; /* number of blocks */
|
||||
u16 blksize; /* size of block in bytes */
|
||||
u8 available; /* flag: access is available */
|
||||
u8 init; /* medium is initialized */
|
||||
u8 devtype; /* SCSI devicetype */
|
||||
u8 rm_medium; /* medium is removable */
|
||||
u8 wp_medium; /* medium is write protected */
|
||||
u8 ansi; /* SCSI I/II or III? */
|
||||
u8 protocol; /* same as ansi */
|
||||
u8 sync; /* flag: sync. transfer enab. */
|
||||
u8 disc; /* flag: disconnect enabled */
|
||||
u8 queueing; /* flag: command queing enab. */
|
||||
u8 cached; /* flag: caching enabled */
|
||||
u8 target_id; /* target ID of device */
|
||||
u8 lun; /* LUN id of device */
|
||||
u8 orphan; /* flag: drive fragment */
|
||||
u32 last_error; /* sense key or drive state */
|
||||
u32 last_result; /* result of last command */
|
||||
u32 check_errors; /* err. in last surface check */
|
||||
u8 percent; /* progress for surface check */
|
||||
u8 last_check; /* IOCTRL operation */
|
||||
u8 res[2];
|
||||
u32 flags; /* from 1.19/2.19: raw reserv.*/
|
||||
u8 multi_bus; /* multi bus dev? (fibre ch.) */
|
||||
u8 mb_status; /* status: available? */
|
||||
u8 res2[2];
|
||||
u8 mb_alt_status; /* status on second bus */
|
||||
u8 mb_alt_bid; /* number of second bus */
|
||||
u8 mb_alt_tid; /* target id on second bus */
|
||||
u8 res3;
|
||||
u8 fc_flag; /* from 1.22/2.22: info valid?*/
|
||||
u8 res4;
|
||||
u16 fc_frame_size; /* frame size (bytes) */
|
||||
char wwn[8]; /* world wide name */
|
||||
} __attribute__((packed)) gdth_diskinfo_str;
|
||||
|
||||
/* get SCSI channel count */
|
||||
typedef struct {
|
||||
u32 channel_no; /* number of channel */
|
||||
u32 drive_cnt; /* drive count */
|
||||
u8 siop_id; /* SCSI processor ID */
|
||||
u8 siop_state; /* SCSI processor state */
|
||||
} __attribute__((packed)) gdth_getch_str;
|
||||
|
||||
/* get SCSI drive numbers */
|
||||
typedef struct {
|
||||
u32 sc_no; /* SCSI channel */
|
||||
u32 sc_cnt; /* sc_list[] elements */
|
||||
u32 sc_list[MAXID]; /* minor device numbers */
|
||||
} __attribute__((packed)) gdth_drlist_str;
|
||||
|
||||
/* get grown/primary defect count */
|
||||
typedef struct {
|
||||
u8 sddc_type; /* 0x08: grown, 0x10: prim. */
|
||||
u8 sddc_format; /* list entry format */
|
||||
u8 sddc_len; /* list entry length */
|
||||
u8 sddc_res;
|
||||
u32 sddc_cnt; /* entry count */
|
||||
} __attribute__((packed)) gdth_defcnt_str;
|
||||
|
||||
/* disk statistics */
|
||||
typedef struct {
|
||||
u32 bid; /* SCSI channel */
|
||||
u32 first; /* first SCSI disk */
|
||||
u32 entries; /* number of elements */
|
||||
u32 count; /* (R) number of init. el. */
|
||||
u32 mon_time; /* time stamp */
|
||||
struct {
|
||||
u8 tid; /* target ID */
|
||||
u8 lun; /* LUN */
|
||||
u8 res[2];
|
||||
u32 blk_size; /* block size in bytes */
|
||||
u32 rd_count; /* bytes read */
|
||||
u32 wr_count; /* bytes written */
|
||||
u32 rd_blk_count; /* blocks read */
|
||||
u32 wr_blk_count; /* blocks written */
|
||||
u32 retries; /* retries */
|
||||
u32 reassigns; /* reassigns */
|
||||
} __attribute__((packed)) list[1];
|
||||
} __attribute__((packed)) gdth_dskstat_str;
|
||||
|
||||
/* IO channel header */
|
||||
typedef struct {
|
||||
u32 version; /* version (-1UL: newest) */
|
||||
u8 list_entries; /* list entry count */
|
||||
u8 first_chan; /* first channel number */
|
||||
u8 last_chan; /* last channel number */
|
||||
u8 chan_count; /* (R) channel count */
|
||||
u32 list_offset; /* offset of list[0] */
|
||||
} __attribute__((packed)) gdth_iochan_header;
|
||||
|
||||
/* get IO channel description */
|
||||
typedef struct {
|
||||
gdth_iochan_header hdr;
|
||||
struct {
|
||||
u32 address; /* channel address */
|
||||
u8 type; /* type (SCSI, FCAL) */
|
||||
u8 local_no; /* local number */
|
||||
u16 features; /* channel features */
|
||||
} __attribute__((packed)) list[MAXBUS];
|
||||
} __attribute__((packed)) gdth_iochan_str;
|
||||
|
||||
/* get raw IO channel description */
|
||||
typedef struct {
|
||||
gdth_iochan_header hdr;
|
||||
struct {
|
||||
u8 proc_id; /* processor id */
|
||||
u8 proc_defect; /* defect ? */
|
||||
u8 reserved[2];
|
||||
} __attribute__((packed)) list[MAXBUS];
|
||||
} __attribute__((packed)) gdth_raw_iochan_str;
|
||||
|
||||
/* array drive component */
|
||||
typedef struct {
|
||||
u32 al_controller; /* controller ID */
|
||||
u8 al_cache_drive; /* cache drive number */
|
||||
u8 al_status; /* cache drive state */
|
||||
u8 al_res[2];
|
||||
} __attribute__((packed)) gdth_arraycomp_str;
|
||||
|
||||
/* array drive information */
|
||||
typedef struct {
|
||||
u8 ai_type; /* array type (RAID0,4,5) */
|
||||
u8 ai_cache_drive_cnt; /* active cachedrives */
|
||||
u8 ai_state; /* array drive state */
|
||||
u8 ai_master_cd; /* master cachedrive */
|
||||
u32 ai_master_controller; /* ID of master controller */
|
||||
u32 ai_size; /* user capacity [sectors] */
|
||||
u32 ai_striping_size; /* striping size [sectors] */
|
||||
u32 ai_secsize; /* sector size [bytes] */
|
||||
u32 ai_err_info; /* failed cache drive */
|
||||
u8 ai_name[8]; /* name of the array drive */
|
||||
u8 ai_controller_cnt; /* number of controllers */
|
||||
u8 ai_removable; /* flag: removable */
|
||||
u8 ai_write_protected; /* flag: write protected */
|
||||
u8 ai_devtype; /* type: always direct access */
|
||||
gdth_arraycomp_str ai_drives[35]; /* drive components: */
|
||||
u8 ai_drive_entries; /* number of drive components */
|
||||
u8 ai_protected; /* protection flag */
|
||||
u8 ai_verify_state; /* state of a parity verify */
|
||||
u8 ai_ext_state; /* extended array drive state */
|
||||
u8 ai_expand_state; /* array expand state (>=2.18)*/
|
||||
u8 ai_reserved[3];
|
||||
} __attribute__((packed)) gdth_arrayinf_str;
|
||||
|
||||
/* get array drive list */
|
||||
typedef struct {
|
||||
u32 controller_no; /* controller no. */
|
||||
u8 cd_handle; /* master cachedrive */
|
||||
u8 is_arrayd; /* Flag: is array drive? */
|
||||
u8 is_master; /* Flag: is array master? */
|
||||
u8 is_parity; /* Flag: is parity drive? */
|
||||
u8 is_hotfix; /* Flag: is hotfix drive? */
|
||||
u8 res[3];
|
||||
} __attribute__((packed)) gdth_alist_str;
|
||||
|
||||
typedef struct {
|
||||
u32 entries_avail; /* allocated entries */
|
||||
u32 entries_init; /* returned entries */
|
||||
u32 first_entry; /* first entry number */
|
||||
u32 list_offset; /* offset of following list */
|
||||
gdth_alist_str list[1]; /* list */
|
||||
} __attribute__((packed)) gdth_arcdl_str;
|
||||
|
||||
/* cache info/config IOCTL */
|
||||
typedef struct {
|
||||
u32 version; /* firmware version */
|
||||
u16 state; /* cache state (on/off) */
|
||||
u16 strategy; /* cache strategy */
|
||||
u16 write_back; /* write back state (on/off) */
|
||||
u16 block_size; /* cache block size */
|
||||
} __attribute__((packed)) gdth_cpar_str;
|
||||
|
||||
typedef struct {
|
||||
u32 csize; /* cache size */
|
||||
u32 read_cnt; /* read/write counter */
|
||||
u32 write_cnt;
|
||||
u32 tr_hits; /* hits */
|
||||
u32 sec_hits;
|
||||
u32 sec_miss; /* misses */
|
||||
} __attribute__((packed)) gdth_cstat_str;
|
||||
|
||||
typedef struct {
|
||||
gdth_cpar_str cpar;
|
||||
gdth_cstat_str cstat;
|
||||
} __attribute__((packed)) gdth_cinfo_str;
|
||||
|
||||
/* cache drive info */
|
||||
typedef struct {
|
||||
u8 cd_name[8]; /* cache drive name */
|
||||
u32 cd_devtype; /* SCSI devicetype */
|
||||
u32 cd_ldcnt; /* number of log. drives */
|
||||
u32 cd_last_error; /* last error */
|
||||
u8 cd_initialized; /* drive is initialized */
|
||||
u8 cd_removable; /* media is removable */
|
||||
u8 cd_write_protected; /* write protected */
|
||||
u8 cd_flags; /* Pool Hot Fix? */
|
||||
u32 ld_blkcnt; /* number of blocks */
|
||||
u32 ld_blksize; /* blocksize */
|
||||
u32 ld_dcnt; /* number of disks */
|
||||
u32 ld_slave; /* log. drive index */
|
||||
u32 ld_dtype; /* type of logical drive */
|
||||
u32 ld_last_error; /* last error */
|
||||
u8 ld_name[8]; /* log. drive name */
|
||||
u8 ld_error; /* error */
|
||||
} __attribute__((packed)) gdth_cdrinfo_str;
|
||||
|
||||
/* OEM string */
|
||||
typedef struct {
|
||||
u32 ctl_version;
|
||||
u32 file_major_version;
|
||||
u32 file_minor_version;
|
||||
u32 buffer_size;
|
||||
u32 cpy_count;
|
||||
u32 ext_error;
|
||||
u32 oem_id;
|
||||
u32 board_id;
|
||||
} __attribute__((packed)) gdth_oem_str_params;
|
||||
|
||||
typedef struct {
|
||||
u8 product_0_1_name[16];
|
||||
u8 product_4_5_name[16];
|
||||
u8 product_cluster_name[16];
|
||||
u8 product_reserved[16];
|
||||
u8 scsi_cluster_target_vendor_id[16];
|
||||
u8 cluster_raid_fw_name[16];
|
||||
u8 oem_brand_name[16];
|
||||
u8 oem_raid_type[16];
|
||||
u8 bios_type[13];
|
||||
u8 bios_title[50];
|
||||
u8 oem_company_name[37];
|
||||
u32 pci_id_1;
|
||||
u32 pci_id_2;
|
||||
u8 validation_status[80];
|
||||
u8 reserved_1[4];
|
||||
u8 scsi_host_drive_inquiry_vendor_id[16];
|
||||
u8 library_file_template[16];
|
||||
u8 reserved_2[16];
|
||||
u8 tool_name_1[32];
|
||||
u8 tool_name_2[32];
|
||||
u8 tool_name_3[32];
|
||||
u8 oem_contact_1[84];
|
||||
u8 oem_contact_2[84];
|
||||
u8 oem_contact_3[84];
|
||||
} __attribute__((packed)) gdth_oem_str;
|
||||
|
||||
typedef struct {
|
||||
gdth_oem_str_params params;
|
||||
gdth_oem_str text;
|
||||
} __attribute__((packed)) gdth_oem_str_ioctl;
|
||||
|
||||
/* board features */
|
||||
typedef struct {
|
||||
u8 chaining; /* Chaining supported */
|
||||
u8 striping; /* Striping (RAID-0) supp. */
|
||||
u8 mirroring; /* Mirroring (RAID-1) supp. */
|
||||
u8 raid; /* RAID-4/5/10 supported */
|
||||
} __attribute__((packed)) gdth_bfeat_str;
|
||||
|
||||
/* board info IOCTL */
|
||||
typedef struct {
|
||||
u32 ser_no; /* serial no. */
|
||||
u8 oem_id[2]; /* OEM ID */
|
||||
u16 ep_flags; /* eprom flags */
|
||||
u32 proc_id; /* processor ID */
|
||||
u32 memsize; /* memory size (bytes) */
|
||||
u8 mem_banks; /* memory banks */
|
||||
u8 chan_type; /* channel type */
|
||||
u8 chan_count; /* channel count */
|
||||
u8 rdongle_pres; /* dongle present? */
|
||||
u32 epr_fw_ver; /* (eprom) firmware version */
|
||||
u32 upd_fw_ver; /* (update) firmware version */
|
||||
u32 upd_revision; /* update revision */
|
||||
char type_string[16]; /* controller name */
|
||||
char raid_string[16]; /* RAID firmware name */
|
||||
u8 update_pres; /* update present? */
|
||||
u8 xor_pres; /* XOR engine present? */
|
||||
u8 prom_type; /* ROM type (eprom/flash) */
|
||||
u8 prom_count; /* number of ROM devices */
|
||||
u32 dup_pres; /* duplexing module present? */
|
||||
u32 chan_pres; /* number of expansion chn. */
|
||||
u32 mem_pres; /* memory expansion inst. ? */
|
||||
u8 ft_bus_system; /* fault bus supported? */
|
||||
u8 subtype_valid; /* board_subtype valid? */
|
||||
u8 board_subtype; /* subtype/hardware level */
|
||||
u8 ramparity_pres; /* RAM parity check hardware? */
|
||||
} __attribute__((packed)) gdth_binfo_str;
|
||||
|
||||
/* get host drive info */
|
||||
typedef struct {
|
||||
char name[8]; /* host drive name */
|
||||
u32 size; /* size (sectors) */
|
||||
u8 host_drive; /* host drive number */
|
||||
u8 log_drive; /* log. drive (master) */
|
||||
u8 reserved;
|
||||
u8 rw_attribs; /* r/w attribs */
|
||||
u32 start_sec; /* start sector */
|
||||
} __attribute__((packed)) gdth_hentry_str;
|
||||
|
||||
typedef struct {
|
||||
u32 entries; /* entry count */
|
||||
u32 offset; /* offset of entries */
|
||||
u8 secs_p_head; /* sectors/head */
|
||||
u8 heads_p_cyl; /* heads/cylinder */
|
||||
u8 reserved;
|
||||
u8 clust_drvtype; /* cluster drive type */
|
||||
u32 location; /* controller number */
|
||||
gdth_hentry_str entry[MAX_HDRIVES]; /* entries */
|
||||
} __attribute__((packed)) gdth_hget_str;
|
||||
|
||||
|
||||
/* DPRAM structures */
|
||||
|
||||
/* interface area ISA/PCI */
|
||||
typedef struct {
|
||||
u8 S_Cmd_Indx; /* special command */
|
||||
u8 volatile S_Status; /* status special command */
|
||||
u16 reserved1;
|
||||
u32 S_Info[4]; /* add. info special command */
|
||||
u8 volatile Sema0; /* command semaphore */
|
||||
u8 reserved2[3];
|
||||
u8 Cmd_Index; /* command number */
|
||||
u8 reserved3[3];
|
||||
u16 volatile Status; /* command status */
|
||||
u16 Service; /* service(for async.events) */
|
||||
u32 Info[2]; /* additional info */
|
||||
struct {
|
||||
u16 offset; /* command offs. in the DPRAM*/
|
||||
u16 serv_id; /* service */
|
||||
} __attribute__((packed)) comm_queue[MAXOFFSETS]; /* command queue */
|
||||
u32 bios_reserved[2];
|
||||
u8 gdt_dpr_cmd[1]; /* commands */
|
||||
} __attribute__((packed)) gdt_dpr_if;
|
||||
|
||||
/* SRAM structure PCI controllers */
|
||||
typedef struct {
|
||||
u32 magic; /* controller ID from BIOS */
|
||||
u16 need_deinit; /* switch betw. BIOS/driver */
|
||||
u8 switch_support; /* see need_deinit */
|
||||
u8 padding[9];
|
||||
u8 os_used[16]; /* OS code per service */
|
||||
u8 unused[28];
|
||||
u8 fw_magic; /* contr. ID from firmware */
|
||||
} __attribute__((packed)) gdt_pci_sram;
|
||||
|
||||
/* DPRAM ISA controllers */
|
||||
typedef struct {
|
||||
union {
|
||||
struct {
|
||||
u8 bios_used[0x3c00-32]; /* 15KB - 32Bytes BIOS */
|
||||
u16 need_deinit; /* switch betw. BIOS/driver */
|
||||
u8 switch_support; /* see need_deinit */
|
||||
u8 padding[9];
|
||||
u8 os_used[16]; /* OS code per service */
|
||||
} __attribute__((packed)) dp_sram;
|
||||
u8 bios_area[0x4000]; /* 16KB reserved for BIOS */
|
||||
} bu;
|
||||
union {
|
||||
gdt_dpr_if ic; /* interface area */
|
||||
u8 if_area[0x3000]; /* 12KB for interface */
|
||||
} u;
|
||||
struct {
|
||||
u8 memlock; /* write protection DPRAM */
|
||||
u8 event; /* release event */
|
||||
u8 irqen; /* board interrupts enable */
|
||||
u8 irqdel; /* acknowledge board int. */
|
||||
u8 volatile Sema1; /* status semaphore */
|
||||
u8 rq; /* IRQ/DRQ configuration */
|
||||
} __attribute__((packed)) io;
|
||||
} __attribute__((packed)) gdt2_dpram_str;
|
||||
|
||||
/* DPRAM PCI controllers */
|
||||
typedef struct {
|
||||
union {
|
||||
gdt_dpr_if ic; /* interface area */
|
||||
u8 if_area[0xff0-sizeof(gdt_pci_sram)];
|
||||
} u;
|
||||
gdt_pci_sram gdt6sr; /* SRAM structure */
|
||||
struct {
|
||||
u8 unused0[1];
|
||||
u8 volatile Sema1; /* command semaphore */
|
||||
u8 unused1[3];
|
||||
u8 irqen; /* board interrupts enable */
|
||||
u8 unused2[2];
|
||||
u8 event; /* release event */
|
||||
u8 unused3[3];
|
||||
u8 irqdel; /* acknowledge board int. */
|
||||
u8 unused4[3];
|
||||
} __attribute__((packed)) io;
|
||||
} __attribute__((packed)) gdt6_dpram_str;
|
||||
|
||||
/* PLX register structure (new PCI controllers) */
|
||||
typedef struct {
|
||||
u8 cfg_reg; /* DPRAM cfg.(2:below 1MB,0:anywhere)*/
|
||||
u8 unused1[0x3f];
|
||||
u8 volatile sema0_reg; /* command semaphore */
|
||||
u8 volatile sema1_reg; /* status semaphore */
|
||||
u8 unused2[2];
|
||||
u16 volatile status; /* command status */
|
||||
u16 service; /* service */
|
||||
u32 info[2]; /* additional info */
|
||||
u8 unused3[0x10];
|
||||
u8 ldoor_reg; /* PCI to local doorbell */
|
||||
u8 unused4[3];
|
||||
u8 volatile edoor_reg; /* local to PCI doorbell */
|
||||
u8 unused5[3];
|
||||
u8 control0; /* control0 register(unused) */
|
||||
u8 control1; /* board interrupts enable */
|
||||
u8 unused6[0x16];
|
||||
} __attribute__((packed)) gdt6c_plx_regs;
|
||||
|
||||
/* DPRAM new PCI controllers */
|
||||
typedef struct {
|
||||
union {
|
||||
gdt_dpr_if ic; /* interface area */
|
||||
u8 if_area[0x4000-sizeof(gdt_pci_sram)];
|
||||
} u;
|
||||
gdt_pci_sram gdt6sr; /* SRAM structure */
|
||||
} __attribute__((packed)) gdt6c_dpram_str;
|
||||
|
||||
/* i960 register structure (PCI MPR controllers) */
|
||||
typedef struct {
|
||||
u8 unused1[16];
|
||||
u8 volatile sema0_reg; /* command semaphore */
|
||||
u8 unused2;
|
||||
u8 volatile sema1_reg; /* status semaphore */
|
||||
u8 unused3;
|
||||
u16 volatile status; /* command status */
|
||||
u16 service; /* service */
|
||||
u32 info[2]; /* additional info */
|
||||
u8 ldoor_reg; /* PCI to local doorbell */
|
||||
u8 unused4[11];
|
||||
u8 volatile edoor_reg; /* local to PCI doorbell */
|
||||
u8 unused5[7];
|
||||
u8 edoor_en_reg; /* board interrupts enable */
|
||||
u8 unused6[27];
|
||||
u32 unused7[939];
|
||||
u32 severity;
|
||||
char evt_str[256]; /* event string */
|
||||
} __attribute__((packed)) gdt6m_i960_regs;
|
||||
|
||||
/* DPRAM PCI MPR controllers */
|
||||
typedef struct {
|
||||
gdt6m_i960_regs i960r; /* 4KB i960 registers */
|
||||
union {
|
||||
gdt_dpr_if ic; /* interface area */
|
||||
u8 if_area[0x3000-sizeof(gdt_pci_sram)];
|
||||
} u;
|
||||
gdt_pci_sram gdt6sr; /* SRAM structure */
|
||||
} __attribute__((packed)) gdt6m_dpram_str;
|
||||
|
||||
|
||||
/* PCI resources */
|
||||
typedef struct {
|
||||
struct pci_dev *pdev;
|
||||
unsigned long dpmem; /* DPRAM address */
|
||||
unsigned long io; /* IO address */
|
||||
} gdth_pci_str;
|
||||
|
||||
|
||||
/* controller information structure */
|
||||
typedef struct {
|
||||
struct Scsi_Host *shost;
|
||||
struct list_head list;
|
||||
u16 hanum;
|
||||
u16 oem_id; /* OEM */
|
||||
u16 type; /* controller class */
|
||||
u32 stype; /* subtype (PCI: device ID) */
|
||||
u16 fw_vers; /* firmware version */
|
||||
u16 cache_feat; /* feat. cache serv. (s/g,..)*/
|
||||
u16 raw_feat; /* feat. raw service (s/g,..)*/
|
||||
u16 screen_feat; /* feat. raw service (s/g,..)*/
|
||||
void __iomem *brd; /* DPRAM address */
|
||||
u32 brd_phys; /* slot number/BIOS address */
|
||||
gdt6c_plx_regs *plx; /* PLX regs (new PCI contr.) */
|
||||
gdth_cmd_str cmdext;
|
||||
gdth_cmd_str *pccb; /* address command structure */
|
||||
u32 ccb_phys; /* phys. address */
|
||||
#ifdef INT_COAL
|
||||
gdth_coal_status *coal_stat; /* buffer for coalescing int.*/
|
||||
u64 coal_stat_phys; /* phys. address */
|
||||
#endif
|
||||
char *pscratch; /* scratch (DMA) buffer */
|
||||
u64 scratch_phys; /* phys. address */
|
||||
u8 scratch_busy; /* in use? */
|
||||
u8 dma64_support; /* 64-bit DMA supported? */
|
||||
gdth_msg_str *pmsg; /* message buffer */
|
||||
u64 msg_phys; /* phys. address */
|
||||
u8 scan_mode; /* current scan mode */
|
||||
u8 irq; /* IRQ */
|
||||
u8 drq; /* DRQ (ISA controllers) */
|
||||
u16 status; /* command status */
|
||||
u16 service; /* service/firmware ver./.. */
|
||||
u32 info;
|
||||
u32 info2; /* additional info */
|
||||
struct scsi_cmnd *req_first; /* top of request queue */
|
||||
struct {
|
||||
u8 present; /* Flag: host drive present? */
|
||||
u8 is_logdrv; /* Flag: log. drive (master)? */
|
||||
u8 is_arraydrv; /* Flag: array drive? */
|
||||
u8 is_master; /* Flag: array drive master? */
|
||||
u8 is_parity; /* Flag: parity drive? */
|
||||
u8 is_hotfix; /* Flag: hotfix drive? */
|
||||
u8 master_no; /* number of master drive */
|
||||
u8 lock; /* drive locked? (hot plug) */
|
||||
u8 heads; /* mapping */
|
||||
u8 secs;
|
||||
u16 devtype; /* further information */
|
||||
u64 size; /* capacity */
|
||||
u8 ldr_no; /* log. drive no. */
|
||||
u8 rw_attribs; /* r/w attributes */
|
||||
u8 cluster_type; /* cluster properties */
|
||||
u8 media_changed; /* Flag:MOUNT/UNMOUNT occurred */
|
||||
u32 start_sec; /* start sector */
|
||||
} hdr[MAX_LDRIVES]; /* host drives */
|
||||
struct {
|
||||
u8 lock; /* channel locked? (hot plug) */
|
||||
u8 pdev_cnt; /* physical device count */
|
||||
u8 local_no; /* local channel number */
|
||||
u8 io_cnt[MAXID]; /* current IO count */
|
||||
u32 address; /* channel address */
|
||||
u32 id_list[MAXID]; /* IDs of the phys. devices */
|
||||
} raw[MAXBUS]; /* SCSI channels */
|
||||
struct {
|
||||
struct scsi_cmnd *cmnd; /* pending request */
|
||||
u16 service; /* service */
|
||||
} cmd_tab[GDTH_MAXCMDS]; /* table of pend. requests */
|
||||
struct gdth_cmndinfo { /* per-command private info */
|
||||
int index;
|
||||
int internal_command; /* don't call scsi_done */
|
||||
gdth_cmd_str *internal_cmd_str; /* crier for internal messages*/
|
||||
dma_addr_t sense_paddr; /* sense dma-addr */
|
||||
u8 priority;
|
||||
int timeout_count; /* # of timeout calls */
|
||||
volatile int wait_for_completion;
|
||||
u16 status;
|
||||
u32 info;
|
||||
enum dma_data_direction dma_dir;
|
||||
int phase; /* ???? */
|
||||
int OpCode;
|
||||
} cmndinfo[GDTH_MAXCMDS]; /* index==0 is free */
|
||||
u8 bus_cnt; /* SCSI bus count */
|
||||
u8 tid_cnt; /* Target ID count */
|
||||
u8 bus_id[MAXBUS]; /* IOP IDs */
|
||||
u8 virt_bus; /* number of virtual bus */
|
||||
u8 more_proc; /* more /proc info supported */
|
||||
u16 cmd_cnt; /* command count in DPRAM */
|
||||
u16 cmd_len; /* length of actual command */
|
||||
u16 cmd_offs_dpmem; /* actual offset in DPRAM */
|
||||
u16 ic_all_size; /* sizeof DPRAM interf. area */
|
||||
gdth_cpar_str cpar; /* controller cache par. */
|
||||
gdth_bfeat_str bfeat; /* controller features */
|
||||
gdth_binfo_str binfo; /* controller info */
|
||||
gdth_evt_data dvr; /* event structure */
|
||||
spinlock_t smp_lock;
|
||||
struct pci_dev *pdev;
|
||||
char oem_name[8];
|
||||
#ifdef GDTH_DMA_STATISTICS
|
||||
unsigned long dma32_cnt, dma64_cnt; /* statistics: DMA buffer */
|
||||
#endif
|
||||
struct scsi_device *sdev;
|
||||
} gdth_ha_str;
|
||||
|
||||
static inline struct gdth_cmndinfo *gdth_cmnd_priv(struct scsi_cmnd* cmd)
|
||||
{
|
||||
return (struct gdth_cmndinfo *)cmd->host_scribble;
|
||||
}
|
||||
|
||||
/* INQUIRY data format */
|
||||
typedef struct {
|
||||
u8 type_qual;
|
||||
u8 modif_rmb;
|
||||
u8 version;
|
||||
u8 resp_aenc;
|
||||
u8 add_length;
|
||||
u8 reserved1;
|
||||
u8 reserved2;
|
||||
u8 misc;
|
||||
u8 vendor[8];
|
||||
u8 product[16];
|
||||
u8 revision[4];
|
||||
} __attribute__((packed)) gdth_inq_data;
|
||||
|
||||
/* READ_CAPACITY data format */
|
||||
typedef struct {
|
||||
u32 last_block_no;
|
||||
u32 block_length;
|
||||
} __attribute__((packed)) gdth_rdcap_data;
|
||||
|
||||
/* READ_CAPACITY (16) data format */
|
||||
typedef struct {
|
||||
u64 last_block_no;
|
||||
u32 block_length;
|
||||
} __attribute__((packed)) gdth_rdcap16_data;
|
||||
|
||||
/* REQUEST_SENSE data format */
|
||||
typedef struct {
|
||||
u8 errorcode;
|
||||
u8 segno;
|
||||
u8 key;
|
||||
u32 info;
|
||||
u8 add_length;
|
||||
u32 cmd_info;
|
||||
u8 adsc;
|
||||
u8 adsq;
|
||||
u8 fruc;
|
||||
u8 key_spec[3];
|
||||
} __attribute__((packed)) gdth_sense_data;
|
||||
|
||||
/* MODE_SENSE data format */
|
||||
typedef struct {
|
||||
struct {
|
||||
u8 data_length;
|
||||
u8 med_type;
|
||||
u8 dev_par;
|
||||
u8 bd_length;
|
||||
} __attribute__((packed)) hd;
|
||||
struct {
|
||||
u8 dens_code;
|
||||
u8 block_count[3];
|
||||
u8 reserved;
|
||||
u8 block_length[3];
|
||||
} __attribute__((packed)) bd;
|
||||
} __attribute__((packed)) gdth_modep_data;
|
||||
|
||||
/* stack frame */
|
||||
typedef struct {
|
||||
unsigned long b[10]; /* 32/64 bit compiler ! */
|
||||
} __attribute__((packed)) gdth_stackframe;
|
||||
|
||||
|
||||
/* function prototyping */
|
||||
|
||||
int gdth_show_info(struct seq_file *, struct Scsi_Host *);
|
||||
int gdth_set_info(struct Scsi_Host *, char *, int);
|
||||
|
||||
#endif
|
@ -1,251 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _GDTH_IOCTL_H
|
||||
#define _GDTH_IOCTL_H
|
||||
|
||||
/* gdth_ioctl.h
|
||||
* $Id: gdth_ioctl.h,v 1.14 2004/02/19 15:43:15 achim Exp $
|
||||
*/
|
||||
|
||||
/* IOCTLs */
|
||||
#define GDTIOCTL_MASK ('J'<<8)
|
||||
#define GDTIOCTL_GENERAL (GDTIOCTL_MASK | 0) /* general IOCTL */
|
||||
#define GDTIOCTL_DRVERS (GDTIOCTL_MASK | 1) /* get driver version */
|
||||
#define GDTIOCTL_CTRTYPE (GDTIOCTL_MASK | 2) /* get controller type */
|
||||
#define GDTIOCTL_OSVERS (GDTIOCTL_MASK | 3) /* get OS version */
|
||||
#define GDTIOCTL_HDRLIST (GDTIOCTL_MASK | 4) /* get host drive list */
|
||||
#define GDTIOCTL_CTRCNT (GDTIOCTL_MASK | 5) /* get controller count */
|
||||
#define GDTIOCTL_LOCKDRV (GDTIOCTL_MASK | 6) /* lock host drive */
|
||||
#define GDTIOCTL_LOCKCHN (GDTIOCTL_MASK | 7) /* lock channel */
|
||||
#define GDTIOCTL_EVENT (GDTIOCTL_MASK | 8) /* read controller events */
|
||||
#define GDTIOCTL_SCSI (GDTIOCTL_MASK | 9) /* SCSI command */
|
||||
#define GDTIOCTL_RESET_BUS (GDTIOCTL_MASK |10) /* reset SCSI bus */
|
||||
#define GDTIOCTL_RESCAN (GDTIOCTL_MASK |11) /* rescan host drives */
|
||||
#define GDTIOCTL_RESET_DRV (GDTIOCTL_MASK |12) /* reset (remote) drv. res. */
|
||||
|
||||
#define GDTIOCTL_MAGIC 0xaffe0004
|
||||
#define EVENT_SIZE 294
|
||||
#define GDTH_MAXSG 32 /* max. s/g elements */
|
||||
|
||||
#define MAX_LDRIVES 255 /* max. log. drive count */
|
||||
#define MAX_HDRIVES MAX_LDRIVES /* max. host drive count */
|
||||
|
||||
/* scatter/gather element */
|
||||
typedef struct {
|
||||
u32 sg_ptr; /* address */
|
||||
u32 sg_len; /* length */
|
||||
} __attribute__((packed)) gdth_sg_str;
|
||||
|
||||
/* scatter/gather element - 64bit addresses */
|
||||
typedef struct {
|
||||
u64 sg_ptr; /* address */
|
||||
u32 sg_len; /* length */
|
||||
} __attribute__((packed)) gdth_sg64_str;
|
||||
|
||||
/* command structure */
|
||||
typedef struct {
|
||||
u32 BoardNode; /* board node (always 0) */
|
||||
u32 CommandIndex; /* command number */
|
||||
u16 OpCode; /* the command (READ,..) */
|
||||
union {
|
||||
struct {
|
||||
u16 DeviceNo; /* number of cache drive */
|
||||
u32 BlockNo; /* block number */
|
||||
u32 BlockCnt; /* block count */
|
||||
u32 DestAddr; /* dest. addr. (if s/g: -1) */
|
||||
u32 sg_canz; /* s/g element count */
|
||||
gdth_sg_str sg_lst[GDTH_MAXSG]; /* s/g list */
|
||||
} __attribute__((packed)) cache; /* cache service cmd. str. */
|
||||
struct {
|
||||
u16 DeviceNo; /* number of cache drive */
|
||||
u64 BlockNo; /* block number */
|
||||
u32 BlockCnt; /* block count */
|
||||
u64 DestAddr; /* dest. addr. (if s/g: -1) */
|
||||
u32 sg_canz; /* s/g element count */
|
||||
gdth_sg64_str sg_lst[GDTH_MAXSG]; /* s/g list */
|
||||
} __attribute__((packed)) cache64; /* cache service cmd. str. */
|
||||
struct {
|
||||
u16 param_size; /* size of p_param buffer */
|
||||
u32 subfunc; /* IOCTL function */
|
||||
u32 channel; /* device */
|
||||
u64 p_param; /* buffer */
|
||||
} __attribute__((packed)) ioctl; /* IOCTL command structure */
|
||||
struct {
|
||||
u16 reserved;
|
||||
union {
|
||||
struct {
|
||||
u32 msg_handle; /* message handle */
|
||||
u64 msg_addr; /* message buffer address */
|
||||
} __attribute__((packed)) msg;
|
||||
u8 data[12]; /* buffer for rtc data, ... */
|
||||
} su;
|
||||
} __attribute__((packed)) screen; /* screen service cmd. str. */
|
||||
struct {
|
||||
u16 reserved;
|
||||
u32 direction; /* data direction */
|
||||
u32 mdisc_time; /* disc. time (0: no timeout)*/
|
||||
u32 mcon_time; /* connect time(0: no to.) */
|
||||
u32 sdata; /* dest. addr. (if s/g: -1) */
|
||||
u32 sdlen; /* data length (bytes) */
|
||||
u32 clen; /* SCSI cmd. length(6,10,12) */
|
||||
u8 cmd[12]; /* SCSI command */
|
||||
u8 target; /* target ID */
|
||||
u8 lun; /* LUN */
|
||||
u8 bus; /* SCSI bus number */
|
||||
u8 priority; /* only 0 used */
|
||||
u32 sense_len; /* sense data length */
|
||||
u32 sense_data; /* sense data addr. */
|
||||
u32 link_p; /* linked cmds (not supp.) */
|
||||
u32 sg_ranz; /* s/g element count */
|
||||
gdth_sg_str sg_lst[GDTH_MAXSG]; /* s/g list */
|
||||
} __attribute__((packed)) raw; /* raw service cmd. struct. */
|
||||
struct {
|
||||
u16 reserved;
|
||||
u32 direction; /* data direction */
|
||||
u32 mdisc_time; /* disc. time (0: no timeout)*/
|
||||
u32 mcon_time; /* connect time(0: no to.) */
|
||||
u64 sdata; /* dest. addr. (if s/g: -1) */
|
||||
u32 sdlen; /* data length (bytes) */
|
||||
u32 clen; /* SCSI cmd. length(6,..,16) */
|
||||
u8 cmd[16]; /* SCSI command */
|
||||
u8 target; /* target ID */
|
||||
u8 lun; /* LUN */
|
||||
u8 bus; /* SCSI bus number */
|
||||
u8 priority; /* only 0 used */
|
||||
u32 sense_len; /* sense data length */
|
||||
u64 sense_data; /* sense data addr. */
|
||||
u32 sg_ranz; /* s/g element count */
|
||||
gdth_sg64_str sg_lst[GDTH_MAXSG]; /* s/g list */
|
||||
} __attribute__((packed)) raw64; /* raw service cmd. struct. */
|
||||
} u;
|
||||
/* additional variables */
|
||||
u8 Service; /* controller service */
|
||||
u8 reserved;
|
||||
u16 Status; /* command result */
|
||||
u32 Info; /* additional information */
|
||||
void *RequestBuffer; /* request buffer */
|
||||
} __attribute__((packed)) gdth_cmd_str;
|
||||
|
||||
/* controller event structure */
|
||||
#define ES_ASYNC 1
|
||||
#define ES_DRIVER 2
|
||||
#define ES_TEST 3
|
||||
#define ES_SYNC 4
|
||||
typedef struct {
|
||||
u16 size; /* size of structure */
|
||||
union {
|
||||
char stream[16];
|
||||
struct {
|
||||
u16 ionode;
|
||||
u16 service;
|
||||
u32 index;
|
||||
} __attribute__((packed)) driver;
|
||||
struct {
|
||||
u16 ionode;
|
||||
u16 service;
|
||||
u16 status;
|
||||
u32 info;
|
||||
u8 scsi_coord[3];
|
||||
} __attribute__((packed)) async;
|
||||
struct {
|
||||
u16 ionode;
|
||||
u16 service;
|
||||
u16 status;
|
||||
u32 info;
|
||||
u16 hostdrive;
|
||||
u8 scsi_coord[3];
|
||||
u8 sense_key;
|
||||
} __attribute__((packed)) sync;
|
||||
struct {
|
||||
u32 l1, l2, l3, l4;
|
||||
} __attribute__((packed)) test;
|
||||
} eu;
|
||||
u32 severity;
|
||||
u8 event_string[256];
|
||||
} __attribute__((packed)) gdth_evt_data;
|
||||
|
||||
typedef struct {
|
||||
u32 first_stamp;
|
||||
u32 last_stamp;
|
||||
u16 same_count;
|
||||
u16 event_source;
|
||||
u16 event_idx;
|
||||
u8 application;
|
||||
u8 reserved;
|
||||
gdth_evt_data event_data;
|
||||
} __attribute__((packed)) gdth_evt_str;
|
||||
|
||||
/* GDTIOCTL_GENERAL */
|
||||
typedef struct {
|
||||
u16 ionode; /* controller number */
|
||||
u16 timeout; /* timeout */
|
||||
u32 info; /* error info */
|
||||
u16 status; /* status */
|
||||
unsigned long data_len; /* data buffer size */
|
||||
unsigned long sense_len; /* sense buffer size */
|
||||
gdth_cmd_str command; /* command */
|
||||
} gdth_ioctl_general;
|
||||
|
||||
/* GDTIOCTL_LOCKDRV */
|
||||
typedef struct {
|
||||
u16 ionode; /* controller number */
|
||||
u8 lock; /* lock/unlock */
|
||||
u8 drive_cnt; /* drive count */
|
||||
u16 drives[MAX_HDRIVES]; /* drives */
|
||||
} gdth_ioctl_lockdrv;
|
||||
|
||||
/* GDTIOCTL_LOCKCHN */
|
||||
typedef struct {
|
||||
u16 ionode; /* controller number */
|
||||
u8 lock; /* lock/unlock */
|
||||
u8 channel; /* channel */
|
||||
} gdth_ioctl_lockchn;
|
||||
|
||||
/* GDTIOCTL_OSVERS */
|
||||
typedef struct {
|
||||
u8 version; /* OS version */
|
||||
u8 subversion; /* OS subversion */
|
||||
u16 revision; /* revision */
|
||||
} gdth_ioctl_osvers;
|
||||
|
||||
/* GDTIOCTL_CTRTYPE */
|
||||
typedef struct {
|
||||
u16 ionode; /* controller number */
|
||||
u8 type; /* controller type */
|
||||
u16 info; /* slot etc. */
|
||||
u16 oem_id; /* OEM ID */
|
||||
u16 bios_ver; /* not used */
|
||||
u16 access; /* not used */
|
||||
u16 ext_type; /* extended type */
|
||||
u16 device_id; /* device ID */
|
||||
u16 sub_device_id; /* sub device ID */
|
||||
} gdth_ioctl_ctrtype;
|
||||
|
||||
/* GDTIOCTL_EVENT */
|
||||
typedef struct {
|
||||
u16 ionode;
|
||||
int erase; /* erase event? */
|
||||
int handle; /* event handle */
|
||||
gdth_evt_str event;
|
||||
} gdth_ioctl_event;
|
||||
|
||||
/* GDTIOCTL_RESCAN/GDTIOCTL_HDRLIST */
|
||||
typedef struct {
|
||||
u16 ionode; /* controller number */
|
||||
u8 flag; /* add/remove */
|
||||
u16 hdr_no; /* drive no. */
|
||||
struct {
|
||||
u8 bus; /* SCSI bus */
|
||||
u8 target; /* target ID */
|
||||
u8 lun; /* LUN */
|
||||
u8 cluster_type; /* cluster properties */
|
||||
} hdr_list[MAX_HDRIVES]; /* index is host drive number */
|
||||
} gdth_ioctl_rescan;
|
||||
|
||||
/* GDTIOCTL_RESET_BUS/GDTIOCTL_RESET_DRV */
|
||||
typedef struct {
|
||||
u16 ionode; /* controller number */
|
||||
u16 number; /* bus/host drive number */
|
||||
u16 status; /* status */
|
||||
} gdth_ioctl_reset;
|
||||
|
||||
#endif
|
@ -1,586 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* gdth_proc.c
|
||||
* $Id: gdth_proc.c,v 1.43 2006/01/11 16:15:00 achim Exp $
|
||||
*/
|
||||
|
||||
#include <linux/completion.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
int gdth_set_info(struct Scsi_Host *host, char *buffer, int length)
|
||||
{
|
||||
gdth_ha_str *ha = shost_priv(host);
|
||||
int ret_val = -EINVAL;
|
||||
|
||||
TRACE2(("gdth_set_info() ha %d\n",ha->hanum,));
|
||||
|
||||
if (length >= 4) {
|
||||
if (strncmp(buffer,"gdth",4) == 0) {
|
||||
buffer += 5;
|
||||
length -= 5;
|
||||
ret_val = gdth_set_asc_info(host, buffer, length, ha);
|
||||
}
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
static int gdth_set_asc_info(struct Scsi_Host *host, char *buffer,
|
||||
int length, gdth_ha_str *ha)
|
||||
{
|
||||
int orig_length, drive, wb_mode;
|
||||
int i, found;
|
||||
gdth_cmd_str gdtcmd;
|
||||
gdth_cpar_str *pcpar;
|
||||
|
||||
char cmnd[MAX_COMMAND_SIZE];
|
||||
memset(cmnd, 0xff, 12);
|
||||
memset(&gdtcmd, 0, sizeof(gdth_cmd_str));
|
||||
|
||||
TRACE2(("gdth_set_asc_info() ha %d\n",ha->hanum));
|
||||
orig_length = length + 5;
|
||||
drive = -1;
|
||||
wb_mode = 0;
|
||||
found = FALSE;
|
||||
|
||||
if (length >= 5 && strncmp(buffer,"flush",5)==0) {
|
||||
buffer += 6;
|
||||
length -= 6;
|
||||
if (length && *buffer>='0' && *buffer<='9') {
|
||||
drive = (int)(*buffer-'0');
|
||||
++buffer; --length;
|
||||
if (length && *buffer>='0' && *buffer<='9') {
|
||||
drive = drive*10 + (int)(*buffer-'0');
|
||||
++buffer; --length;
|
||||
}
|
||||
printk("GDT: Flushing host drive %d .. ",drive);
|
||||
} else {
|
||||
printk("GDT: Flushing all host drives .. ");
|
||||
}
|
||||
for (i = 0; i < MAX_HDRIVES; ++i) {
|
||||
if (ha->hdr[i].present) {
|
||||
if (drive != -1 && i != drive)
|
||||
continue;
|
||||
found = TRUE;
|
||||
gdtcmd.Service = CACHESERVICE;
|
||||
gdtcmd.OpCode = GDT_FLUSH;
|
||||
if (ha->cache_feat & GDT_64BIT) {
|
||||
gdtcmd.u.cache64.DeviceNo = i;
|
||||
gdtcmd.u.cache64.BlockNo = 1;
|
||||
} else {
|
||||
gdtcmd.u.cache.DeviceNo = i;
|
||||
gdtcmd.u.cache.BlockNo = 1;
|
||||
}
|
||||
|
||||
gdth_execute(host, &gdtcmd, cmnd, 30, NULL);
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
printk("\nNo host drive found !\n");
|
||||
else
|
||||
printk("Done.\n");
|
||||
return(orig_length);
|
||||
}
|
||||
|
||||
if (length >= 7 && strncmp(buffer,"wbp_off",7)==0) {
|
||||
buffer += 8;
|
||||
length -= 8;
|
||||
printk("GDT: Disabling write back permanently .. ");
|
||||
wb_mode = 1;
|
||||
} else if (length >= 6 && strncmp(buffer,"wbp_on",6)==0) {
|
||||
buffer += 7;
|
||||
length -= 7;
|
||||
printk("GDT: Enabling write back permanently .. ");
|
||||
wb_mode = 2;
|
||||
} else if (length >= 6 && strncmp(buffer,"wb_off",6)==0) {
|
||||
buffer += 7;
|
||||
length -= 7;
|
||||
printk("GDT: Disabling write back commands .. ");
|
||||
if (ha->cache_feat & GDT_WR_THROUGH) {
|
||||
gdth_write_through = TRUE;
|
||||
printk("Done.\n");
|
||||
} else {
|
||||
printk("Not supported !\n");
|
||||
}
|
||||
return(orig_length);
|
||||
} else if (length >= 5 && strncmp(buffer,"wb_on",5)==0) {
|
||||
buffer += 6;
|
||||
length -= 6;
|
||||
printk("GDT: Enabling write back commands .. ");
|
||||
gdth_write_through = FALSE;
|
||||
printk("Done.\n");
|
||||
return(orig_length);
|
||||
}
|
||||
|
||||
if (wb_mode) {
|
||||
unsigned long flags;
|
||||
|
||||
BUILD_BUG_ON(sizeof(gdth_cpar_str) > GDTH_SCRATCH);
|
||||
|
||||
spin_lock_irqsave(&ha->smp_lock, flags);
|
||||
if (ha->scratch_busy) {
|
||||
spin_unlock_irqrestore(&ha->smp_lock, flags);
|
||||
return -EBUSY;
|
||||
}
|
||||
ha->scratch_busy = TRUE;
|
||||
spin_unlock_irqrestore(&ha->smp_lock, flags);
|
||||
|
||||
pcpar = (gdth_cpar_str *)ha->pscratch;
|
||||
memcpy( pcpar, &ha->cpar, sizeof(gdth_cpar_str) );
|
||||
gdtcmd.Service = CACHESERVICE;
|
||||
gdtcmd.OpCode = GDT_IOCTL;
|
||||
gdtcmd.u.ioctl.p_param = ha->scratch_phys;
|
||||
gdtcmd.u.ioctl.param_size = sizeof(gdth_cpar_str);
|
||||
gdtcmd.u.ioctl.subfunc = CACHE_CONFIG;
|
||||
gdtcmd.u.ioctl.channel = INVALID_CHANNEL;
|
||||
pcpar->write_back = wb_mode==1 ? 0:1;
|
||||
|
||||
gdth_execute(host, &gdtcmd, cmnd, 30, NULL);
|
||||
|
||||
spin_lock_irqsave(&ha->smp_lock, flags);
|
||||
ha->scratch_busy = FALSE;
|
||||
spin_unlock_irqrestore(&ha->smp_lock, flags);
|
||||
|
||||
printk("Done.\n");
|
||||
return(orig_length);
|
||||
}
|
||||
|
||||
printk("GDT: Unknown command: %s Length: %d\n",buffer,length);
|
||||
return(-EINVAL);
|
||||
}
|
||||
|
||||
int gdth_show_info(struct seq_file *m, struct Scsi_Host *host)
|
||||
{
|
||||
gdth_ha_str *ha = shost_priv(host);
|
||||
int hlen;
|
||||
int id, i, j, k, sec, flag;
|
||||
int no_mdrv = 0, drv_no, is_mirr;
|
||||
u32 cnt;
|
||||
dma_addr_t paddr;
|
||||
int rc = -ENOMEM;
|
||||
|
||||
gdth_cmd_str *gdtcmd;
|
||||
gdth_evt_str *estr;
|
||||
char hrec[277];
|
||||
|
||||
char *buf;
|
||||
gdth_dskstat_str *pds;
|
||||
gdth_diskinfo_str *pdi;
|
||||
gdth_arrayinf_str *pai;
|
||||
gdth_defcnt_str *pdef;
|
||||
gdth_cdrinfo_str *pcdi;
|
||||
gdth_hget_str *phg;
|
||||
char cmnd[MAX_COMMAND_SIZE];
|
||||
|
||||
gdtcmd = kmalloc(sizeof(*gdtcmd), GFP_KERNEL);
|
||||
estr = kmalloc(sizeof(*estr), GFP_KERNEL);
|
||||
if (!gdtcmd || !estr)
|
||||
goto free_fail;
|
||||
|
||||
memset(cmnd, 0xff, 12);
|
||||
memset(gdtcmd, 0, sizeof(gdth_cmd_str));
|
||||
|
||||
TRACE2(("gdth_get_info() ha %d\n",ha->hanum));
|
||||
|
||||
|
||||
/* request is i.e. "cat /proc/scsi/gdth/0" */
|
||||
/* format: %-15s\t%-10s\t%-15s\t%s */
|
||||
/* driver parameters */
|
||||
seq_puts(m, "Driver Parameters:\n");
|
||||
if (reserve_list[0] == 0xff)
|
||||
strcpy(hrec, "--");
|
||||
else {
|
||||
hlen = sprintf(hrec, "%d", reserve_list[0]);
|
||||
for (i = 1; i < MAX_RES_ARGS; i++) {
|
||||
if (reserve_list[i] == 0xff)
|
||||
break;
|
||||
hlen += scnprintf(hrec + hlen, 161 - hlen, ",%d", reserve_list[i]);
|
||||
}
|
||||
}
|
||||
seq_printf(m,
|
||||
" reserve_mode: \t%d \treserve_list: \t%s\n",
|
||||
reserve_mode, hrec);
|
||||
seq_printf(m,
|
||||
" max_ids: \t%-3d \thdr_channel: \t%d\n",
|
||||
max_ids, hdr_channel);
|
||||
|
||||
/* controller information */
|
||||
seq_puts(m, "\nDisk Array Controller Information:\n");
|
||||
seq_printf(m,
|
||||
" Number: \t%d \tName: \t%s\n",
|
||||
ha->hanum, ha->binfo.type_string);
|
||||
|
||||
seq_printf(m,
|
||||
" Driver Ver.: \t%-10s\tFirmware Ver.: \t",
|
||||
GDTH_VERSION_STR);
|
||||
if (ha->more_proc)
|
||||
seq_printf(m, "%d.%02d.%02d-%c%03X\n",
|
||||
(u8)(ha->binfo.upd_fw_ver>>24),
|
||||
(u8)(ha->binfo.upd_fw_ver>>16),
|
||||
(u8)(ha->binfo.upd_fw_ver),
|
||||
ha->bfeat.raid ? 'R':'N',
|
||||
ha->binfo.upd_revision);
|
||||
else
|
||||
seq_printf(m, "%d.%02d\n", (u8)(ha->cpar.version>>8),
|
||||
(u8)(ha->cpar.version));
|
||||
|
||||
if (ha->more_proc)
|
||||
/* more information: 1. about controller */
|
||||
seq_printf(m,
|
||||
" Serial No.: \t0x%8X\tCache RAM size:\t%d KB\n",
|
||||
ha->binfo.ser_no, ha->binfo.memsize / 1024);
|
||||
|
||||
if (ha->more_proc) {
|
||||
size_t size = max_t(size_t, GDTH_SCRATCH, sizeof(gdth_hget_str));
|
||||
|
||||
/* more information: 2. about physical devices */
|
||||
seq_puts(m, "\nPhysical Devices:");
|
||||
flag = FALSE;
|
||||
|
||||
buf = dma_alloc_coherent(&ha->pdev->dev, size, &paddr, GFP_KERNEL);
|
||||
if (!buf)
|
||||
goto stop_output;
|
||||
for (i = 0; i < ha->bus_cnt; ++i) {
|
||||
/* 2.a statistics (and retries/reassigns) */
|
||||
TRACE2(("pdr_statistics() chn %d\n",i));
|
||||
pds = (gdth_dskstat_str *)(buf + GDTH_SCRATCH/4);
|
||||
gdtcmd->Service = CACHESERVICE;
|
||||
gdtcmd->OpCode = GDT_IOCTL;
|
||||
gdtcmd->u.ioctl.p_param = paddr + GDTH_SCRATCH/4;
|
||||
gdtcmd->u.ioctl.param_size = 3*GDTH_SCRATCH/4;
|
||||
gdtcmd->u.ioctl.subfunc = DSK_STATISTICS | L_CTRL_PATTERN;
|
||||
gdtcmd->u.ioctl.channel = ha->raw[i].address | INVALID_CHANNEL;
|
||||
pds->bid = ha->raw[i].local_no;
|
||||
pds->first = 0;
|
||||
pds->entries = ha->raw[i].pdev_cnt;
|
||||
cnt = (3*GDTH_SCRATCH/4 - 5 * sizeof(u32)) /
|
||||
sizeof(pds->list[0]);
|
||||
if (pds->entries > cnt)
|
||||
pds->entries = cnt;
|
||||
|
||||
if (gdth_execute(host, gdtcmd, cmnd, 30, NULL) != S_OK)
|
||||
pds->count = 0;
|
||||
|
||||
/* other IOCTLs must fit into area GDTH_SCRATCH/4 */
|
||||
for (j = 0; j < ha->raw[i].pdev_cnt; ++j) {
|
||||
/* 2.b drive info */
|
||||
TRACE2(("scsi_drv_info() chn %d dev %d\n",
|
||||
i, ha->raw[i].id_list[j]));
|
||||
pdi = (gdth_diskinfo_str *)buf;
|
||||
gdtcmd->Service = CACHESERVICE;
|
||||
gdtcmd->OpCode = GDT_IOCTL;
|
||||
gdtcmd->u.ioctl.p_param = paddr;
|
||||
gdtcmd->u.ioctl.param_size = sizeof(gdth_diskinfo_str);
|
||||
gdtcmd->u.ioctl.subfunc = SCSI_DR_INFO | L_CTRL_PATTERN;
|
||||
gdtcmd->u.ioctl.channel =
|
||||
ha->raw[i].address | ha->raw[i].id_list[j];
|
||||
|
||||
if (gdth_execute(host, gdtcmd, cmnd, 30, NULL) == S_OK) {
|
||||
strncpy(hrec,pdi->vendor,8);
|
||||
strncpy(hrec+8,pdi->product,16);
|
||||
strncpy(hrec+24,pdi->revision,4);
|
||||
hrec[28] = 0;
|
||||
seq_printf(m,
|
||||
"\n Chn/ID/LUN: \t%c/%02d/%d \tName: \t%s\n",
|
||||
'A'+i,pdi->target_id,pdi->lun,hrec);
|
||||
flag = TRUE;
|
||||
pdi->no_ldrive &= 0xffff;
|
||||
if (pdi->no_ldrive == 0xffff)
|
||||
strcpy(hrec,"--");
|
||||
else
|
||||
sprintf(hrec,"%d",pdi->no_ldrive);
|
||||
seq_printf(m,
|
||||
" Capacity [MB]:\t%-6d \tTo Log. Drive: \t%s\n",
|
||||
pdi->blkcnt/(1024*1024/pdi->blksize),
|
||||
hrec);
|
||||
} else {
|
||||
pdi->devtype = 0xff;
|
||||
}
|
||||
|
||||
if (pdi->devtype == 0) {
|
||||
/* search retries/reassigns */
|
||||
for (k = 0; k < pds->count; ++k) {
|
||||
if (pds->list[k].tid == pdi->target_id &&
|
||||
pds->list[k].lun == pdi->lun) {
|
||||
seq_printf(m,
|
||||
" Retries: \t%-6d \tReassigns: \t%d\n",
|
||||
pds->list[k].retries,
|
||||
pds->list[k].reassigns);
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* 2.c grown defects */
|
||||
TRACE2(("scsi_drv_defcnt() chn %d dev %d\n",
|
||||
i, ha->raw[i].id_list[j]));
|
||||
pdef = (gdth_defcnt_str *)buf;
|
||||
gdtcmd->Service = CACHESERVICE;
|
||||
gdtcmd->OpCode = GDT_IOCTL;
|
||||
gdtcmd->u.ioctl.p_param = paddr;
|
||||
gdtcmd->u.ioctl.param_size = sizeof(gdth_defcnt_str);
|
||||
gdtcmd->u.ioctl.subfunc = SCSI_DEF_CNT | L_CTRL_PATTERN;
|
||||
gdtcmd->u.ioctl.channel =
|
||||
ha->raw[i].address | ha->raw[i].id_list[j];
|
||||
pdef->sddc_type = 0x08;
|
||||
|
||||
if (gdth_execute(host, gdtcmd, cmnd, 30, NULL) == S_OK) {
|
||||
seq_printf(m,
|
||||
" Grown Defects:\t%d\n",
|
||||
pdef->sddc_cnt);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!flag)
|
||||
seq_puts(m, "\n --\n");
|
||||
|
||||
/* 3. about logical drives */
|
||||
seq_puts(m, "\nLogical Drives:");
|
||||
flag = FALSE;
|
||||
|
||||
for (i = 0; i < MAX_LDRIVES; ++i) {
|
||||
if (!ha->hdr[i].is_logdrv)
|
||||
continue;
|
||||
drv_no = i;
|
||||
j = k = 0;
|
||||
is_mirr = FALSE;
|
||||
do {
|
||||
/* 3.a log. drive info */
|
||||
TRACE2(("cache_drv_info() drive no %d\n",drv_no));
|
||||
pcdi = (gdth_cdrinfo_str *)buf;
|
||||
gdtcmd->Service = CACHESERVICE;
|
||||
gdtcmd->OpCode = GDT_IOCTL;
|
||||
gdtcmd->u.ioctl.p_param = paddr;
|
||||
gdtcmd->u.ioctl.param_size = sizeof(gdth_cdrinfo_str);
|
||||
gdtcmd->u.ioctl.subfunc = CACHE_DRV_INFO;
|
||||
gdtcmd->u.ioctl.channel = drv_no;
|
||||
if (gdth_execute(host, gdtcmd, cmnd, 30, NULL) != S_OK)
|
||||
break;
|
||||
pcdi->ld_dtype >>= 16;
|
||||
j++;
|
||||
if (pcdi->ld_dtype > 2) {
|
||||
strcpy(hrec, "missing");
|
||||
} else if (pcdi->ld_error & 1) {
|
||||
strcpy(hrec, "fault");
|
||||
} else if (pcdi->ld_error & 2) {
|
||||
strcpy(hrec, "invalid");
|
||||
k++; j--;
|
||||
} else {
|
||||
strcpy(hrec, "ok");
|
||||
}
|
||||
|
||||
if (drv_no == i) {
|
||||
seq_printf(m,
|
||||
"\n Number: \t%-2d \tStatus: \t%s\n",
|
||||
drv_no, hrec);
|
||||
flag = TRUE;
|
||||
no_mdrv = pcdi->cd_ldcnt;
|
||||
if (no_mdrv > 1 || pcdi->ld_slave != -1) {
|
||||
is_mirr = TRUE;
|
||||
strcpy(hrec, "RAID-1");
|
||||
} else if (pcdi->ld_dtype == 0) {
|
||||
strcpy(hrec, "Disk");
|
||||
} else if (pcdi->ld_dtype == 1) {
|
||||
strcpy(hrec, "RAID-0");
|
||||
} else if (pcdi->ld_dtype == 2) {
|
||||
strcpy(hrec, "Chain");
|
||||
} else {
|
||||
strcpy(hrec, "???");
|
||||
}
|
||||
seq_printf(m,
|
||||
" Capacity [MB]:\t%-6d \tType: \t%s\n",
|
||||
pcdi->ld_blkcnt/(1024*1024/pcdi->ld_blksize),
|
||||
hrec);
|
||||
} else {
|
||||
seq_printf(m,
|
||||
" Slave Number: \t%-2d \tStatus: \t%s\n",
|
||||
drv_no & 0x7fff, hrec);
|
||||
}
|
||||
drv_no = pcdi->ld_slave;
|
||||
} while (drv_no != -1);
|
||||
|
||||
if (is_mirr)
|
||||
seq_printf(m,
|
||||
" Missing Drv.: \t%-2d \tInvalid Drv.: \t%d\n",
|
||||
no_mdrv - j - k, k);
|
||||
|
||||
if (!ha->hdr[i].is_arraydrv)
|
||||
strcpy(hrec, "--");
|
||||
else
|
||||
sprintf(hrec, "%d", ha->hdr[i].master_no);
|
||||
seq_printf(m,
|
||||
" To Array Drv.:\t%s\n", hrec);
|
||||
}
|
||||
|
||||
if (!flag)
|
||||
seq_puts(m, "\n --\n");
|
||||
|
||||
/* 4. about array drives */
|
||||
seq_puts(m, "\nArray Drives:");
|
||||
flag = FALSE;
|
||||
|
||||
for (i = 0; i < MAX_LDRIVES; ++i) {
|
||||
if (!(ha->hdr[i].is_arraydrv && ha->hdr[i].is_master))
|
||||
continue;
|
||||
/* 4.a array drive info */
|
||||
TRACE2(("array_info() drive no %d\n",i));
|
||||
pai = (gdth_arrayinf_str *)buf;
|
||||
gdtcmd->Service = CACHESERVICE;
|
||||
gdtcmd->OpCode = GDT_IOCTL;
|
||||
gdtcmd->u.ioctl.p_param = paddr;
|
||||
gdtcmd->u.ioctl.param_size = sizeof(gdth_arrayinf_str);
|
||||
gdtcmd->u.ioctl.subfunc = ARRAY_INFO | LA_CTRL_PATTERN;
|
||||
gdtcmd->u.ioctl.channel = i;
|
||||
if (gdth_execute(host, gdtcmd, cmnd, 30, NULL) == S_OK) {
|
||||
if (pai->ai_state == 0)
|
||||
strcpy(hrec, "idle");
|
||||
else if (pai->ai_state == 2)
|
||||
strcpy(hrec, "build");
|
||||
else if (pai->ai_state == 4)
|
||||
strcpy(hrec, "ready");
|
||||
else if (pai->ai_state == 6)
|
||||
strcpy(hrec, "fail");
|
||||
else if (pai->ai_state == 8 || pai->ai_state == 10)
|
||||
strcpy(hrec, "rebuild");
|
||||
else
|
||||
strcpy(hrec, "error");
|
||||
if (pai->ai_ext_state & 0x10)
|
||||
strcat(hrec, "/expand");
|
||||
else if (pai->ai_ext_state & 0x1)
|
||||
strcat(hrec, "/patch");
|
||||
seq_printf(m,
|
||||
"\n Number: \t%-2d \tStatus: \t%s\n",
|
||||
i,hrec);
|
||||
flag = TRUE;
|
||||
|
||||
if (pai->ai_type == 0)
|
||||
strcpy(hrec, "RAID-0");
|
||||
else if (pai->ai_type == 4)
|
||||
strcpy(hrec, "RAID-4");
|
||||
else if (pai->ai_type == 5)
|
||||
strcpy(hrec, "RAID-5");
|
||||
else
|
||||
strcpy(hrec, "RAID-10");
|
||||
seq_printf(m,
|
||||
" Capacity [MB]:\t%-6d \tType: \t%s\n",
|
||||
pai->ai_size/(1024*1024/pai->ai_secsize),
|
||||
hrec);
|
||||
}
|
||||
}
|
||||
|
||||
if (!flag)
|
||||
seq_puts(m, "\n --\n");
|
||||
|
||||
/* 5. about host drives */
|
||||
seq_puts(m, "\nHost Drives:");
|
||||
flag = FALSE;
|
||||
|
||||
for (i = 0; i < MAX_LDRIVES; ++i) {
|
||||
if (!ha->hdr[i].is_logdrv ||
|
||||
(ha->hdr[i].is_arraydrv && !ha->hdr[i].is_master))
|
||||
continue;
|
||||
/* 5.a get host drive list */
|
||||
TRACE2(("host_get() drv_no %d\n",i));
|
||||
phg = (gdth_hget_str *)buf;
|
||||
gdtcmd->Service = CACHESERVICE;
|
||||
gdtcmd->OpCode = GDT_IOCTL;
|
||||
gdtcmd->u.ioctl.p_param = paddr;
|
||||
gdtcmd->u.ioctl.param_size = sizeof(gdth_hget_str);
|
||||
gdtcmd->u.ioctl.subfunc = HOST_GET | LA_CTRL_PATTERN;
|
||||
gdtcmd->u.ioctl.channel = i;
|
||||
phg->entries = MAX_HDRIVES;
|
||||
phg->offset = GDTOFFSOF(gdth_hget_str, entry[0]);
|
||||
if (gdth_execute(host, gdtcmd, cmnd, 30, NULL) == S_OK) {
|
||||
ha->hdr[i].ldr_no = i;
|
||||
ha->hdr[i].rw_attribs = 0;
|
||||
ha->hdr[i].start_sec = 0;
|
||||
} else {
|
||||
for (j = 0; j < phg->entries; ++j) {
|
||||
k = phg->entry[j].host_drive;
|
||||
if (k >= MAX_LDRIVES)
|
||||
continue;
|
||||
ha->hdr[k].ldr_no = phg->entry[j].log_drive;
|
||||
ha->hdr[k].rw_attribs = phg->entry[j].rw_attribs;
|
||||
ha->hdr[k].start_sec = phg->entry[j].start_sec;
|
||||
}
|
||||
}
|
||||
}
|
||||
dma_free_coherent(&ha->pdev->dev, size, buf, paddr);
|
||||
|
||||
for (i = 0; i < MAX_HDRIVES; ++i) {
|
||||
if (!(ha->hdr[i].present))
|
||||
continue;
|
||||
|
||||
seq_printf(m,
|
||||
"\n Number: \t%-2d \tArr/Log. Drive:\t%d\n",
|
||||
i, ha->hdr[i].ldr_no);
|
||||
flag = TRUE;
|
||||
|
||||
seq_printf(m,
|
||||
" Capacity [MB]:\t%-6d \tStart Sector: \t%d\n",
|
||||
(u32)(ha->hdr[i].size/2048), ha->hdr[i].start_sec);
|
||||
}
|
||||
|
||||
if (!flag)
|
||||
seq_puts(m, "\n --\n");
|
||||
}
|
||||
|
||||
/* controller events */
|
||||
seq_puts(m, "\nController Events:\n");
|
||||
|
||||
for (id = -1;;) {
|
||||
id = gdth_read_event(ha, id, estr);
|
||||
if (estr->event_source == 0)
|
||||
break;
|
||||
if (estr->event_data.eu.driver.ionode == ha->hanum &&
|
||||
estr->event_source == ES_ASYNC) {
|
||||
gdth_log_event(&estr->event_data, hrec);
|
||||
|
||||
/*
|
||||
* Elapsed seconds subtraction with unsigned operands is
|
||||
* safe from wrap around in year 2106. Executes as:
|
||||
* operand a + (2's complement operand b) + 1
|
||||
*/
|
||||
|
||||
sec = (int)((u32)ktime_get_real_seconds() - estr->first_stamp);
|
||||
if (sec < 0) sec = 0;
|
||||
seq_printf(m," date- %02d:%02d:%02d\t%s\n",
|
||||
sec/3600, sec%3600/60, sec%60, hrec);
|
||||
}
|
||||
if (id == -1)
|
||||
break;
|
||||
}
|
||||
stop_output:
|
||||
rc = 0;
|
||||
free_fail:
|
||||
kfree(gdtcmd);
|
||||
kfree(estr);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void gdth_wait_completion(gdth_ha_str *ha, int busnum, int id)
|
||||
{
|
||||
unsigned long flags;
|
||||
int i;
|
||||
struct scsi_cmnd *scp;
|
||||
struct gdth_cmndinfo *cmndinfo;
|
||||
u8 b, t;
|
||||
|
||||
spin_lock_irqsave(&ha->smp_lock, flags);
|
||||
|
||||
for (i = 0; i < GDTH_MAXCMDS; ++i) {
|
||||
scp = ha->cmd_tab[i].cmnd;
|
||||
cmndinfo = gdth_cmnd_priv(scp);
|
||||
|
||||
b = scp->device->channel;
|
||||
t = scp->device->id;
|
||||
if (!SPECIAL_SCP(scp) && t == (u8)id &&
|
||||
b == (u8)busnum) {
|
||||
cmndinfo->wait_for_completion = 0;
|
||||
spin_unlock_irqrestore(&ha->smp_lock, flags);
|
||||
while (!cmndinfo->wait_for_completion)
|
||||
barrier();
|
||||
spin_lock_irqsave(&ha->smp_lock, flags);
|
||||
}
|
||||
}
|
||||
spin_unlock_irqrestore(&ha->smp_lock, flags);
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _GDTH_PROC_H
|
||||
#define _GDTH_PROC_H
|
||||
|
||||
/* gdth_proc.h
|
||||
* $Id: gdth_proc.h,v 1.16 2004/01/14 13:09:01 achim Exp $
|
||||
*/
|
||||
|
||||
int gdth_execute(struct Scsi_Host *shost, gdth_cmd_str *gdtcmd, char *cmnd,
|
||||
int timeout, u32 *info);
|
||||
|
||||
static int gdth_set_asc_info(struct Scsi_Host *host, char *buffer,
|
||||
int length, gdth_ha_str *ha);
|
||||
|
||||
static void gdth_wait_completion(gdth_ha_str *ha, int busnum, int id);
|
||||
|
||||
#endif
|
||||
|
@ -18,3 +18,9 @@ config SCSI_HISI_SAS_PCI
|
||||
depends on ACPI
|
||||
help
|
||||
This driver supports HiSilicon's SAS HBA based on PCI device
|
||||
|
||||
config SCSI_HISI_SAS_DEBUGFS_DEFAULT_ENABLE
|
||||
bool "HiSilicon SAS debugging default enable"
|
||||
depends on SCSI_HISI_SAS
|
||||
help
|
||||
Set Y to default enable DEBUGFS for SCSI_HISI_SAS
|
||||
|
@ -44,6 +44,7 @@
|
||||
|
||||
#define HISI_SAS_IOST_ITCT_CACHE_NUM 64
|
||||
#define HISI_SAS_IOST_ITCT_CACHE_DW_SZ 10
|
||||
#define HISI_SAS_FIFO_DATA_DW_SIZE 32
|
||||
|
||||
#define HISI_SAS_STATUS_BUF_SZ (sizeof(struct hisi_sas_status_buffer))
|
||||
#define HISI_SAS_COMMAND_TABLE_SZ (sizeof(union hisi_sas_command_table))
|
||||
@ -154,6 +155,16 @@ enum hisi_sas_phy_event {
|
||||
HISI_PHYES_NUM,
|
||||
};
|
||||
|
||||
struct hisi_sas_debugfs_fifo {
|
||||
u32 signal_sel;
|
||||
u32 dump_msk;
|
||||
u32 dump_mode;
|
||||
u32 trigger;
|
||||
u32 trigger_msk;
|
||||
u32 trigger_mode;
|
||||
u32 rd_data[HISI_SAS_FIFO_DATA_DW_SIZE];
|
||||
};
|
||||
|
||||
struct hisi_sas_phy {
|
||||
struct work_struct works[HISI_PHYES_NUM];
|
||||
struct hisi_hba *hisi_hba;
|
||||
@ -175,6 +186,9 @@ struct hisi_sas_phy {
|
||||
enum sas_linkrate maximum_linkrate;
|
||||
int enable;
|
||||
atomic_t down_cnt;
|
||||
|
||||
/* Trace FIFO */
|
||||
struct hisi_sas_debugfs_fifo fifo;
|
||||
};
|
||||
|
||||
struct hisi_sas_port {
|
||||
@ -474,6 +488,7 @@ struct hisi_hba {
|
||||
struct dentry *debugfs_dir;
|
||||
struct dentry *debugfs_dump_dentry;
|
||||
struct dentry *debugfs_bist_dentry;
|
||||
struct dentry *debugfs_fifo_dentry;
|
||||
};
|
||||
|
||||
/* Generic HW DMA host memory structures */
|
||||
@ -637,7 +652,8 @@ extern void hisi_sas_scan_start(struct Scsi_Host *shost);
|
||||
extern int hisi_sas_host_reset(struct Scsi_Host *shost, int reset_type);
|
||||
extern void hisi_sas_phy_enable(struct hisi_hba *hisi_hba, int phy_no,
|
||||
int enable);
|
||||
extern void hisi_sas_phy_down(struct hisi_hba *hisi_hba, int phy_no, int rdy);
|
||||
extern void hisi_sas_phy_down(struct hisi_hba *hisi_hba, int phy_no, int rdy,
|
||||
gfp_t gfp_flags);
|
||||
extern void hisi_sas_slot_task_free(struct hisi_hba *hisi_hba,
|
||||
struct sas_task *task,
|
||||
struct hisi_sas_slot *slot);
|
||||
|
@ -445,21 +445,19 @@ static int hisi_sas_task_prep(struct sas_task *task,
|
||||
}
|
||||
}
|
||||
|
||||
if (scmd && hisi_hba->shost->nr_hw_queues) {
|
||||
if (scmd) {
|
||||
unsigned int dq_index;
|
||||
u32 blk_tag;
|
||||
|
||||
blk_tag = blk_mq_unique_tag(scmd->request);
|
||||
dq_index = blk_mq_unique_tag_to_hwq(blk_tag);
|
||||
*dq_pointer = dq = &hisi_hba->dq[dq_index];
|
||||
} else if (hisi_hba->shost->nr_hw_queues) {
|
||||
} else {
|
||||
struct Scsi_Host *shost = hisi_hba->shost;
|
||||
struct blk_mq_queue_map *qmap = &shost->tag_set.map[HCTX_TYPE_DEFAULT];
|
||||
int queue = qmap->mq_map[raw_smp_processor_id()];
|
||||
|
||||
*dq_pointer = dq = &hisi_hba->dq[queue];
|
||||
} else {
|
||||
*dq_pointer = dq = sas_dev->dq;
|
||||
}
|
||||
|
||||
port = to_hisi_sas_port(sas_port);
|
||||
@ -612,11 +610,11 @@ static int hisi_sas_task_exec(struct sas_task *task, gfp_t gfp_flags,
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void hisi_sas_bytes_dmaed(struct hisi_hba *hisi_hba, int phy_no)
|
||||
static void hisi_sas_bytes_dmaed(struct hisi_hba *hisi_hba, int phy_no,
|
||||
gfp_t gfp_flags)
|
||||
{
|
||||
struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no];
|
||||
struct asd_sas_phy *sas_phy = &phy->sas_phy;
|
||||
struct sas_ha_struct *sas_ha;
|
||||
|
||||
if (!phy->phy_attached)
|
||||
return;
|
||||
@ -627,8 +625,7 @@ static void hisi_sas_bytes_dmaed(struct hisi_hba *hisi_hba, int phy_no)
|
||||
return;
|
||||
}
|
||||
|
||||
sas_ha = &hisi_hba->sha;
|
||||
sas_ha->notify_phy_event(sas_phy, PHYE_OOB_DONE);
|
||||
sas_notify_phy_event(sas_phy, PHYE_OOB_DONE, gfp_flags);
|
||||
|
||||
if (sas_phy->phy) {
|
||||
struct sas_phy *sphy = sas_phy->phy;
|
||||
@ -656,7 +653,7 @@ static void hisi_sas_bytes_dmaed(struct hisi_hba *hisi_hba, int phy_no)
|
||||
}
|
||||
|
||||
sas_phy->frame_rcvd_size = phy->frame_rcvd_size;
|
||||
sas_ha->notify_port_event(sas_phy, PORTE_BYTES_DMAED);
|
||||
sas_notify_port_event(sas_phy, PORTE_BYTES_DMAED, gfp_flags);
|
||||
}
|
||||
|
||||
static struct hisi_sas_device *hisi_sas_alloc_dev(struct domain_device *device)
|
||||
@ -862,7 +859,7 @@ static void hisi_sas_phyup_work(struct work_struct *work)
|
||||
|
||||
if (phy->identify.target_port_protocols == SAS_PROTOCOL_SSP)
|
||||
hisi_hba->hw->sl_notify_ssp(hisi_hba, phy_no);
|
||||
hisi_sas_bytes_dmaed(hisi_hba, phy_no);
|
||||
hisi_sas_bytes_dmaed(hisi_hba, phy_no, GFP_KERNEL);
|
||||
}
|
||||
|
||||
static void hisi_sas_linkreset_work(struct work_struct *work)
|
||||
@ -1411,7 +1408,6 @@ static void hisi_sas_refresh_port_id(struct hisi_hba *hisi_hba)
|
||||
|
||||
static void hisi_sas_rescan_topology(struct hisi_hba *hisi_hba, u32 state)
|
||||
{
|
||||
struct sas_ha_struct *sas_ha = &hisi_hba->sha;
|
||||
struct asd_sas_port *_sas_port = NULL;
|
||||
int phy_no;
|
||||
|
||||
@ -1432,11 +1428,12 @@ static void hisi_sas_rescan_topology(struct hisi_hba *hisi_hba, u32 state)
|
||||
_sas_port = sas_port;
|
||||
|
||||
if (dev_is_expander(dev->dev_type))
|
||||
sas_ha->notify_port_event(sas_phy,
|
||||
PORTE_BROADCAST_RCVD);
|
||||
sas_notify_port_event(sas_phy,
|
||||
PORTE_BROADCAST_RCVD,
|
||||
GFP_KERNEL);
|
||||
}
|
||||
} else {
|
||||
hisi_sas_phy_down(hisi_hba, phy_no, 0);
|
||||
hisi_sas_phy_down(hisi_hba, phy_no, 0, GFP_KERNEL);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1790,7 +1787,7 @@ static int hisi_sas_debug_I_T_nexus_reset(struct domain_device *device)
|
||||
|
||||
/* report PHY down if timed out */
|
||||
if (!ret)
|
||||
hisi_sas_phy_down(hisi_hba, sas_phy->id, 0);
|
||||
hisi_sas_phy_down(hisi_hba, sas_phy->id, 0, GFP_KERNEL);
|
||||
} else if (sas_dev->dev_status != HISI_SAS_DEV_INIT) {
|
||||
/*
|
||||
* If in init state, we rely on caller to wait for link to be
|
||||
@ -2190,16 +2187,16 @@ static void hisi_sas_phy_disconnected(struct hisi_sas_phy *phy)
|
||||
spin_unlock_irqrestore(&phy->lock, flags);
|
||||
}
|
||||
|
||||
void hisi_sas_phy_down(struct hisi_hba *hisi_hba, int phy_no, int rdy)
|
||||
void hisi_sas_phy_down(struct hisi_hba *hisi_hba, int phy_no, int rdy,
|
||||
gfp_t gfp_flags)
|
||||
{
|
||||
struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no];
|
||||
struct asd_sas_phy *sas_phy = &phy->sas_phy;
|
||||
struct sas_ha_struct *sas_ha = &hisi_hba->sha;
|
||||
struct device *dev = hisi_hba->dev;
|
||||
|
||||
if (rdy) {
|
||||
/* Phy down but ready */
|
||||
hisi_sas_bytes_dmaed(hisi_hba, phy_no);
|
||||
hisi_sas_bytes_dmaed(hisi_hba, phy_no, gfp_flags);
|
||||
hisi_sas_port_notify_formed(sas_phy);
|
||||
} else {
|
||||
struct hisi_sas_port *port = phy->port;
|
||||
@ -2210,7 +2207,7 @@ void hisi_sas_phy_down(struct hisi_hba *hisi_hba, int phy_no, int rdy)
|
||||
return;
|
||||
}
|
||||
/* Phy down and not ready */
|
||||
sas_ha->notify_phy_event(sas_phy, PHYE_LOSS_OF_SIGNAL);
|
||||
sas_notify_phy_event(sas_phy, PHYE_LOSS_OF_SIGNAL, gfp_flags);
|
||||
sas_phy_disconnected(sas_phy);
|
||||
|
||||
if (port) {
|
||||
@ -2725,12 +2722,21 @@ int hisi_sas_remove(struct platform_device *pdev)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hisi_sas_remove);
|
||||
|
||||
#if IS_ENABLED(CONFIG_SCSI_HISI_SAS_DEBUGFS_DEFAULT_ENABLE)
|
||||
#define DEBUGFS_ENABLE_DEFAULT "enabled"
|
||||
bool hisi_sas_debugfs_enable = true;
|
||||
u32 hisi_sas_debugfs_dump_count = 50;
|
||||
#else
|
||||
#define DEBUGFS_ENABLE_DEFAULT "disabled"
|
||||
bool hisi_sas_debugfs_enable;
|
||||
u32 hisi_sas_debugfs_dump_count = 1;
|
||||
#endif
|
||||
|
||||
EXPORT_SYMBOL_GPL(hisi_sas_debugfs_enable);
|
||||
module_param_named(debugfs_enable, hisi_sas_debugfs_enable, bool, 0444);
|
||||
MODULE_PARM_DESC(hisi_sas_debugfs_enable, "Enable driver debugfs (default disabled)");
|
||||
MODULE_PARM_DESC(hisi_sas_debugfs_enable,
|
||||
"Enable driver debugfs (default "DEBUGFS_ENABLE_DEFAULT")");
|
||||
|
||||
u32 hisi_sas_debugfs_dump_count = 1;
|
||||
EXPORT_SYMBOL_GPL(hisi_sas_debugfs_dump_count);
|
||||
module_param_named(debugfs_dump_count, hisi_sas_debugfs_dump_count, uint, 0444);
|
||||
MODULE_PARM_DESC(hisi_sas_debugfs_dump_count, "Number of debugfs dumps to allow");
|
||||
|
@ -1408,7 +1408,6 @@ static irqreturn_t int_bcast_v1_hw(int irq, void *p)
|
||||
struct hisi_sas_phy *phy = p;
|
||||
struct hisi_hba *hisi_hba = phy->hisi_hba;
|
||||
struct asd_sas_phy *sas_phy = &phy->sas_phy;
|
||||
struct sas_ha_struct *sha = &hisi_hba->sha;
|
||||
struct device *dev = hisi_hba->dev;
|
||||
int phy_no = sas_phy->id;
|
||||
u32 irq_value;
|
||||
@ -1424,7 +1423,8 @@ static irqreturn_t int_bcast_v1_hw(int irq, void *p)
|
||||
}
|
||||
|
||||
if (!test_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags))
|
||||
sha->notify_port_event(sas_phy, PORTE_BROADCAST_RCVD);
|
||||
sas_notify_port_event(sas_phy, PORTE_BROADCAST_RCVD,
|
||||
GFP_ATOMIC);
|
||||
|
||||
end:
|
||||
hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT2,
|
||||
@ -1453,7 +1453,8 @@ static irqreturn_t int_abnormal_v1_hw(int irq, void *p)
|
||||
u32 phy_state = hisi_sas_read32(hisi_hba, PHY_STATE);
|
||||
|
||||
hisi_sas_phy_down(hisi_hba, phy_no,
|
||||
(phy_state & 1 << phy_no) ? 1 : 0);
|
||||
(phy_state & 1 << phy_no) ? 1 : 0,
|
||||
GFP_ATOMIC);
|
||||
}
|
||||
|
||||
if (irq_value & CHL_INT0_ID_TIMEOUT_MSK)
|
||||
|
@ -2734,7 +2734,8 @@ static int phy_down_v2_hw(int phy_no, struct hisi_hba *hisi_hba)
|
||||
|
||||
phy_state = hisi_sas_read32(hisi_hba, PHY_STATE);
|
||||
dev_info(dev, "phydown: phy%d phy_state=0x%x\n", phy_no, phy_state);
|
||||
hisi_sas_phy_down(hisi_hba, phy_no, (phy_state & 1 << phy_no) ? 1 : 0);
|
||||
hisi_sas_phy_down(hisi_hba, phy_no, (phy_state & 1 << phy_no) ? 1 : 0,
|
||||
GFP_ATOMIC);
|
||||
|
||||
sl_ctrl = hisi_sas_phy_read32(hisi_hba, phy_no, SL_CONTROL);
|
||||
hisi_sas_phy_write32(hisi_hba, phy_no, SL_CONTROL,
|
||||
@ -2818,14 +2819,14 @@ static void phy_bcast_v2_hw(int phy_no, struct hisi_hba *hisi_hba)
|
||||
{
|
||||
struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no];
|
||||
struct asd_sas_phy *sas_phy = &phy->sas_phy;
|
||||
struct sas_ha_struct *sas_ha = &hisi_hba->sha;
|
||||
u32 bcast_status;
|
||||
|
||||
hisi_sas_phy_write32(hisi_hba, phy_no, SL_RX_BCAST_CHK_MSK, 1);
|
||||
bcast_status = hisi_sas_phy_read32(hisi_hba, phy_no, RX_PRIMS_STATUS);
|
||||
if ((bcast_status & RX_BCAST_CHG_MSK) &&
|
||||
!test_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags))
|
||||
sas_ha->notify_port_event(sas_phy, PORTE_BROADCAST_RCVD);
|
||||
sas_notify_port_event(sas_phy, PORTE_BROADCAST_RCVD,
|
||||
GFP_ATOMIC);
|
||||
hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT0,
|
||||
CHL_INT0_SL_RX_BCST_ACK_MSK);
|
||||
hisi_sas_phy_write32(hisi_hba, phy_no, SL_RX_BCAST_CHK_MSK, 0);
|
||||
@ -3626,18 +3627,6 @@ static const struct hisi_sas_hw hisi_sas_v2_hw = {
|
||||
|
||||
static int hisi_sas_v2_probe(struct platform_device *pdev)
|
||||
{
|
||||
/*
|
||||
* Check if we should defer the probe before we probe the
|
||||
* upper layer, as it's hard to defer later on.
|
||||
*/
|
||||
int ret = platform_get_irq(pdev, 0);
|
||||
|
||||
if (ret < 0) {
|
||||
if (ret != -EPROBE_DEFER)
|
||||
dev_err(&pdev->dev, "cannot obtain irq\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return hisi_sas_probe(pdev, &hisi_sas_v2_hw);
|
||||
}
|
||||
|
||||
|
@ -303,6 +303,19 @@
|
||||
#define ERR_CNT_INVLD_DW (PORT_BASE + 0x390)
|
||||
#define ERR_CNT_CODE_ERR (PORT_BASE + 0x394)
|
||||
#define ERR_CNT_DISP_ERR (PORT_BASE + 0x398)
|
||||
#define DFX_FIFO_CTRL (PORT_BASE + 0x3a0)
|
||||
#define DFX_FIFO_CTRL_TRIGGER_MODE_OFF 0
|
||||
#define DFX_FIFO_CTRL_TRIGGER_MODE_MSK (0x7 << DFX_FIFO_CTRL_TRIGGER_MODE_OFF)
|
||||
#define DFX_FIFO_CTRL_DUMP_MODE_OFF 3
|
||||
#define DFX_FIFO_CTRL_DUMP_MODE_MSK (0x7 << DFX_FIFO_CTRL_DUMP_MODE_OFF)
|
||||
#define DFX_FIFO_CTRL_SIGNAL_SEL_OFF 6
|
||||
#define DFX_FIFO_CTRL_SIGNAL_SEL_MSK (0xF << DFX_FIFO_CTRL_SIGNAL_SEL_OFF)
|
||||
#define DFX_FIFO_CTRL_DUMP_DISABLE_OFF 10
|
||||
#define DFX_FIFO_CTRL_DUMP_DISABLE_MSK (0x1 << DFX_FIFO_CTRL_DUMP_DISABLE_OFF)
|
||||
#define DFX_FIFO_TRIGGER (PORT_BASE + 0x3a4)
|
||||
#define DFX_FIFO_TRIGGER_MSK (PORT_BASE + 0x3a8)
|
||||
#define DFX_FIFO_DUMP_MSK (PORT_BASE + 0x3aC)
|
||||
#define DFX_FIFO_RD_DATA (PORT_BASE + 0x3b0)
|
||||
|
||||
#define DEFAULT_ITCT_HW 2048 /* reset value, not reprogrammed */
|
||||
#if (HISI_SAS_MAX_DEVICES > DEFAULT_ITCT_HW)
|
||||
@ -517,11 +530,6 @@ static int prot_mask;
|
||||
module_param(prot_mask, int, 0);
|
||||
MODULE_PARM_DESC(prot_mask, " host protection capabilities mask, def=0x0 ");
|
||||
|
||||
static bool auto_affine_msi_experimental;
|
||||
module_param(auto_affine_msi_experimental, bool, 0444);
|
||||
MODULE_PARM_DESC(auto_affine_msi_experimental, "Enable auto-affinity of MSI IRQs as experimental:\n"
|
||||
"default is off");
|
||||
|
||||
static void debugfs_work_handler_v3_hw(struct work_struct *work);
|
||||
|
||||
static u32 hisi_sas_read32(struct hisi_hba *hisi_hba, u32 off)
|
||||
@ -1580,7 +1588,8 @@ static irqreturn_t phy_down_v3_hw(int phy_no, struct hisi_hba *hisi_hba)
|
||||
|
||||
phy_state = hisi_sas_read32(hisi_hba, PHY_STATE);
|
||||
dev_info(dev, "phydown: phy%d phy_state=0x%x\n", phy_no, phy_state);
|
||||
hisi_sas_phy_down(hisi_hba, phy_no, (phy_state & 1 << phy_no) ? 1 : 0);
|
||||
hisi_sas_phy_down(hisi_hba, phy_no, (phy_state & 1 << phy_no) ? 1 : 0,
|
||||
GFP_ATOMIC);
|
||||
|
||||
sl_ctrl = hisi_sas_phy_read32(hisi_hba, phy_no, SL_CONTROL);
|
||||
hisi_sas_phy_write32(hisi_hba, phy_no, SL_CONTROL,
|
||||
@ -1600,14 +1609,14 @@ static irqreturn_t phy_bcast_v3_hw(int phy_no, struct hisi_hba *hisi_hba)
|
||||
{
|
||||
struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no];
|
||||
struct asd_sas_phy *sas_phy = &phy->sas_phy;
|
||||
struct sas_ha_struct *sas_ha = &hisi_hba->sha;
|
||||
u32 bcast_status;
|
||||
|
||||
hisi_sas_phy_write32(hisi_hba, phy_no, SL_RX_BCAST_CHK_MSK, 1);
|
||||
bcast_status = hisi_sas_phy_read32(hisi_hba, phy_no, RX_PRIMS_STATUS);
|
||||
if ((bcast_status & RX_BCAST_CHG_MSK) &&
|
||||
!test_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags))
|
||||
sas_ha->notify_port_event(sas_phy, PORTE_BROADCAST_RCVD);
|
||||
sas_notify_port_event(sas_phy, PORTE_BROADCAST_RCVD,
|
||||
GFP_ATOMIC);
|
||||
hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT0,
|
||||
CHL_INT0_SL_RX_BCST_ACK_MSK);
|
||||
hisi_sas_phy_write32(hisi_hba, phy_no, SL_RX_BCAST_CHK_MSK, 0);
|
||||
@ -4157,6 +4166,243 @@ static const struct file_operations debugfs_phy_down_cnt_v3_hw_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
enum fifo_dump_mode_v3_hw {
|
||||
FIFO_DUMP_FORVER = (1U << 0),
|
||||
FIFO_DUMP_AFTER_TRIGGER = (1U << 1),
|
||||
FIFO_DUMP_UNTILL_TRIGGER = (1U << 2),
|
||||
};
|
||||
|
||||
enum fifo_trigger_mode_v3_hw {
|
||||
FIFO_TRIGGER_EDGE = (1U << 0),
|
||||
FIFO_TRIGGER_SAME_LEVEL = (1U << 1),
|
||||
FIFO_TRIGGER_DIFF_LEVEL = (1U << 2),
|
||||
};
|
||||
|
||||
static int debugfs_is_fifo_config_valid_v3_hw(struct hisi_sas_phy *phy)
|
||||
{
|
||||
struct hisi_hba *hisi_hba = phy->hisi_hba;
|
||||
|
||||
if (phy->fifo.signal_sel > 0xf) {
|
||||
dev_info(hisi_hba->dev, "Invalid signal select: %u\n",
|
||||
phy->fifo.signal_sel);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
switch (phy->fifo.dump_mode) {
|
||||
case FIFO_DUMP_FORVER:
|
||||
case FIFO_DUMP_AFTER_TRIGGER:
|
||||
case FIFO_DUMP_UNTILL_TRIGGER:
|
||||
break;
|
||||
default:
|
||||
dev_info(hisi_hba->dev, "Invalid dump mode: %u\n",
|
||||
phy->fifo.dump_mode);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* when FIFO_DUMP_FORVER, no need to check trigger_mode */
|
||||
if (phy->fifo.dump_mode == FIFO_DUMP_FORVER)
|
||||
return 0;
|
||||
|
||||
switch (phy->fifo.trigger_mode) {
|
||||
case FIFO_TRIGGER_EDGE:
|
||||
case FIFO_TRIGGER_SAME_LEVEL:
|
||||
case FIFO_TRIGGER_DIFF_LEVEL:
|
||||
break;
|
||||
default:
|
||||
dev_info(hisi_hba->dev, "Invalid trigger mode: %u\n",
|
||||
phy->fifo.trigger_mode);
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int debugfs_update_fifo_config_v3_hw(struct hisi_sas_phy *phy)
|
||||
{
|
||||
u32 trigger_mode = phy->fifo.trigger_mode;
|
||||
u32 signal_sel = phy->fifo.signal_sel;
|
||||
u32 dump_mode = phy->fifo.dump_mode;
|
||||
struct hisi_hba *hisi_hba = phy->hisi_hba;
|
||||
int phy_no = phy->sas_phy.id;
|
||||
u32 reg_val;
|
||||
int res;
|
||||
|
||||
/* Check the validity of trace FIFO configuration */
|
||||
res = debugfs_is_fifo_config_valid_v3_hw(phy);
|
||||
if (res)
|
||||
return res;
|
||||
|
||||
reg_val = hisi_sas_phy_read32(hisi_hba, phy_no, DFX_FIFO_CTRL);
|
||||
/* Disable trace FIFO before update configuration */
|
||||
reg_val |= DFX_FIFO_CTRL_DUMP_DISABLE_MSK;
|
||||
|
||||
/* Update trace FIFO configuration */
|
||||
reg_val &= ~(DFX_FIFO_CTRL_DUMP_MODE_MSK |
|
||||
DFX_FIFO_CTRL_SIGNAL_SEL_MSK |
|
||||
DFX_FIFO_CTRL_TRIGGER_MODE_MSK);
|
||||
|
||||
reg_val |= ((trigger_mode << DFX_FIFO_CTRL_TRIGGER_MODE_OFF) |
|
||||
(dump_mode << DFX_FIFO_CTRL_DUMP_MODE_OFF) |
|
||||
(signal_sel << DFX_FIFO_CTRL_SIGNAL_SEL_OFF));
|
||||
hisi_sas_phy_write32(hisi_hba, phy_no, DFX_FIFO_CTRL, reg_val);
|
||||
|
||||
hisi_sas_phy_write32(hisi_hba, phy_no, DFX_FIFO_DUMP_MSK,
|
||||
phy->fifo.dump_msk);
|
||||
|
||||
hisi_sas_phy_write32(hisi_hba, phy_no, DFX_FIFO_TRIGGER,
|
||||
phy->fifo.trigger);
|
||||
|
||||
hisi_sas_phy_write32(hisi_hba, phy_no, DFX_FIFO_TRIGGER_MSK,
|
||||
phy->fifo.trigger_msk);
|
||||
|
||||
/* Enable trace FIFO after updated configuration */
|
||||
reg_val = hisi_sas_phy_read32(hisi_hba, phy_no, DFX_FIFO_CTRL);
|
||||
reg_val &= ~DFX_FIFO_CTRL_DUMP_DISABLE_MSK;
|
||||
hisi_sas_phy_write32(hisi_hba, phy_no, DFX_FIFO_CTRL, reg_val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t debugfs_fifo_update_cfg_v3_hw_write(struct file *filp,
|
||||
const char __user *buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct hisi_sas_phy *phy = filp->private_data;
|
||||
bool update;
|
||||
int val;
|
||||
|
||||
val = kstrtobool_from_user(buf, count, &update);
|
||||
if (val)
|
||||
return val;
|
||||
|
||||
if (update != 1)
|
||||
return -EINVAL;
|
||||
|
||||
val = debugfs_update_fifo_config_v3_hw(phy);
|
||||
if (val)
|
||||
return val;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static const struct file_operations debugfs_fifo_update_cfg_v3_hw_fops = {
|
||||
.open = simple_open,
|
||||
.write = debugfs_fifo_update_cfg_v3_hw_write,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
static void debugfs_read_fifo_data_v3_hw(struct hisi_sas_phy *phy)
|
||||
{
|
||||
struct hisi_hba *hisi_hba = phy->hisi_hba;
|
||||
u32 *buf = phy->fifo.rd_data;
|
||||
int phy_no = phy->sas_phy.id;
|
||||
u32 val;
|
||||
int i;
|
||||
|
||||
memset(buf, 0, sizeof(phy->fifo.rd_data));
|
||||
|
||||
/* Disable trace FIFO before read data */
|
||||
val = hisi_sas_phy_read32(hisi_hba, phy_no, DFX_FIFO_CTRL);
|
||||
val |= DFX_FIFO_CTRL_DUMP_DISABLE_MSK;
|
||||
hisi_sas_phy_write32(hisi_hba, phy_no, DFX_FIFO_CTRL, val);
|
||||
|
||||
for (i = 0; i < HISI_SAS_FIFO_DATA_DW_SIZE; i++) {
|
||||
val = hisi_sas_phy_read32(hisi_hba, phy_no,
|
||||
DFX_FIFO_RD_DATA);
|
||||
buf[i] = val;
|
||||
}
|
||||
|
||||
/* Enable trace FIFO after read data */
|
||||
val = hisi_sas_phy_read32(hisi_hba, phy_no, DFX_FIFO_CTRL);
|
||||
val &= ~DFX_FIFO_CTRL_DUMP_DISABLE_MSK;
|
||||
hisi_sas_phy_write32(hisi_hba, phy_no, DFX_FIFO_CTRL, val);
|
||||
}
|
||||
|
||||
static int debugfs_fifo_data_v3_hw_show(struct seq_file *s, void *p)
|
||||
{
|
||||
struct hisi_sas_phy *phy = s->private;
|
||||
|
||||
debugfs_read_fifo_data_v3_hw(phy);
|
||||
|
||||
debugfs_show_row_32_v3_hw(s, 0, HISI_SAS_FIFO_DATA_DW_SIZE * 4,
|
||||
phy->fifo.rd_data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
DEFINE_SHOW_ATTRIBUTE(debugfs_fifo_data_v3_hw);
|
||||
|
||||
static void debugfs_fifo_init_v3_hw(struct hisi_hba *hisi_hba)
|
||||
{
|
||||
int phy_no;
|
||||
|
||||
hisi_hba->debugfs_fifo_dentry =
|
||||
debugfs_create_dir("fifo", hisi_hba->debugfs_dir);
|
||||
|
||||
for (phy_no = 0; phy_no < hisi_hba->n_phy; phy_no++) {
|
||||
struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no];
|
||||
struct dentry *port_dentry;
|
||||
char name[256];
|
||||
u32 val;
|
||||
|
||||
/* get default configuration for trace FIFO */
|
||||
val = hisi_sas_phy_read32(hisi_hba, phy_no, DFX_FIFO_CTRL);
|
||||
val &= DFX_FIFO_CTRL_DUMP_MODE_MSK;
|
||||
val >>= DFX_FIFO_CTRL_DUMP_MODE_OFF;
|
||||
phy->fifo.dump_mode = val;
|
||||
|
||||
val = hisi_sas_phy_read32(hisi_hba, phy_no, DFX_FIFO_CTRL);
|
||||
val &= DFX_FIFO_CTRL_TRIGGER_MODE_MSK;
|
||||
val >>= DFX_FIFO_CTRL_TRIGGER_MODE_OFF;
|
||||
phy->fifo.trigger_mode = val;
|
||||
|
||||
val = hisi_sas_phy_read32(hisi_hba, phy_no, DFX_FIFO_CTRL);
|
||||
val &= DFX_FIFO_CTRL_SIGNAL_SEL_MSK;
|
||||
val >>= DFX_FIFO_CTRL_SIGNAL_SEL_OFF;
|
||||
phy->fifo.signal_sel = val;
|
||||
|
||||
val = hisi_sas_phy_read32(hisi_hba, phy_no, DFX_FIFO_DUMP_MSK);
|
||||
phy->fifo.dump_msk = val;
|
||||
|
||||
val = hisi_sas_phy_read32(hisi_hba, phy_no, DFX_FIFO_TRIGGER);
|
||||
phy->fifo.trigger = val;
|
||||
val = hisi_sas_phy_read32(hisi_hba, phy_no, DFX_FIFO_TRIGGER_MSK);
|
||||
phy->fifo.trigger_msk = val;
|
||||
|
||||
snprintf(name, 256, "%d", phy_no);
|
||||
port_dentry = debugfs_create_dir(name,
|
||||
hisi_hba->debugfs_fifo_dentry);
|
||||
|
||||
debugfs_create_file("update_config", 0200, port_dentry, phy,
|
||||
&debugfs_fifo_update_cfg_v3_hw_fops);
|
||||
|
||||
debugfs_create_file("signal_sel", 0600, port_dentry,
|
||||
&phy->fifo.signal_sel,
|
||||
&debugfs_v3_hw_fops);
|
||||
|
||||
debugfs_create_file("dump_msk", 0600, port_dentry,
|
||||
&phy->fifo.dump_msk,
|
||||
&debugfs_v3_hw_fops);
|
||||
|
||||
debugfs_create_file("dump_mode", 0600, port_dentry,
|
||||
&phy->fifo.dump_mode,
|
||||
&debugfs_v3_hw_fops);
|
||||
|
||||
debugfs_create_file("trigger_mode", 0600, port_dentry,
|
||||
&phy->fifo.trigger_mode,
|
||||
&debugfs_v3_hw_fops);
|
||||
|
||||
debugfs_create_file("trigger", 0600, port_dentry,
|
||||
&phy->fifo.trigger,
|
||||
&debugfs_v3_hw_fops);
|
||||
|
||||
debugfs_create_file("trigger_msk", 0600, port_dentry,
|
||||
&phy->fifo.trigger_msk,
|
||||
&debugfs_v3_hw_fops);
|
||||
|
||||
debugfs_create_file("fifo_data", 0400, port_dentry, phy,
|
||||
&debugfs_fifo_data_v3_hw_fops);
|
||||
}
|
||||
}
|
||||
|
||||
static void debugfs_work_handler_v3_hw(struct work_struct *work)
|
||||
{
|
||||
struct hisi_hba *hisi_hba =
|
||||
@ -4392,6 +4638,7 @@ static void debugfs_init_v3_hw(struct hisi_hba *hisi_hba)
|
||||
debugfs_create_dir("dump", hisi_hba->debugfs_dir);
|
||||
|
||||
debugfs_phy_down_cnt_init_v3_hw(hisi_hba);
|
||||
debugfs_fifo_init_v3_hw(hisi_hba);
|
||||
|
||||
for (i = 0; i < hisi_sas_debugfs_dump_count; i++) {
|
||||
if (debugfs_alloc_v3_hw(hisi_hba, i)) {
|
||||
@ -4576,6 +4823,7 @@ static void hisi_sas_v3_remove(struct pci_dev *pdev)
|
||||
del_timer(&hisi_hba->timer);
|
||||
|
||||
sas_unregister_ha(sha);
|
||||
flush_workqueue(hisi_hba->wq);
|
||||
sas_remove_host(sha->core.shost);
|
||||
|
||||
hisi_sas_v3_destroy_irqs(pdev, hisi_hba);
|
||||
|
@ -2396,7 +2396,6 @@ static int handle_ioaccel_mode2_error(struct ctlr_info *h,
|
||||
break;
|
||||
case IOACCEL2_STATUS_SR_UNDERRUN:
|
||||
cmd->result = (DID_OK << 16); /* host byte */
|
||||
cmd->result |= (COMMAND_COMPLETE << 8); /* msg byte */
|
||||
ioaccel2_resid = get_unaligned_le32(
|
||||
&c2->error_data.resid_cnt[0]);
|
||||
scsi_set_resid(cmd, ioaccel2_resid);
|
||||
@ -2597,8 +2596,7 @@ static void complete_scsi_command(struct CommandList *cp)
|
||||
(c2->sg[0].chain_indicator == IOACCEL2_CHAIN))
|
||||
hpsa_unmap_ioaccel2_sg_chain_block(h, c2);
|
||||
|
||||
cmd->result = (DID_OK << 16); /* host byte */
|
||||
cmd->result |= (COMMAND_COMPLETE << 8); /* msg byte */
|
||||
cmd->result = (DID_OK << 16); /* host byte */
|
||||
|
||||
/* SCSI command has already been cleaned up in SML */
|
||||
if (dev->was_removed) {
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -41,6 +41,12 @@
|
||||
#define IBMVFC_DEFAULT_LOG_LEVEL 2
|
||||
#define IBMVFC_MAX_CDB_LEN 16
|
||||
#define IBMVFC_CLS3_ERROR 0
|
||||
#define IBMVFC_MQ 1
|
||||
#define IBMVFC_SCSI_CHANNELS 8
|
||||
#define IBMVFC_MAX_SCSI_QUEUES 16
|
||||
#define IBMVFC_SCSI_HW_QUEUES 8
|
||||
#define IBMVFC_MIG_NO_SUB_TO_CRQ 0
|
||||
#define IBMVFC_MIG_NO_N_TO_M 0
|
||||
|
||||
/*
|
||||
* Ensure we have resources for ERP and initialization:
|
||||
@ -645,11 +651,10 @@ struct ibmvfc_crq {
|
||||
volatile __be64 ioba;
|
||||
} __packed __aligned(8);
|
||||
|
||||
struct ibmvfc_crq_queue {
|
||||
struct ibmvfc_crq *msgs;
|
||||
int size, cur;
|
||||
dma_addr_t msg_token;
|
||||
};
|
||||
struct ibmvfc_sub_crq {
|
||||
struct ibmvfc_crq crq;
|
||||
__be64 reserved[2];
|
||||
} __packed __aligned(8);
|
||||
|
||||
enum ibmvfc_ae_link_state {
|
||||
IBMVFC_AE_LS_LINK_UP = 0x01,
|
||||
@ -678,12 +683,6 @@ struct ibmvfc_async_crq {
|
||||
__be64 reserved;
|
||||
} __packed __aligned(8);
|
||||
|
||||
struct ibmvfc_async_crq_queue {
|
||||
struct ibmvfc_async_crq *msgs;
|
||||
int size, cur;
|
||||
dma_addr_t msg_token;
|
||||
};
|
||||
|
||||
union ibmvfc_iu {
|
||||
struct ibmvfc_mad_common mad_common;
|
||||
struct ibmvfc_npiv_login_mad npiv_login;
|
||||
@ -738,13 +737,16 @@ struct ibmvfc_target {
|
||||
|
||||
/* a unit of work for the hosting partition */
|
||||
struct ibmvfc_event {
|
||||
struct list_head queue;
|
||||
struct list_head queue_list;
|
||||
struct list_head cancel;
|
||||
struct ibmvfc_host *vhost;
|
||||
struct ibmvfc_queue *queue;
|
||||
struct ibmvfc_target *tgt;
|
||||
struct scsi_cmnd *cmnd;
|
||||
atomic_t free;
|
||||
union ibmvfc_iu *xfer_iu;
|
||||
void (*done) (struct ibmvfc_event *);
|
||||
void (*done)(struct ibmvfc_event *evt);
|
||||
void (*_done)(struct ibmvfc_event *evt);
|
||||
struct ibmvfc_crq crq;
|
||||
union ibmvfc_iu iu;
|
||||
union ibmvfc_iu *sync_iu;
|
||||
@ -753,6 +755,7 @@ struct ibmvfc_event {
|
||||
struct completion comp;
|
||||
struct completion *eh_comp;
|
||||
struct timer_list timer;
|
||||
u16 hwq;
|
||||
};
|
||||
|
||||
/* a pool of event structs for use */
|
||||
@ -763,6 +766,49 @@ struct ibmvfc_event_pool {
|
||||
dma_addr_t iu_token;
|
||||
};
|
||||
|
||||
enum ibmvfc_msg_fmt {
|
||||
IBMVFC_CRQ_FMT = 0,
|
||||
IBMVFC_ASYNC_FMT,
|
||||
IBMVFC_SUB_CRQ_FMT,
|
||||
};
|
||||
|
||||
union ibmvfc_msgs {
|
||||
void *handle;
|
||||
struct ibmvfc_crq *crq;
|
||||
struct ibmvfc_async_crq *async;
|
||||
struct ibmvfc_sub_crq *scrq;
|
||||
};
|
||||
|
||||
struct ibmvfc_queue {
|
||||
union ibmvfc_msgs msgs;
|
||||
dma_addr_t msg_token;
|
||||
enum ibmvfc_msg_fmt fmt;
|
||||
int size, cur;
|
||||
spinlock_t _lock;
|
||||
spinlock_t *q_lock;
|
||||
|
||||
struct ibmvfc_event_pool evt_pool;
|
||||
struct list_head sent;
|
||||
struct list_head free;
|
||||
spinlock_t l_lock;
|
||||
|
||||
union ibmvfc_iu cancel_rsp;
|
||||
|
||||
/* Sub-CRQ fields */
|
||||
struct ibmvfc_host *vhost;
|
||||
unsigned long cookie;
|
||||
unsigned long vios_cookie;
|
||||
unsigned long hw_irq;
|
||||
unsigned long irq;
|
||||
unsigned long hwq_id;
|
||||
char name[32];
|
||||
};
|
||||
|
||||
struct ibmvfc_scsi_channels {
|
||||
struct ibmvfc_queue *scrqs;
|
||||
unsigned int active_queues;
|
||||
};
|
||||
|
||||
enum ibmvfc_host_action {
|
||||
IBMVFC_HOST_ACTION_NONE = 0,
|
||||
IBMVFC_HOST_ACTION_RESET,
|
||||
@ -797,26 +843,29 @@ struct ibmvfc_host {
|
||||
enum ibmvfc_host_action action;
|
||||
#define IBMVFC_NUM_TRACE_INDEX_BITS 8
|
||||
#define IBMVFC_NUM_TRACE_ENTRIES (1 << IBMVFC_NUM_TRACE_INDEX_BITS)
|
||||
#define IBMVFC_TRACE_INDEX_MASK (IBMVFC_NUM_TRACE_ENTRIES - 1)
|
||||
#define IBMVFC_TRACE_SIZE (sizeof(struct ibmvfc_trace_entry) * IBMVFC_NUM_TRACE_ENTRIES)
|
||||
struct ibmvfc_trace_entry *trace;
|
||||
u32 trace_index:IBMVFC_NUM_TRACE_INDEX_BITS;
|
||||
atomic_t trace_index;
|
||||
int num_targets;
|
||||
struct list_head targets;
|
||||
struct list_head sent;
|
||||
struct list_head free;
|
||||
struct list_head purge;
|
||||
struct device *dev;
|
||||
struct ibmvfc_event_pool pool;
|
||||
struct dma_pool *sg_pool;
|
||||
mempool_t *tgt_pool;
|
||||
struct ibmvfc_crq_queue crq;
|
||||
struct ibmvfc_async_crq_queue async_crq;
|
||||
struct ibmvfc_queue crq;
|
||||
struct ibmvfc_queue async_crq;
|
||||
struct ibmvfc_scsi_channels scsi_scrqs;
|
||||
struct ibmvfc_npiv_login login_info;
|
||||
union ibmvfc_npiv_login_data *login_buf;
|
||||
dma_addr_t login_buf_dma;
|
||||
struct ibmvfc_channel_setup *channel_setup_buf;
|
||||
dma_addr_t channel_setup_dma;
|
||||
int disc_buf_sz;
|
||||
int log_level;
|
||||
struct ibmvfc_discover_targets_entry *disc_buf;
|
||||
struct mutex passthru_mutex;
|
||||
int max_vios_scsi_channels;
|
||||
int task_set;
|
||||
int init_retries;
|
||||
int discovery_threads;
|
||||
@ -826,6 +875,10 @@ struct ibmvfc_host {
|
||||
int delay_init;
|
||||
int scan_complete;
|
||||
int logged_in;
|
||||
int mq_enabled;
|
||||
int using_channels;
|
||||
int do_enquiry;
|
||||
int client_scsi_channels;
|
||||
int aborting_passthru;
|
||||
int events_to_log;
|
||||
#define IBMVFC_AE_LINKUP 0x0001
|
||||
|
@ -1315,15 +1315,15 @@ static int initio_state_1(struct initio_host * host)
|
||||
}
|
||||
if ((active_tc->flags & (TCF_WDTR_DONE | TCF_NO_WDTR)) == 0) {
|
||||
active_tc->flags |= TCF_WDTR_DONE;
|
||||
outb(MSG_EXTEND, host->addr + TUL_SFifo);
|
||||
outb(EXTENDED_MESSAGE, host->addr + TUL_SFifo);
|
||||
outb(2, host->addr + TUL_SFifo); /* Extended msg length */
|
||||
outb(3, host->addr + TUL_SFifo); /* Sync request */
|
||||
outb(EXTENDED_SDTR, host->addr + TUL_SFifo); /* Sync request */
|
||||
outb(1, host->addr + TUL_SFifo); /* Start from 16 bits */
|
||||
} else if ((active_tc->flags & (TCF_SYNC_DONE | TCF_NO_SYNC_NEGO)) == 0) {
|
||||
active_tc->flags |= TCF_SYNC_DONE;
|
||||
outb(MSG_EXTEND, host->addr + TUL_SFifo);
|
||||
outb(EXTENDED_MESSAGE, host->addr + TUL_SFifo);
|
||||
outb(3, host->addr + TUL_SFifo); /* extended msg length */
|
||||
outb(1, host->addr + TUL_SFifo); /* sync request */
|
||||
outb(EXTENDED_SDTR, host->addr + TUL_SFifo); /* sync request */
|
||||
outb(initio_rate_tbl[active_tc->flags & TCF_SCSI_RATE], host->addr + TUL_SFifo);
|
||||
outb(MAX_OFFSET, host->addr + TUL_SFifo); /* REQ/ACK offset */
|
||||
}
|
||||
@ -1409,16 +1409,16 @@ static int initio_state_3(struct initio_host * host)
|
||||
|
||||
case MSG_OUT: /* Message out phase */
|
||||
if (active_tc->flags & (TCF_SYNC_DONE | TCF_NO_SYNC_NEGO)) {
|
||||
outb(MSG_NOP, host->addr + TUL_SFifo); /* msg nop */
|
||||
outb(NOP, host->addr + TUL_SFifo); /* msg nop */
|
||||
outb(TSC_XF_FIFO_OUT, host->addr + TUL_SCmd);
|
||||
if (wait_tulip(host) == -1)
|
||||
return -1;
|
||||
} else {
|
||||
active_tc->flags |= TCF_SYNC_DONE;
|
||||
|
||||
outb(MSG_EXTEND, host->addr + TUL_SFifo);
|
||||
outb(EXTENDED_MESSAGE, host->addr + TUL_SFifo);
|
||||
outb(3, host->addr + TUL_SFifo); /* ext. msg len */
|
||||
outb(1, host->addr + TUL_SFifo); /* sync request */
|
||||
outb(EXTENDED_SDTR, host->addr + TUL_SFifo); /* sync request */
|
||||
outb(initio_rate_tbl[active_tc->flags & TCF_SCSI_RATE], host->addr + TUL_SFifo);
|
||||
outb(MAX_OFFSET, host->addr + TUL_SFifo); /* REQ/ACK offset */
|
||||
outb(TSC_XF_FIFO_OUT, host->addr + TUL_SCmd);
|
||||
@ -1479,7 +1479,7 @@ static int initio_state_4(struct initio_host * host)
|
||||
return -1;
|
||||
return 6;
|
||||
} else {
|
||||
outb(MSG_NOP, host->addr + TUL_SFifo); /* msg nop */
|
||||
outb(NOP, host->addr + TUL_SFifo); /* msg nop */
|
||||
outb(TSC_XF_FIFO_OUT, host->addr + TUL_SCmd);
|
||||
if (wait_tulip(host) == -1)
|
||||
return -1;
|
||||
@ -1616,7 +1616,7 @@ static int initio_state_6(struct initio_host * host)
|
||||
break;
|
||||
|
||||
case MSG_OUT: /* Message out phase */
|
||||
outb(MSG_NOP, host->addr + TUL_SFifo); /* msg nop */
|
||||
outb(NOP, host->addr + TUL_SFifo); /* msg nop */
|
||||
outb(TSC_XF_FIFO_OUT, host->addr + TUL_SCmd);
|
||||
if (wait_tulip(host) == -1)
|
||||
return -1;
|
||||
@ -1789,9 +1789,9 @@ int initio_status_msg(struct initio_host * host)
|
||||
|
||||
if (host->phase == MSG_OUT) {
|
||||
if (host->jsstatus0 & TSS_PAR_ERROR)
|
||||
outb(MSG_PARITY, host->addr + TUL_SFifo);
|
||||
outb(MSG_PARITY_ERROR, host->addr + TUL_SFifo);
|
||||
else
|
||||
outb(MSG_NOP, host->addr + TUL_SFifo);
|
||||
outb(NOP, host->addr + TUL_SFifo);
|
||||
outb(TSC_XF_FIFO_OUT, host->addr + TUL_SCmd);
|
||||
return wait_tulip(host);
|
||||
}
|
||||
@ -1802,7 +1802,7 @@ int initio_status_msg(struct initio_host * host)
|
||||
return -1;
|
||||
if (host->phase != MSG_OUT)
|
||||
return initio_bad_seq(host);
|
||||
outb(MSG_PARITY, host->addr + TUL_SFifo);
|
||||
outb(MSG_PARITY_ERROR, host->addr + TUL_SFifo);
|
||||
outb(TSC_XF_FIFO_OUT, host->addr + TUL_SCmd);
|
||||
return wait_tulip(host);
|
||||
}
|
||||
@ -1815,7 +1815,8 @@ int initio_status_msg(struct initio_host * host)
|
||||
return initio_wait_done_disc(host);
|
||||
|
||||
}
|
||||
if (msg == MSG_LINK_COMP || msg == MSG_LINK_FLAG) {
|
||||
if (msg == LINKED_CMD_COMPLETE ||
|
||||
msg == LINKED_FLG_CMD_COMPLETE) {
|
||||
if ((scb->tastat & 0x18) == 0x10)
|
||||
return initio_msgin_accept(host);
|
||||
}
|
||||
@ -1930,7 +1931,8 @@ int int_initio_resel(struct initio_host * host)
|
||||
return -1;
|
||||
msg = inb(host->addr + TUL_SFifo); /* Read Tag Message */
|
||||
|
||||
if (msg < MSG_STAG || msg > MSG_OTAG) /* Is simple Tag */
|
||||
if (msg < SIMPLE_QUEUE_TAG || msg > ORDERED_QUEUE_TAG)
|
||||
/* Is simple Tag */
|
||||
goto no_tag;
|
||||
|
||||
if (initio_msgin_accept(host) == -1)
|
||||
@ -2010,7 +2012,7 @@ static int initio_msgout_abort_targ(struct initio_host * host)
|
||||
if (host->phase != MSG_OUT)
|
||||
return initio_bad_seq(host);
|
||||
|
||||
outb(MSG_ABORT, host->addr + TUL_SFifo);
|
||||
outb(ABORT_TASK_SET, host->addr + TUL_SFifo);
|
||||
outb(TSC_XF_FIFO_OUT, host->addr + TUL_SCmd);
|
||||
|
||||
return initio_wait_disc(host);
|
||||
@ -2033,7 +2035,7 @@ static int initio_msgout_abort_tag(struct initio_host * host)
|
||||
if (host->phase != MSG_OUT)
|
||||
return initio_bad_seq(host);
|
||||
|
||||
outb(MSG_ABORT_TAG, host->addr + TUL_SFifo);
|
||||
outb(ABORT_TASK, host->addr + TUL_SFifo);
|
||||
outb(TSC_XF_FIFO_OUT, host->addr + TUL_SCmd);
|
||||
|
||||
return initio_wait_disc(host);
|
||||
@ -2059,15 +2061,15 @@ static int initio_msgin(struct initio_host * host)
|
||||
return -1;
|
||||
|
||||
switch (inb(host->addr + TUL_SFifo)) {
|
||||
case MSG_DISC: /* Disconnect msg */
|
||||
case DISCONNECT: /* Disconnect msg */
|
||||
outb(TSC_MSG_ACCEPT, host->addr + TUL_SCmd);
|
||||
return initio_wait_disc(host);
|
||||
case MSG_SDP:
|
||||
case MSG_RESTORE:
|
||||
case MSG_NOP:
|
||||
case SAVE_POINTERS:
|
||||
case RESTORE_POINTERS:
|
||||
case NOP:
|
||||
initio_msgin_accept(host);
|
||||
break;
|
||||
case MSG_REJ: /* Clear ATN first */
|
||||
case MESSAGE_REJECT: /* Clear ATN first */
|
||||
outb((inb(host->addr + TUL_SSignal) & (TSC_SET_ACK | 7)),
|
||||
host->addr + TUL_SSignal);
|
||||
active_tc = host->active_tc;
|
||||
@ -2076,13 +2078,13 @@ static int initio_msgin(struct initio_host * host)
|
||||
host->addr + TUL_SSignal);
|
||||
initio_msgin_accept(host);
|
||||
break;
|
||||
case MSG_EXTEND: /* extended msg */
|
||||
case EXTENDED_MESSAGE: /* extended msg */
|
||||
initio_msgin_extend(host);
|
||||
break;
|
||||
case MSG_IGNOREWIDE:
|
||||
case IGNORE_WIDE_RESIDUE:
|
||||
initio_msgin_accept(host);
|
||||
break;
|
||||
case MSG_COMP:
|
||||
case COMMAND_COMPLETE:
|
||||
outb(TSC_FLUSH_FIFO, host->addr + TUL_SCtrl0);
|
||||
outb(TSC_MSG_ACCEPT, host->addr + TUL_SCmd);
|
||||
return initio_wait_done_disc(host);
|
||||
@ -2104,7 +2106,7 @@ static int initio_msgout_reject(struct initio_host * host)
|
||||
return -1;
|
||||
|
||||
if (host->phase == MSG_OUT) {
|
||||
outb(MSG_REJ, host->addr + TUL_SFifo); /* Msg reject */
|
||||
outb(MESSAGE_REJECT, host->addr + TUL_SFifo); /* Msg reject */
|
||||
outb(TSC_XF_FIFO_OUT, host->addr + TUL_SCmd);
|
||||
return wait_tulip(host);
|
||||
}
|
||||
@ -2113,7 +2115,7 @@ static int initio_msgout_reject(struct initio_host * host)
|
||||
|
||||
static int initio_msgout_ide(struct initio_host * host)
|
||||
{
|
||||
outb(MSG_IDE, host->addr + TUL_SFifo); /* Initiator Detected Error */
|
||||
outb(INITIATOR_ERROR, host->addr + TUL_SFifo); /* Initiator Detected Error */
|
||||
outb(TSC_XF_FIFO_OUT, host->addr + TUL_SCmd);
|
||||
return wait_tulip(host);
|
||||
}
|
||||
@ -2167,9 +2169,9 @@ static int initio_msgin_extend(struct initio_host * host)
|
||||
|
||||
initio_sync_done(host);
|
||||
|
||||
outb(MSG_EXTEND, host->addr + TUL_SFifo);
|
||||
outb(EXTENDED_MESSAGE, host->addr + TUL_SFifo);
|
||||
outb(3, host->addr + TUL_SFifo);
|
||||
outb(1, host->addr + TUL_SFifo);
|
||||
outb(EXTENDED_SDTR, host->addr + TUL_SFifo);
|
||||
outb(host->msg[2], host->addr + TUL_SFifo);
|
||||
outb(host->msg[3], host->addr + TUL_SFifo);
|
||||
outb(TSC_XF_FIFO_OUT, host->addr + TUL_SCmd);
|
||||
@ -2199,9 +2201,9 @@ static int initio_msgin_extend(struct initio_host * host)
|
||||
if (initio_msgin_accept(host) != MSG_OUT)
|
||||
return host->phase;
|
||||
/* WDTR msg out */
|
||||
outb(MSG_EXTEND, host->addr + TUL_SFifo);
|
||||
outb(EXTENDED_MESSAGE, host->addr + TUL_SFifo);
|
||||
outb(2, host->addr + TUL_SFifo);
|
||||
outb(3, host->addr + TUL_SFifo);
|
||||
outb(EXTENDED_WDTR, host->addr + TUL_SFifo);
|
||||
outb(host->msg[2], host->addr + TUL_SFifo);
|
||||
outb(TSC_XF_FIFO_OUT, host->addr + TUL_SCmd);
|
||||
return wait_tulip(host);
|
||||
@ -2391,7 +2393,7 @@ int initio_bus_device_reset(struct initio_host * host)
|
||||
}
|
||||
tmp = tmp->next;
|
||||
}
|
||||
outb(MSG_DEVRST, host->addr + TUL_SFifo);
|
||||
outb(TARGET_RESET, host->addr + TUL_SFifo);
|
||||
outb(TSC_XF_FIFO_OUT, host->addr + TUL_SCmd);
|
||||
return initio_wait_disc(host);
|
||||
|
||||
|
@ -433,31 +433,6 @@ struct scsi_ctrl_blk {
|
||||
#define TARGET_BUSY 0x08
|
||||
#define INI_QUEUE_FULL 0x28
|
||||
|
||||
/* SCSI MESSAGE */
|
||||
#define MSG_COMP 0x00
|
||||
#define MSG_EXTEND 0x01
|
||||
#define MSG_SDP 0x02
|
||||
#define MSG_RESTORE 0x03
|
||||
#define MSG_DISC 0x04
|
||||
#define MSG_IDE 0x05
|
||||
#define MSG_ABORT 0x06
|
||||
#define MSG_REJ 0x07
|
||||
#define MSG_NOP 0x08
|
||||
#define MSG_PARITY 0x09
|
||||
#define MSG_LINK_COMP 0x0A
|
||||
#define MSG_LINK_FLAG 0x0B
|
||||
#define MSG_DEVRST 0x0C
|
||||
#define MSG_ABORT_TAG 0x0D
|
||||
|
||||
/* Queue tag msg: Simple_quque_tag, Head_of_queue_tag, Ordered_queue_tag */
|
||||
#define MSG_STAG 0x20
|
||||
#define MSG_HTAG 0x21
|
||||
#define MSG_OTAG 0x22
|
||||
|
||||
#define MSG_IGNOREWIDE 0x23
|
||||
|
||||
#define MSG_IDENT 0x80
|
||||
|
||||
/***********************************************************************
|
||||
Target Device Control Structure
|
||||
**********************************************************************/
|
||||
|
@ -1045,10 +1045,10 @@ static int ips_queue_lck(struct scsi_cmnd *SC, void (*done) (struct scsi_cmnd *)
|
||||
ha = (ips_ha_t *) SC->device->host->hostdata;
|
||||
|
||||
if (!ha)
|
||||
return (1);
|
||||
goto out_error;
|
||||
|
||||
if (!ha->active)
|
||||
return (DID_ERROR);
|
||||
goto out_error;
|
||||
|
||||
if (ips_is_passthru(SC)) {
|
||||
if (ha->copp_waitlist.count == IPS_MAX_IOCTL_QUEUE) {
|
||||
@ -1123,6 +1123,11 @@ static int ips_queue_lck(struct scsi_cmnd *SC, void (*done) (struct scsi_cmnd *)
|
||||
|
||||
ips_next(ha, IPS_INTR_IORL);
|
||||
|
||||
return (0);
|
||||
out_error:
|
||||
SC->result = DID_ERROR << 16;
|
||||
done(SC);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -164,7 +164,8 @@ static void isci_port_bc_change_received(struct isci_host *ihost,
|
||||
"%s: isci_phy = %p, sas_phy = %p\n",
|
||||
__func__, iphy, &iphy->sas_phy);
|
||||
|
||||
ihost->sas_ha.notify_port_event(&iphy->sas_phy, PORTE_BROADCAST_RCVD);
|
||||
sas_notify_port_event(&iphy->sas_phy,
|
||||
PORTE_BROADCAST_RCVD, GFP_ATOMIC);
|
||||
sci_port_bcn_enable(iport);
|
||||
}
|
||||
|
||||
@ -223,8 +224,8 @@ static void isci_port_link_up(struct isci_host *isci_host,
|
||||
/* Notify libsas that we have an address frame, if indeed
|
||||
* we've found an SSP, SMP, or STP target */
|
||||
if (success)
|
||||
isci_host->sas_ha.notify_port_event(&iphy->sas_phy,
|
||||
PORTE_BYTES_DMAED);
|
||||
sas_notify_port_event(&iphy->sas_phy,
|
||||
PORTE_BYTES_DMAED, GFP_ATOMIC);
|
||||
}
|
||||
|
||||
|
||||
@ -270,8 +271,8 @@ static void isci_port_link_down(struct isci_host *isci_host,
|
||||
* isci_port_deformed and isci_dev_gone functions.
|
||||
*/
|
||||
sas_phy_disconnected(&isci_phy->sas_phy);
|
||||
isci_host->sas_ha.notify_phy_event(&isci_phy->sas_phy,
|
||||
PHYE_LOSS_OF_SIGNAL);
|
||||
sas_notify_phy_event(&isci_phy->sas_phy,
|
||||
PHYE_LOSS_OF_SIGNAL, GFP_ATOMIC);
|
||||
|
||||
dev_dbg(&isci_host->pdev->dev,
|
||||
"%s: isci_port = %p - Done\n", __func__, isci_port);
|
||||
|
@ -2103,8 +2103,6 @@ sci_io_request_frame_handler(struct isci_request *ireq,
|
||||
static enum sci_status stp_request_udma_await_tc_event(struct isci_request *ireq,
|
||||
u32 completion_code)
|
||||
{
|
||||
enum sci_status status = SCI_SUCCESS;
|
||||
|
||||
switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
|
||||
case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
|
||||
ireq->scu_status = SCU_TASK_DONE_GOOD;
|
||||
@ -2148,7 +2146,7 @@ static enum sci_status stp_request_udma_await_tc_event(struct isci_request *ireq
|
||||
break;
|
||||
}
|
||||
|
||||
return status;
|
||||
return SCI_SUCCESS;
|
||||
}
|
||||
|
||||
static enum sci_status atapi_raw_completion(struct isci_request *ireq, u32 completion_code,
|
||||
|
@ -109,7 +109,8 @@ void sas_enable_revalidation(struct sas_ha_struct *ha)
|
||||
|
||||
sas_phy = container_of(port->phy_list.next, struct asd_sas_phy,
|
||||
port_phy_el);
|
||||
ha->notify_port_event(sas_phy, PORTE_BROADCAST_RCVD);
|
||||
sas_notify_port_event(sas_phy,
|
||||
PORTE_BROADCAST_RCVD, GFP_KERNEL);
|
||||
}
|
||||
mutex_unlock(&ha->disco_mutex);
|
||||
}
|
||||
@ -131,15 +132,16 @@ static void sas_phy_event_worker(struct work_struct *work)
|
||||
sas_free_event(ev);
|
||||
}
|
||||
|
||||
static int sas_notify_port_event(struct asd_sas_phy *phy, enum port_event event)
|
||||
int sas_notify_port_event(struct asd_sas_phy *phy, enum port_event event,
|
||||
gfp_t gfp_flags)
|
||||
{
|
||||
struct asd_sas_event *ev;
|
||||
struct sas_ha_struct *ha = phy->ha;
|
||||
struct asd_sas_event *ev;
|
||||
int ret;
|
||||
|
||||
BUG_ON(event >= PORT_NUM_EVENTS);
|
||||
|
||||
ev = sas_alloc_event(phy);
|
||||
ev = sas_alloc_event(phy, gfp_flags);
|
||||
if (!ev)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -151,16 +153,18 @@ static int sas_notify_port_event(struct asd_sas_phy *phy, enum port_event event)
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(sas_notify_port_event);
|
||||
|
||||
int sas_notify_phy_event(struct asd_sas_phy *phy, enum phy_event event)
|
||||
int sas_notify_phy_event(struct asd_sas_phy *phy, enum phy_event event,
|
||||
gfp_t gfp_flags)
|
||||
{
|
||||
struct asd_sas_event *ev;
|
||||
struct sas_ha_struct *ha = phy->ha;
|
||||
struct asd_sas_event *ev;
|
||||
int ret;
|
||||
|
||||
BUG_ON(event >= PHY_NUM_EVENTS);
|
||||
|
||||
ev = sas_alloc_event(phy);
|
||||
ev = sas_alloc_event(phy, gfp_flags);
|
||||
if (!ev)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -172,11 +176,4 @@ int sas_notify_phy_event(struct asd_sas_phy *phy, enum phy_event event)
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int sas_init_events(struct sas_ha_struct *sas_ha)
|
||||
{
|
||||
sas_ha->notify_port_event = sas_notify_port_event;
|
||||
sas_ha->notify_phy_event = sas_notify_phy_event;
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(sas_notify_phy_event);
|
||||
|
@ -123,12 +123,6 @@ int sas_register_ha(struct sas_ha_struct *sas_ha)
|
||||
goto Undo_phys;
|
||||
}
|
||||
|
||||
error = sas_init_events(sas_ha);
|
||||
if (error) {
|
||||
pr_notice("couldn't start event thread:%d\n", error);
|
||||
goto Undo_ports;
|
||||
}
|
||||
|
||||
error = -ENOMEM;
|
||||
snprintf(name, sizeof(name), "%s_event_q", dev_name(sas_ha->dev));
|
||||
sas_ha->event_q = create_singlethread_workqueue(name);
|
||||
@ -410,7 +404,8 @@ void sas_resume_ha(struct sas_ha_struct *ha)
|
||||
|
||||
if (phy->suspended) {
|
||||
dev_warn(&phy->phy->dev, "resume timeout\n");
|
||||
sas_notify_phy_event(phy, PHYE_RESUME_TIMEOUT);
|
||||
sas_notify_phy_event(phy, PHYE_RESUME_TIMEOUT,
|
||||
GFP_KERNEL);
|
||||
}
|
||||
}
|
||||
|
||||
@ -590,16 +585,15 @@ sas_domain_attach_transport(struct sas_domain_function_template *dft)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(sas_domain_attach_transport);
|
||||
|
||||
|
||||
struct asd_sas_event *sas_alloc_event(struct asd_sas_phy *phy)
|
||||
struct asd_sas_event *sas_alloc_event(struct asd_sas_phy *phy,
|
||||
gfp_t gfp_flags)
|
||||
{
|
||||
struct asd_sas_event *event;
|
||||
gfp_t flags = in_interrupt() ? GFP_ATOMIC : GFP_KERNEL;
|
||||
struct sas_ha_struct *sas_ha = phy->ha;
|
||||
struct sas_internal *i =
|
||||
to_sas_internal(sas_ha->core.shost->transportt);
|
||||
|
||||
event = kmem_cache_zalloc(sas_event_cache, flags);
|
||||
event = kmem_cache_zalloc(sas_event_cache, gfp_flags);
|
||||
if (!event)
|
||||
return NULL;
|
||||
|
||||
@ -610,7 +604,8 @@ struct asd_sas_event *sas_alloc_event(struct asd_sas_phy *phy)
|
||||
if (cmpxchg(&phy->in_shutdown, 0, 1) == 0) {
|
||||
pr_notice("The phy%d bursting events, shut it down.\n",
|
||||
phy->id);
|
||||
sas_notify_phy_event(phy, PHYE_SHUTDOWN);
|
||||
sas_notify_phy_event(phy, PHYE_SHUTDOWN,
|
||||
gfp_flags);
|
||||
}
|
||||
} else {
|
||||
/* Do not support PHY control, stop allocating events */
|
||||
|
@ -48,13 +48,12 @@ int sas_show_oob_mode(enum sas_oob_mode oob_mode, char *buf);
|
||||
int sas_register_phys(struct sas_ha_struct *sas_ha);
|
||||
void sas_unregister_phys(struct sas_ha_struct *sas_ha);
|
||||
|
||||
struct asd_sas_event *sas_alloc_event(struct asd_sas_phy *phy);
|
||||
struct asd_sas_event *sas_alloc_event(struct asd_sas_phy *phy, gfp_t gfp_flags);
|
||||
void sas_free_event(struct asd_sas_event *event);
|
||||
|
||||
int sas_register_ports(struct sas_ha_struct *sas_ha);
|
||||
void sas_unregister_ports(struct sas_ha_struct *sas_ha);
|
||||
|
||||
int sas_init_events(struct sas_ha_struct *sas_ha);
|
||||
void sas_disable_revalidation(struct sas_ha_struct *ha);
|
||||
void sas_enable_revalidation(struct sas_ha_struct *ha);
|
||||
void __sas_drain_work(struct sas_ha_struct *ha);
|
||||
@ -77,7 +76,8 @@ int sas_smp_phy_control(struct domain_device *dev, int phy_id,
|
||||
enum phy_func phy_func, struct sas_phy_linkrates *);
|
||||
int sas_smp_get_phy_events(struct sas_phy *phy);
|
||||
|
||||
int sas_notify_phy_event(struct asd_sas_phy *phy, enum phy_event event);
|
||||
int sas_notify_phy_event(struct asd_sas_phy *phy, enum phy_event event,
|
||||
gfp_t flags);
|
||||
void sas_device_set_phy(struct domain_device *dev, struct sas_port *port);
|
||||
struct domain_device *sas_find_dev_by_rphy(struct sas_rphy *rphy);
|
||||
struct domain_device *sas_ex_to_ata(struct domain_device *ex_dev, int phy_id);
|
||||
|
@ -779,6 +779,9 @@ struct lpfc_hba {
|
||||
*/
|
||||
#define HBA_FLOGI_ISSUED 0x100000 /* FLOGI was issued */
|
||||
#define HBA_DEFER_FLOGI 0x800000 /* Defer FLOGI till read_sparm cmpl */
|
||||
#define HBA_NEEDS_CFG_PORT 0x2000000 /* SLI3 - needs a CONFIG_PORT mbox */
|
||||
#define HBA_HBEAT_INP 0x4000000 /* mbox HBEAT is in progress */
|
||||
#define HBA_HBEAT_TMO 0x8000000 /* HBEAT initiated after timeout */
|
||||
|
||||
uint32_t fcp_ring_in_use; /* When polling test if intr-hndlr active*/
|
||||
struct lpfc_dmabuf slim2p;
|
||||
@ -1135,7 +1138,6 @@ struct lpfc_hba {
|
||||
unsigned long last_completion_time;
|
||||
unsigned long skipped_hb;
|
||||
struct timer_list hb_tmofunc;
|
||||
uint8_t hb_outstanding;
|
||||
struct timer_list rrq_tmr;
|
||||
enum hba_temp_state over_temp_state;
|
||||
/*
|
||||
|
@ -1788,6 +1788,8 @@ lpfc_board_mode_store(struct device *dev, struct device_attribute *attr,
|
||||
else if (strncmp(buf, "pci_bus_reset", sizeof("pci_bus_reset") - 1)
|
||||
== 0)
|
||||
status = lpfc_reset_pci_bus(phba);
|
||||
else if (strncmp(buf, "heartbeat", sizeof("heartbeat") - 1) == 0)
|
||||
lpfc_issue_hb_tmo(phba);
|
||||
else if (strncmp(buf, "trunk", sizeof("trunk") - 1) == 0)
|
||||
status = lpfc_set_trunking(phba, (char *)buf + sizeof("trunk"));
|
||||
else
|
||||
@ -3441,11 +3443,8 @@ unsigned long lpfc_no_hba_reset[MAX_HBAS_NO_RESET] = {
|
||||
module_param_array(lpfc_no_hba_reset, ulong, &lpfc_no_hba_reset_cnt, 0444);
|
||||
MODULE_PARM_DESC(lpfc_no_hba_reset, "WWPN of HBAs that should not be reset");
|
||||
|
||||
LPFC_ATTR(sli_mode, 0, 0, 3,
|
||||
"SLI mode selector:"
|
||||
" 0 - auto (SLI-3 if supported),"
|
||||
" 2 - select SLI-2 even on SLI-3 capable HBAs,"
|
||||
" 3 - select SLI-3");
|
||||
LPFC_ATTR(sli_mode, 3, 3, 3,
|
||||
"SLI mode selector: 3 - select SLI-3");
|
||||
|
||||
LPFC_ATTR_R(enable_npiv, 1, 0, 1,
|
||||
"Enable NPIV functionality");
|
||||
|
@ -5376,9 +5376,9 @@ lpfc_check_fwlog_support(struct lpfc_hba *phba)
|
||||
|
||||
ras_fwlog = &phba->ras_fwlog;
|
||||
|
||||
if (ras_fwlog->ras_hwsupport == false)
|
||||
if (!ras_fwlog->ras_hwsupport)
|
||||
return -EACCES;
|
||||
else if (ras_fwlog->ras_enabled == false)
|
||||
else if (!ras_fwlog->ras_enabled)
|
||||
return -EPERM;
|
||||
else
|
||||
return 0;
|
||||
|
@ -255,7 +255,6 @@ void lpfc_nvmet_ctxbuf_post(struct lpfc_hba *phba,
|
||||
int lpfc_nvmet_rcv_unsol_abort(struct lpfc_vport *vport,
|
||||
struct fc_frame_header *fc_hdr);
|
||||
void lpfc_nvmet_wqfull_process(struct lpfc_hba *phba, struct lpfc_queue *wq);
|
||||
void lpfc_sli_flush_nvme_rings(struct lpfc_hba *phba);
|
||||
void lpfc_nvme_wait_for_io_drain(struct lpfc_hba *phba);
|
||||
void lpfc_sli4_build_dflt_fcf_record(struct lpfc_hba *, struct fcf_record *,
|
||||
uint16_t);
|
||||
@ -360,6 +359,8 @@ lpfc_sli_abort_taskmgmt(struct lpfc_vport *, struct lpfc_sli_ring *,
|
||||
|
||||
void lpfc_mbox_timeout(struct timer_list *t);
|
||||
void lpfc_mbox_timeout_handler(struct lpfc_hba *);
|
||||
int lpfc_issue_hb_mbox(struct lpfc_hba *phba);
|
||||
void lpfc_issue_hb_tmo(struct lpfc_hba *phba);
|
||||
|
||||
struct lpfc_nodelist *lpfc_findnode_did(struct lpfc_vport *, uint32_t);
|
||||
struct lpfc_nodelist *lpfc_findnode_wwpn(struct lpfc_vport *,
|
||||
@ -598,7 +599,8 @@ void lpfc_release_io_buf(struct lpfc_hba *phba, struct lpfc_io_buf *ncmd,
|
||||
void lpfc_io_ktime(struct lpfc_hba *phba, struct lpfc_io_buf *ncmd);
|
||||
void lpfc_wqe_cmd_template(void);
|
||||
void lpfc_nvmet_cmd_template(void);
|
||||
void lpfc_nvme_cancel_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *pwqeIn);
|
||||
void lpfc_nvme_cancel_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *pwqeIn,
|
||||
uint32_t stat, uint32_t param);
|
||||
extern int lpfc_enable_nvmet_cnt;
|
||||
extern unsigned long long lpfc_enable_nvmet[];
|
||||
extern int lpfc_no_hba_reset_cnt;
|
||||
|
@ -77,6 +77,13 @@ struct lpfc_node_rrqs {
|
||||
unsigned long xri_bitmap[XRI_BITMAP_ULONGS];
|
||||
};
|
||||
|
||||
enum lpfc_fc4_xpt_flags {
|
||||
NLP_WAIT_FOR_UNREG = 0x1,
|
||||
SCSI_XPT_REGD = 0x2,
|
||||
NVME_XPT_REGD = 0x4,
|
||||
NLP_XPT_HAS_HH = 0x8,
|
||||
};
|
||||
|
||||
struct lpfc_nodelist {
|
||||
struct list_head nlp_listp;
|
||||
struct lpfc_name nlp_portname;
|
||||
@ -134,15 +141,15 @@ struct lpfc_nodelist {
|
||||
unsigned long *active_rrqs_xri_bitmap;
|
||||
struct lpfc_scsicmd_bkt *lat_data; /* Latency data */
|
||||
uint32_t fc4_prli_sent;
|
||||
uint32_t fc4_xpt_flags;
|
||||
#define NLP_WAIT_FOR_UNREG 0x1
|
||||
#define SCSI_XPT_REGD 0x2
|
||||
#define NVME_XPT_REGD 0x4
|
||||
u32 upcall_flags;
|
||||
#define NLP_WAIT_FOR_LOGO 0x2
|
||||
|
||||
enum lpfc_fc4_xpt_flags fc4_xpt_flags;
|
||||
|
||||
uint32_t nvme_fb_size; /* NVME target's supported byte cnt */
|
||||
#define NVME_FB_BIT_SHIFT 9 /* PRLI Rsp first burst in 512B units. */
|
||||
uint32_t nlp_defer_did;
|
||||
wait_queue_head_t *logo_waitq;
|
||||
};
|
||||
|
||||
struct lpfc_node_rrq {
|
||||
|
@ -732,7 +732,7 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
||||
spin_unlock_irq(&phba->hbalock);
|
||||
} else {
|
||||
/* Because we asked f/w for NPIV it still expects us
|
||||
to call reg_vnpid atleast for the physcial host */
|
||||
to call reg_vnpid at least for the physical host */
|
||||
lpfc_printf_vlog(vport, KERN_WARNING,
|
||||
LOG_ELS | LOG_VPORT,
|
||||
"1817 Fabric does not support NPIV "
|
||||
@ -1428,6 +1428,9 @@ lpfc_els_abort_flogi(struct lpfc_hba *phba)
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
/* Make sure HBA is alive */
|
||||
lpfc_issue_hb_tmo(phba);
|
||||
|
||||
spin_unlock_irq(&phba->hbalock);
|
||||
|
||||
return 0;
|
||||
@ -2815,9 +2818,9 @@ lpfc_cmpl_els_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) cmdiocb->context1;
|
||||
struct lpfc_vport *vport = ndlp->vport;
|
||||
IOCB_t *irsp;
|
||||
struct lpfcMboxq *mbox;
|
||||
unsigned long flags;
|
||||
uint32_t skip_recovery = 0;
|
||||
int wake_up_waiter = 0;
|
||||
|
||||
/* we pass cmdiocb to state machine which needs rspiocb as well */
|
||||
cmdiocb->context_un.rsp_iocb = rspiocb;
|
||||
@ -2825,6 +2828,10 @@ lpfc_cmpl_els_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
irsp = &(rspiocb->iocb);
|
||||
spin_lock_irq(&ndlp->lock);
|
||||
ndlp->nlp_flag &= ~NLP_LOGO_SND;
|
||||
if (ndlp->upcall_flags & NLP_WAIT_FOR_LOGO) {
|
||||
wake_up_waiter = 1;
|
||||
ndlp->upcall_flags &= ~NLP_WAIT_FOR_LOGO;
|
||||
}
|
||||
spin_unlock_irq(&ndlp->lock);
|
||||
|
||||
lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
|
||||
@ -2884,32 +2891,14 @@ lpfc_cmpl_els_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||
lpfc_els_free_iocb(phba, cmdiocb);
|
||||
lpfc_nlp_put(ndlp);
|
||||
|
||||
/* If we are in pt2pt mode, we could rcv new S_ID on PLOGI */
|
||||
if ((vport->fc_flag & FC_PT2PT) &&
|
||||
!(vport->fc_flag & FC_PT2PT_PLOGI)) {
|
||||
phba->pport->fc_myDID = 0;
|
||||
|
||||
if ((vport->cfg_enable_fc4_type == LPFC_ENABLE_BOTH) ||
|
||||
(vport->cfg_enable_fc4_type == LPFC_ENABLE_NVME)) {
|
||||
if (phba->nvmet_support)
|
||||
lpfc_nvmet_update_targetport(phba);
|
||||
else
|
||||
lpfc_nvme_update_localport(phba->pport);
|
||||
}
|
||||
|
||||
mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
|
||||
if (mbox) {
|
||||
lpfc_config_link(phba, mbox);
|
||||
mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
|
||||
mbox->vport = vport;
|
||||
if (lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT) ==
|
||||
MBX_NOT_FINISHED) {
|
||||
mempool_free(mbox, phba->mbox_mem_pool);
|
||||
skip_recovery = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* At this point, the LOGO processing is complete. NOTE: For a
|
||||
* pt2pt topology, we are assuming the NPortID will only change
|
||||
* on link up processing. For a LOGO / PLOGI initiated by the
|
||||
* Initiator, we are assuming the NPortID is not going to change.
|
||||
*/
|
||||
|
||||
if (wake_up_waiter && ndlp->logo_waitq)
|
||||
wake_up(ndlp->logo_waitq);
|
||||
/*
|
||||
* If the node is a target, the handling attempts to recover the port.
|
||||
* For any other port type, the rpi is unregistered as an implicit
|
||||
@ -8141,6 +8130,9 @@ lpfc_els_timeout_handler(struct lpfc_vport *vport)
|
||||
spin_unlock_irq(&phba->hbalock);
|
||||
}
|
||||
|
||||
/* Make sure HBA is alive */
|
||||
lpfc_issue_hb_tmo(phba);
|
||||
|
||||
if (!list_empty(&pring->txcmplq))
|
||||
if (!(phba->pport->load_flag & FC_UNLOADING))
|
||||
mod_timer(&vport->els_tmofunc,
|
||||
@ -8240,6 +8232,9 @@ lpfc_els_flush_cmd(struct lpfc_vport *vport)
|
||||
lpfc_sli_issue_abort_iotag(phba, pring, piocb, NULL);
|
||||
spin_unlock_irqrestore(&phba->hbalock, iflags);
|
||||
}
|
||||
/* Make sure HBA is alive */
|
||||
lpfc_issue_hb_tmo(phba);
|
||||
|
||||
if (!list_empty(&abort_list))
|
||||
lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
|
||||
"3387 abort list for txq not empty\n");
|
||||
|
@ -73,6 +73,16 @@ static void lpfc_unregister_fcfi_cmpl(struct lpfc_hba *, LPFC_MBOXQ_t *);
|
||||
static int lpfc_fcf_inuse(struct lpfc_hba *);
|
||||
static void lpfc_mbx_cmpl_read_sparam(struct lpfc_hba *, LPFC_MBOXQ_t *);
|
||||
|
||||
static int
|
||||
lpfc_valid_xpt_node(struct lpfc_nodelist *ndlp)
|
||||
{
|
||||
if (ndlp->nlp_fc4_type ||
|
||||
ndlp->nlp_DID == Fabric_DID ||
|
||||
ndlp->nlp_DID == NameServer_DID ||
|
||||
ndlp->nlp_DID == FDMI_DID)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
/* The source of a terminate rport I/O is either a dev_loss_tmo
|
||||
* event or a call to fc_remove_host. While the rport should be
|
||||
* valid during these downcalls, the transport can call twice
|
||||
@ -1145,13 +1155,14 @@ lpfc_mbx_cmpl_local_config_link(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
|
||||
struct lpfc_vport *vport = pmb->vport;
|
||||
LPFC_MBOXQ_t *sparam_mb;
|
||||
struct lpfc_dmabuf *sparam_mp;
|
||||
u16 status = pmb->u.mb.mbxStatus;
|
||||
int rc;
|
||||
|
||||
if (pmb->u.mb.mbxStatus)
|
||||
goto out;
|
||||
|
||||
mempool_free(pmb, phba->mbox_mem_pool);
|
||||
|
||||
if (status)
|
||||
goto out;
|
||||
|
||||
/* don't perform discovery for SLI4 loopback diagnostic test */
|
||||
if ((phba->sli_rev == LPFC_SLI_REV4) &&
|
||||
!(phba->hba_flag & HBA_FCOE_MODE) &&
|
||||
@ -1214,12 +1225,10 @@ lpfc_mbx_cmpl_local_config_link(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
|
||||
|
||||
out:
|
||||
lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
|
||||
"0306 CONFIG_LINK mbxStatus error x%x "
|
||||
"HBA state x%x\n",
|
||||
pmb->u.mb.mbxStatus, vport->port_state);
|
||||
sparam_out:
|
||||
mempool_free(pmb, phba->mbox_mem_pool);
|
||||
"0306 CONFIG_LINK mbxStatus error x%x HBA state x%x\n",
|
||||
status, vport->port_state);
|
||||
|
||||
sparam_out:
|
||||
lpfc_linkdown(phba);
|
||||
|
||||
lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
|
||||
@ -4318,7 +4327,8 @@ lpfc_nlp_state_cleanup(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
||||
/* FCP and NVME Transport interface */
|
||||
if ((old_state == NLP_STE_MAPPED_NODE ||
|
||||
old_state == NLP_STE_UNMAPPED_NODE)) {
|
||||
if (ndlp->rport) {
|
||||
if (ndlp->rport &&
|
||||
lpfc_valid_xpt_node(ndlp)) {
|
||||
vport->phba->nport_event_cnt++;
|
||||
lpfc_unregister_remote_port(ndlp);
|
||||
}
|
||||
@ -4340,10 +4350,7 @@ lpfc_nlp_state_cleanup(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
||||
|
||||
if (new_state == NLP_STE_MAPPED_NODE ||
|
||||
new_state == NLP_STE_UNMAPPED_NODE) {
|
||||
if (ndlp->nlp_fc4_type ||
|
||||
ndlp->nlp_DID == Fabric_DID ||
|
||||
ndlp->nlp_DID == NameServer_DID ||
|
||||
ndlp->nlp_DID == FDMI_DID) {
|
||||
if (lpfc_valid_xpt_node(ndlp)) {
|
||||
vport->phba->nport_event_cnt++;
|
||||
/*
|
||||
* Tell the fc transport about the port, if we haven't
|
||||
@ -5611,6 +5618,9 @@ lpfc_free_tx(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
|
||||
}
|
||||
spin_unlock_irq(&phba->hbalock);
|
||||
|
||||
/* Make sure HBA is alive */
|
||||
lpfc_issue_hb_tmo(phba);
|
||||
|
||||
/* Cancel all the IOCBs from the completions list */
|
||||
lpfc_sli_cancel_iocbs(phba, &completions, IOSTAT_LOCAL_REJECT,
|
||||
IOERR_SLI_ABORTED);
|
||||
|
@ -591,7 +591,7 @@ lpfc_config_port_post(struct lpfc_hba *phba)
|
||||
/* Set up heart beat (HB) timer */
|
||||
mod_timer(&phba->hb_tmofunc,
|
||||
jiffies + msecs_to_jiffies(1000 * LPFC_HB_MBOX_INTERVAL));
|
||||
phba->hb_outstanding = 0;
|
||||
phba->hba_flag &= ~(HBA_HBEAT_INP | HBA_HBEAT_TMO);
|
||||
phba->last_completion_time = jiffies;
|
||||
/* Set up error attention (ERATT) polling timer */
|
||||
mod_timer(&phba->eratt_poll,
|
||||
@ -1204,10 +1204,10 @@ lpfc_hb_mbox_cmpl(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq)
|
||||
unsigned long drvr_flag;
|
||||
|
||||
spin_lock_irqsave(&phba->hbalock, drvr_flag);
|
||||
phba->hb_outstanding = 0;
|
||||
phba->hba_flag &= ~(HBA_HBEAT_INP | HBA_HBEAT_TMO);
|
||||
spin_unlock_irqrestore(&phba->hbalock, drvr_flag);
|
||||
|
||||
/* Check and reset heart-beat timer is necessary */
|
||||
/* Check and reset heart-beat timer if necessary */
|
||||
mempool_free(pmboxq, phba->mbox_mem_pool);
|
||||
if (!(phba->pport->fc_flag & FC_OFFLINE_MODE) &&
|
||||
!(phba->link_state == LPFC_HBA_ERROR) &&
|
||||
@ -1380,6 +1380,60 @@ static void lpfc_hb_mxp_handler(struct lpfc_hba *phba)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* lpfc_issue_hb_mbox - Issues heart-beat mailbox command
|
||||
* @phba: pointer to lpfc hba data structure.
|
||||
*
|
||||
* If a HB mbox is not already in progrees, this routine will allocate
|
||||
* a LPFC_MBOXQ_t, populate it with a MBX_HEARTBEAT (0x31) command,
|
||||
* and issue it. The HBA_HBEAT_INP flag means the command is in progress.
|
||||
**/
|
||||
int
|
||||
lpfc_issue_hb_mbox(struct lpfc_hba *phba)
|
||||
{
|
||||
LPFC_MBOXQ_t *pmboxq;
|
||||
int retval;
|
||||
|
||||
/* Is a Heartbeat mbox already in progress */
|
||||
if (phba->hba_flag & HBA_HBEAT_INP)
|
||||
return 0;
|
||||
|
||||
pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
|
||||
if (!pmboxq)
|
||||
return -ENOMEM;
|
||||
|
||||
lpfc_heart_beat(phba, pmboxq);
|
||||
pmboxq->mbox_cmpl = lpfc_hb_mbox_cmpl;
|
||||
pmboxq->vport = phba->pport;
|
||||
retval = lpfc_sli_issue_mbox(phba, pmboxq, MBX_NOWAIT);
|
||||
|
||||
if (retval != MBX_BUSY && retval != MBX_SUCCESS) {
|
||||
mempool_free(pmboxq, phba->mbox_mem_pool);
|
||||
return -ENXIO;
|
||||
}
|
||||
phba->hba_flag |= HBA_HBEAT_INP;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* lpfc_issue_hb_tmo - Signals heartbeat timer to issue mbox command
|
||||
* @phba: pointer to lpfc hba data structure.
|
||||
*
|
||||
* The heartbeat timer (every 5 sec) will fire. If the HBA_HBEAT_TMO
|
||||
* flag is set, it will force a MBX_HEARTBEAT mbox command, regardless
|
||||
* of the value of lpfc_enable_hba_heartbeat.
|
||||
* If lpfc_enable_hba_heartbeat is set, the timeout routine will always
|
||||
* try to issue a MBX_HEARTBEAT mbox command.
|
||||
**/
|
||||
void
|
||||
lpfc_issue_hb_tmo(struct lpfc_hba *phba)
|
||||
{
|
||||
if (phba->cfg_enable_hba_heartbeat)
|
||||
return;
|
||||
phba->hba_flag |= HBA_HBEAT_TMO;
|
||||
}
|
||||
|
||||
/**
|
||||
* lpfc_hb_timeout_handler - The HBA-timer timeout handler
|
||||
* @phba: pointer to lpfc hba data structure.
|
||||
@ -1400,9 +1454,9 @@ void
|
||||
lpfc_hb_timeout_handler(struct lpfc_hba *phba)
|
||||
{
|
||||
struct lpfc_vport **vports;
|
||||
LPFC_MBOXQ_t *pmboxq;
|
||||
struct lpfc_dmabuf *buf_ptr;
|
||||
int retval, i;
|
||||
int retval = 0;
|
||||
int i, tmo;
|
||||
struct lpfc_sli *psli = &phba->sli;
|
||||
LIST_HEAD(completions);
|
||||
|
||||
@ -1424,24 +1478,6 @@ lpfc_hb_timeout_handler(struct lpfc_hba *phba)
|
||||
(phba->pport->fc_flag & FC_OFFLINE_MODE))
|
||||
return;
|
||||
|
||||
spin_lock_irq(&phba->pport->work_port_lock);
|
||||
|
||||
if (time_after(phba->last_completion_time +
|
||||
msecs_to_jiffies(1000 * LPFC_HB_MBOX_INTERVAL),
|
||||
jiffies)) {
|
||||
spin_unlock_irq(&phba->pport->work_port_lock);
|
||||
if (!phba->hb_outstanding)
|
||||
mod_timer(&phba->hb_tmofunc,
|
||||
jiffies +
|
||||
msecs_to_jiffies(1000 * LPFC_HB_MBOX_INTERVAL));
|
||||
else
|
||||
mod_timer(&phba->hb_tmofunc,
|
||||
jiffies +
|
||||
msecs_to_jiffies(1000 * LPFC_HB_MBOX_TIMEOUT));
|
||||
return;
|
||||
}
|
||||
spin_unlock_irq(&phba->pport->work_port_lock);
|
||||
|
||||
if (phba->elsbuf_cnt &&
|
||||
(phba->elsbuf_cnt == phba->elsbuf_prev_cnt)) {
|
||||
spin_lock_irq(&phba->hbalock);
|
||||
@ -1461,37 +1497,43 @@ lpfc_hb_timeout_handler(struct lpfc_hba *phba)
|
||||
|
||||
/* If there is no heart beat outstanding, issue a heartbeat command */
|
||||
if (phba->cfg_enable_hba_heartbeat) {
|
||||
if (!phba->hb_outstanding) {
|
||||
/* If IOs are completing, no need to issue a MBX_HEARTBEAT */
|
||||
spin_lock_irq(&phba->pport->work_port_lock);
|
||||
if (time_after(phba->last_completion_time +
|
||||
msecs_to_jiffies(1000 * LPFC_HB_MBOX_INTERVAL),
|
||||
jiffies)) {
|
||||
spin_unlock_irq(&phba->pport->work_port_lock);
|
||||
if (phba->hba_flag & HBA_HBEAT_INP)
|
||||
tmo = (1000 * LPFC_HB_MBOX_TIMEOUT);
|
||||
else
|
||||
tmo = (1000 * LPFC_HB_MBOX_INTERVAL);
|
||||
goto out;
|
||||
}
|
||||
spin_unlock_irq(&phba->pport->work_port_lock);
|
||||
|
||||
/* Check if a MBX_HEARTBEAT is already in progress */
|
||||
if (phba->hba_flag & HBA_HBEAT_INP) {
|
||||
/*
|
||||
* If heart beat timeout called with HBA_HBEAT_INP set
|
||||
* we need to give the hb mailbox cmd a chance to
|
||||
* complete or TMO.
|
||||
*/
|
||||
lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
|
||||
"0459 Adapter heartbeat still outstanding: "
|
||||
"last compl time was %d ms.\n",
|
||||
jiffies_to_msecs(jiffies
|
||||
- phba->last_completion_time));
|
||||
tmo = (1000 * LPFC_HB_MBOX_TIMEOUT);
|
||||
} else {
|
||||
if ((!(psli->sli_flag & LPFC_SLI_MBOX_ACTIVE)) &&
|
||||
(list_empty(&psli->mboxq))) {
|
||||
pmboxq = mempool_alloc(phba->mbox_mem_pool,
|
||||
GFP_KERNEL);
|
||||
if (!pmboxq) {
|
||||
mod_timer(&phba->hb_tmofunc,
|
||||
jiffies +
|
||||
msecs_to_jiffies(1000 *
|
||||
LPFC_HB_MBOX_INTERVAL));
|
||||
return;
|
||||
}
|
||||
|
||||
lpfc_heart_beat(phba, pmboxq);
|
||||
pmboxq->mbox_cmpl = lpfc_hb_mbox_cmpl;
|
||||
pmboxq->vport = phba->pport;
|
||||
retval = lpfc_sli_issue_mbox(phba, pmboxq,
|
||||
MBX_NOWAIT);
|
||||
|
||||
if (retval != MBX_BUSY &&
|
||||
retval != MBX_SUCCESS) {
|
||||
mempool_free(pmboxq,
|
||||
phba->mbox_mem_pool);
|
||||
mod_timer(&phba->hb_tmofunc,
|
||||
jiffies +
|
||||
msecs_to_jiffies(1000 *
|
||||
LPFC_HB_MBOX_INTERVAL));
|
||||
return;
|
||||
retval = lpfc_issue_hb_mbox(phba);
|
||||
if (retval) {
|
||||
tmo = (1000 * LPFC_HB_MBOX_INTERVAL);
|
||||
goto out;
|
||||
}
|
||||
phba->skipped_hb = 0;
|
||||
phba->hb_outstanding = 1;
|
||||
} else if (time_before_eq(phba->last_completion_time,
|
||||
phba->skipped_hb)) {
|
||||
lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
|
||||
@ -1502,30 +1544,23 @@ lpfc_hb_timeout_handler(struct lpfc_hba *phba)
|
||||
} else
|
||||
phba->skipped_hb = jiffies;
|
||||
|
||||
mod_timer(&phba->hb_tmofunc,
|
||||
jiffies +
|
||||
msecs_to_jiffies(1000 * LPFC_HB_MBOX_TIMEOUT));
|
||||
return;
|
||||
} else {
|
||||
/*
|
||||
* If heart beat timeout called with hb_outstanding set
|
||||
* we need to give the hb mailbox cmd a chance to
|
||||
* complete or TMO.
|
||||
*/
|
||||
lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
|
||||
"0459 Adapter heartbeat still out"
|
||||
"standing:last compl time was %d ms.\n",
|
||||
jiffies_to_msecs(jiffies
|
||||
- phba->last_completion_time));
|
||||
mod_timer(&phba->hb_tmofunc,
|
||||
jiffies +
|
||||
msecs_to_jiffies(1000 * LPFC_HB_MBOX_TIMEOUT));
|
||||
tmo = (1000 * LPFC_HB_MBOX_TIMEOUT);
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
mod_timer(&phba->hb_tmofunc,
|
||||
jiffies +
|
||||
msecs_to_jiffies(1000 * LPFC_HB_MBOX_INTERVAL));
|
||||
/* Check to see if we want to force a MBX_HEARTBEAT */
|
||||
if (phba->hba_flag & HBA_HBEAT_TMO) {
|
||||
retval = lpfc_issue_hb_mbox(phba);
|
||||
if (retval)
|
||||
tmo = (1000 * LPFC_HB_MBOX_INTERVAL);
|
||||
else
|
||||
tmo = (1000 * LPFC_HB_MBOX_TIMEOUT);
|
||||
goto out;
|
||||
}
|
||||
tmo = (1000 * LPFC_HB_MBOX_INTERVAL);
|
||||
}
|
||||
out:
|
||||
mod_timer(&phba->hb_tmofunc, jiffies + msecs_to_jiffies(tmo));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1830,9 +1865,19 @@ lpfc_sli4_port_sta_fn_reset(struct lpfc_hba *phba, int mbx_action,
|
||||
|
||||
/* need reset: attempt for port recovery */
|
||||
if (en_rn_msg)
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
|
||||
"2887 Reset Needed: Attempting Port "
|
||||
"Recovery...\n");
|
||||
|
||||
/* If we are no wait, the HBA has been reset and is not
|
||||
* functional, thus we should clear LPFC_SLI_ACTIVE flag.
|
||||
*/
|
||||
if (mbx_action == LPFC_MBX_NO_WAIT) {
|
||||
spin_lock_irq(&phba->hbalock);
|
||||
phba->sli.sli_flag &= ~LPFC_SLI_ACTIVE;
|
||||
spin_unlock_irq(&phba->hbalock);
|
||||
}
|
||||
|
||||
lpfc_offline_prep(phba, mbx_action);
|
||||
lpfc_sli_flush_io_rings(phba);
|
||||
lpfc_offline(phba);
|
||||
@ -2979,7 +3024,7 @@ lpfc_stop_hba_timers(struct lpfc_hba *phba)
|
||||
del_timer_sync(&phba->rrq_tmr);
|
||||
phba->hba_flag &= ~HBA_RRQ_ACTIVE;
|
||||
}
|
||||
phba->hb_outstanding = 0;
|
||||
phba->hba_flag &= ~(HBA_HBEAT_INP | HBA_HBEAT_TMO);
|
||||
|
||||
switch (phba->pci_dev_grp) {
|
||||
case LPFC_PCI_DEV_LP:
|
||||
@ -3592,7 +3637,11 @@ lpfc_offline(struct lpfc_hba *phba)
|
||||
spin_unlock_irq(shost->host_lock);
|
||||
}
|
||||
lpfc_destroy_vport_work_array(phba, vports);
|
||||
__lpfc_cpuhp_remove(phba);
|
||||
/* If OFFLINE flag is clear (i.e. unloading), cpuhp removal is handled
|
||||
* in hba_unset
|
||||
*/
|
||||
if (phba->pport->fc_flag & FC_OFFLINE_MODE)
|
||||
__lpfc_cpuhp_remove(phba);
|
||||
|
||||
if (phba->cfg_xri_rebalancing)
|
||||
lpfc_destroy_multixri_pools(phba);
|
||||
@ -6177,10 +6226,14 @@ lpfc_reset_hba(struct lpfc_hba *phba)
|
||||
phba->link_state = LPFC_HBA_ERROR;
|
||||
return;
|
||||
}
|
||||
if (phba->sli.sli_flag & LPFC_SLI_ACTIVE)
|
||||
|
||||
/* If not LPFC_SLI_ACTIVE, force all IO to be flushed */
|
||||
if (phba->sli.sli_flag & LPFC_SLI_ACTIVE) {
|
||||
lpfc_offline_prep(phba, LPFC_MBX_WAIT);
|
||||
else
|
||||
} else {
|
||||
lpfc_offline_prep(phba, LPFC_MBX_NO_WAIT);
|
||||
lpfc_sli_flush_io_rings(phba);
|
||||
}
|
||||
lpfc_offline(phba);
|
||||
lpfc_sli_brdrestart(phba);
|
||||
lpfc_online(phba);
|
||||
@ -10728,17 +10781,19 @@ lpfc_sli_enable_intr(struct lpfc_hba *phba, uint32_t cfg_mode)
|
||||
uint32_t intr_mode = LPFC_INTR_ERROR;
|
||||
int retval;
|
||||
|
||||
/* Need to issue conf_port mbox cmd before conf_msi mbox cmd */
|
||||
retval = lpfc_sli_config_port(phba, LPFC_SLI_REV3);
|
||||
if (retval)
|
||||
return intr_mode;
|
||||
phba->hba_flag &= ~HBA_NEEDS_CFG_PORT;
|
||||
|
||||
if (cfg_mode == 2) {
|
||||
/* Need to issue conf_port mbox cmd before conf_msi mbox cmd */
|
||||
retval = lpfc_sli_config_port(phba, LPFC_SLI_REV3);
|
||||
/* Now, try to enable MSI-X interrupt mode */
|
||||
retval = lpfc_sli_enable_msix(phba);
|
||||
if (!retval) {
|
||||
/* Now, try to enable MSI-X interrupt mode */
|
||||
retval = lpfc_sli_enable_msix(phba);
|
||||
if (!retval) {
|
||||
/* Indicate initialization to MSI-X mode */
|
||||
phba->intr_type = MSIX;
|
||||
intr_mode = 2;
|
||||
}
|
||||
/* Indicate initialization to MSI-X mode */
|
||||
phba->intr_type = MSIX;
|
||||
intr_mode = 2;
|
||||
}
|
||||
}
|
||||
|
||||
@ -14122,15 +14177,32 @@ void lpfc_dmp_dbg(struct lpfc_hba *phba)
|
||||
int i;
|
||||
int j = 0;
|
||||
unsigned long rem_nsec;
|
||||
struct lpfc_vport **vports;
|
||||
|
||||
/* Don't dump messages if we explicitly set log_verbose for the
|
||||
* physical port or any vport.
|
||||
*/
|
||||
if (phba->cfg_log_verbose)
|
||||
return;
|
||||
|
||||
vports = lpfc_create_vport_work_array(phba);
|
||||
if (vports != NULL) {
|
||||
for (i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) {
|
||||
if (vports[i]->cfg_log_verbose) {
|
||||
lpfc_destroy_vport_work_array(phba, vports);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
lpfc_destroy_vport_work_array(phba, vports);
|
||||
|
||||
if (atomic_cmpxchg(&phba->dbg_log_dmping, 0, 1) != 0)
|
||||
return;
|
||||
|
||||
start_idx = (unsigned int)atomic_read(&phba->dbg_log_idx) % DBG_LOG_SZ;
|
||||
dbg_cnt = (unsigned int)atomic_read(&phba->dbg_log_cnt);
|
||||
if (!dbg_cnt)
|
||||
goto out;
|
||||
temp_idx = start_idx;
|
||||
if (dbg_cnt >= DBG_LOG_SZ) {
|
||||
dbg_cnt = DBG_LOG_SZ;
|
||||
@ -14160,6 +14232,7 @@ void lpfc_dmp_dbg(struct lpfc_hba *phba)
|
||||
rem_nsec / 1000,
|
||||
phba->dbg_log[temp_idx].log);
|
||||
}
|
||||
out:
|
||||
atomic_set(&phba->dbg_log_cnt, 0);
|
||||
atomic_set(&phba->dbg_log_dmping, 0);
|
||||
}
|
||||
|
@ -2409,7 +2409,7 @@ lpfc_mbx_cmpl_rdp_page_a0(struct lpfc_hba *phba, LPFC_MBOXQ_t *mbox)
|
||||
|
||||
|
||||
/*
|
||||
* lpfc_sli4_dump_sfp_pagea0 - Dump sli4 read SFP Diagnostic.
|
||||
* lpfc_sli4_dump_page_a0 - Dump sli4 read SFP Diagnostic.
|
||||
* @phba: pointer to the hba structure containing.
|
||||
* @mbox: pointer to lpfc mbox command to initialize.
|
||||
*
|
||||
|
@ -250,6 +250,8 @@ lpfc_els_abort(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
|
||||
lpfc_sli_issue_abort_iotag(phba, pring, iocb, NULL);
|
||||
spin_unlock_irq(&phba->hbalock);
|
||||
}
|
||||
/* Make sure HBA is alive */
|
||||
lpfc_issue_hb_tmo(phba);
|
||||
|
||||
INIT_LIST_HEAD(&abort_list);
|
||||
|
||||
@ -471,6 +473,15 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
||||
*/
|
||||
if (!(ndlp->nlp_type & NLP_FABRIC) &&
|
||||
!(phba->nvmet_support)) {
|
||||
/* Clear ndlp info, since follow up PRLI may have
|
||||
* updated ndlp information
|
||||
*/
|
||||
ndlp->nlp_type &= ~(NLP_FCP_TARGET | NLP_FCP_INITIATOR);
|
||||
ndlp->nlp_type &= ~(NLP_NVME_TARGET | NLP_NVME_INITIATOR);
|
||||
ndlp->nlp_fcp_info &= ~NLP_FCP_2_DEVICE;
|
||||
ndlp->nlp_nvme_info &= ~NLP_NVME_NSLER;
|
||||
ndlp->nlp_flag &= ~NLP_FIRSTBURST;
|
||||
|
||||
lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb,
|
||||
ndlp, NULL);
|
||||
return 1;
|
||||
@ -499,6 +510,7 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
||||
ndlp->nlp_type &= ~(NLP_FCP_TARGET | NLP_FCP_INITIATOR);
|
||||
ndlp->nlp_type &= ~(NLP_NVME_TARGET | NLP_NVME_INITIATOR);
|
||||
ndlp->nlp_fcp_info &= ~NLP_FCP_2_DEVICE;
|
||||
ndlp->nlp_nvme_info &= ~NLP_NVME_NSLER;
|
||||
ndlp->nlp_flag &= ~NLP_FIRSTBURST;
|
||||
|
||||
login_mbox = NULL;
|
||||
@ -1011,7 +1023,12 @@ lpfc_rcv_prli(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
||||
ndlp->nlp_fc4_type |= NLP_FC4_NVME;
|
||||
lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
|
||||
}
|
||||
if (npr->prliType == PRLI_FCP_TYPE)
|
||||
|
||||
/* Fabric Controllers send FCP PRLI as an initiator but should
|
||||
* not get recognized as FCP type and registered with transport.
|
||||
*/
|
||||
if (npr->prliType == PRLI_FCP_TYPE &&
|
||||
!(ndlp->nlp_type & NLP_FABRIC))
|
||||
ndlp->nlp_fc4_type |= NLP_FC4_FCP;
|
||||
}
|
||||
if (rport) {
|
||||
@ -2034,6 +2051,7 @@ lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_vport *vport,
|
||||
* must complete PRLI.
|
||||
*/
|
||||
if (ndlp->nlp_type & NLP_FABRIC) {
|
||||
ndlp->nlp_fc4_type &= ~NLP_FC4_FCP;
|
||||
ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE;
|
||||
lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
|
||||
}
|
||||
@ -2107,6 +2125,7 @@ lpfc_rcv_prli_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
||||
|
||||
if (!lpfc_rcv_prli_support_check(vport, ndlp, cmdiocb))
|
||||
return ndlp->nlp_state;
|
||||
lpfc_rcv_prli(vport, ndlp, cmdiocb);
|
||||
lpfc_els_rsp_prli_acc(vport, cmdiocb, ndlp);
|
||||
return ndlp->nlp_state;
|
||||
}
|
||||
|
@ -458,7 +458,7 @@ lpfc_nvme_gen_req(struct lpfc_vport *vport, struct lpfc_dmabuf *bmp,
|
||||
bf_set(wqe_xri_tag, &wqe->gen_req.wqe_com, genwqe->sli4_xritag);
|
||||
|
||||
/* Word 7 */
|
||||
bf_set(wqe_tmo, &wqe->gen_req.wqe_com, (vport->phba->fc_ratov-1));
|
||||
bf_set(wqe_tmo, &wqe->gen_req.wqe_com, tmo);
|
||||
bf_set(wqe_class, &wqe->gen_req.wqe_com, CLASS3);
|
||||
bf_set(wqe_cmnd, &wqe->gen_req.wqe_com, CMD_GEN_REQUEST64_WQE);
|
||||
bf_set(wqe_ct, &wqe->gen_req.wqe_com, SLI4_CT_RPI);
|
||||
@ -618,7 +618,7 @@ __lpfc_nvme_ls_req(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
||||
|
||||
ret = lpfc_nvme_gen_req(vport, bmp, pnvme_lsreq->rqstaddr,
|
||||
pnvme_lsreq, gen_req_cmp, ndlp, 2,
|
||||
LPFC_NVME_LS_TIMEOUT, 0);
|
||||
pnvme_lsreq->timeout, 0);
|
||||
if (ret != WQE_SUCCESS) {
|
||||
lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
|
||||
"6052 NVMEx REQ: EXIT. issue ls wqe failed "
|
||||
@ -1850,6 +1850,10 @@ lpfc_nvme_fcp_abort(struct nvme_fc_local_port *pnvme_lport,
|
||||
|
||||
spin_unlock(&lpfc_nbuf->buf_lock);
|
||||
spin_unlock_irqrestore(&phba->hbalock, flags);
|
||||
|
||||
/* Make sure HBA is alive */
|
||||
lpfc_issue_hb_tmo(phba);
|
||||
|
||||
if (ret_val != WQE_SUCCESS) {
|
||||
lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
|
||||
"6137 Failed abts issue_wqe with status x%x "
|
||||
@ -2596,17 +2600,24 @@ lpfc_nvme_wait_for_io_drain(struct lpfc_hba *phba)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Make sure HBA is alive */
|
||||
lpfc_issue_hb_tmo(phba);
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
lpfc_nvme_cancel_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *pwqeIn)
|
||||
lpfc_nvme_cancel_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *pwqeIn,
|
||||
uint32_t stat, uint32_t param)
|
||||
{
|
||||
#if (IS_ENABLED(CONFIG_NVME_FC))
|
||||
struct lpfc_io_buf *lpfc_ncmd;
|
||||
struct nvmefc_fcp_req *nCmd;
|
||||
struct lpfc_nvme_fcpreq_priv *freqpriv;
|
||||
struct lpfc_wcqe_complete wcqe;
|
||||
struct lpfc_wcqe_complete *wcqep = &wcqe;
|
||||
|
||||
if (!pwqeIn->context1) {
|
||||
lpfc_ncmd = (struct lpfc_io_buf *)pwqeIn->context1;
|
||||
if (!lpfc_ncmd) {
|
||||
lpfc_sli_release_iocbq(phba, pwqeIn);
|
||||
return;
|
||||
}
|
||||
@ -2616,31 +2627,29 @@ lpfc_nvme_cancel_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *pwqeIn)
|
||||
lpfc_sli_release_iocbq(phba, pwqeIn);
|
||||
return;
|
||||
}
|
||||
lpfc_ncmd = (struct lpfc_io_buf *)pwqeIn->context1;
|
||||
|
||||
spin_lock(&lpfc_ncmd->buf_lock);
|
||||
if (!lpfc_ncmd->nvmeCmd) {
|
||||
nCmd = lpfc_ncmd->nvmeCmd;
|
||||
if (!nCmd) {
|
||||
spin_unlock(&lpfc_ncmd->buf_lock);
|
||||
lpfc_release_nvme_buf(phba, lpfc_ncmd);
|
||||
return;
|
||||
}
|
||||
spin_unlock(&lpfc_ncmd->buf_lock);
|
||||
|
||||
nCmd = lpfc_ncmd->nvmeCmd;
|
||||
lpfc_printf_log(phba, KERN_INFO, LOG_NVME_IOERR,
|
||||
"6194 NVME Cancel xri %x\n",
|
||||
lpfc_ncmd->cur_iocbq.sli4_xritag);
|
||||
|
||||
nCmd->transferred_length = 0;
|
||||
nCmd->rcv_rsplen = 0;
|
||||
nCmd->status = NVME_SC_INTERNAL;
|
||||
freqpriv = nCmd->private;
|
||||
freqpriv->nvme_buf = NULL;
|
||||
lpfc_ncmd->nvmeCmd = NULL;
|
||||
|
||||
spin_unlock(&lpfc_ncmd->buf_lock);
|
||||
nCmd->done(nCmd);
|
||||
wcqep->word0 = 0;
|
||||
bf_set(lpfc_wcqe_c_status, wcqep, stat);
|
||||
wcqep->parameter = param;
|
||||
wcqep->word3 = 0; /* xb is 0 */
|
||||
|
||||
/* Call release with XB=1 to queue the IO into the abort list. */
|
||||
lpfc_release_nvme_buf(phba, lpfc_ncmd);
|
||||
if (phba->sli.sli_flag & LPFC_SLI_ACTIVE)
|
||||
bf_set(lpfc_wcqe_c_xb, wcqep, 1);
|
||||
|
||||
(pwqeIn->wqe_cmpl)(phba, pwqeIn, wcqep);
|
||||
#endif
|
||||
}
|
||||
|
@ -1367,17 +1367,22 @@ static void
|
||||
lpfc_nvmet_host_release(void *hosthandle)
|
||||
{
|
||||
struct lpfc_nodelist *ndlp = hosthandle;
|
||||
struct lpfc_hba *phba = NULL;
|
||||
struct lpfc_hba *phba = ndlp->phba;
|
||||
struct lpfc_nvmet_tgtport *tgtp;
|
||||
|
||||
phba = ndlp->phba;
|
||||
if (!phba->targetport || !phba->targetport->private)
|
||||
return;
|
||||
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_NVME,
|
||||
"6202 NVMET XPT releasing hosthandle x%px\n",
|
||||
hosthandle);
|
||||
"6202 NVMET XPT releasing hosthandle x%px "
|
||||
"DID x%x xflags x%x refcnt %d\n",
|
||||
hosthandle, ndlp->nlp_DID, ndlp->fc4_xpt_flags,
|
||||
kref_read(&ndlp->kref));
|
||||
tgtp = (struct lpfc_nvmet_tgtport *)phba->targetport->private;
|
||||
spin_lock_irq(&ndlp->lock);
|
||||
ndlp->fc4_xpt_flags &= ~NLP_XPT_HAS_HH;
|
||||
spin_unlock_irq(&ndlp->lock);
|
||||
lpfc_nlp_put(ndlp);
|
||||
atomic_set(&tgtp->state, 0);
|
||||
}
|
||||
|
||||
@ -3644,15 +3649,33 @@ lpfc_nvme_unsol_ls_issue_abort(struct lpfc_hba *phba,
|
||||
void
|
||||
lpfc_nvmet_invalidate_host(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
|
||||
{
|
||||
u32 ndlp_has_hh;
|
||||
struct lpfc_nvmet_tgtport *tgtp;
|
||||
|
||||
lpfc_printf_log(phba, KERN_INFO, LOG_NVME | LOG_NVME_ABTS,
|
||||
lpfc_printf_log(phba, KERN_INFO,
|
||||
LOG_NVME | LOG_NVME_ABTS | LOG_NVME_DISC,
|
||||
"6203 Invalidating hosthandle x%px\n",
|
||||
ndlp);
|
||||
|
||||
tgtp = (struct lpfc_nvmet_tgtport *)phba->targetport->private;
|
||||
atomic_set(&tgtp->state, LPFC_NVMET_INV_HOST_ACTIVE);
|
||||
|
||||
spin_lock_irq(&ndlp->lock);
|
||||
ndlp_has_hh = ndlp->fc4_xpt_flags & NLP_XPT_HAS_HH;
|
||||
spin_unlock_irq(&ndlp->lock);
|
||||
|
||||
/* Do not invalidate any nodes that do not have a hosthandle.
|
||||
* The host_release callbk will cause a node reference
|
||||
* count imbalance and a crash.
|
||||
*/
|
||||
if (!ndlp_has_hh) {
|
||||
lpfc_printf_log(phba, KERN_INFO,
|
||||
LOG_NVME | LOG_NVME_ABTS | LOG_NVME_DISC,
|
||||
"6204 Skip invalidate on node x%px DID x%x\n",
|
||||
ndlp, ndlp->nlp_DID);
|
||||
return;
|
||||
}
|
||||
|
||||
#if (IS_ENABLED(CONFIG_NVME_TARGET_FC))
|
||||
/* Need to get the nvmet_fc_target_port pointer here.*/
|
||||
nvmet_fc_invalidate_host(phba->targetport, ndlp);
|
||||
|
@ -5479,6 +5479,9 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd)
|
||||
lpfc_sli_abort_fcp_cmpl);
|
||||
}
|
||||
|
||||
/* Make sure HBA is alive */
|
||||
lpfc_issue_hb_tmo(phba);
|
||||
|
||||
if (ret_val != IOCB_SUCCESS) {
|
||||
/* Indicate the IO is not being aborted by the driver. */
|
||||
lpfc_cmd->waitq = NULL;
|
||||
@ -5849,6 +5852,7 @@ lpfc_device_reset_handler(struct scsi_cmnd *cmnd)
|
||||
uint64_t lun_id = cmnd->device->lun;
|
||||
struct lpfc_scsi_event_header scsi_event;
|
||||
int status;
|
||||
u32 logit = LOG_FCP;
|
||||
|
||||
rdata = lpfc_rport_data_from_scsi_device(cmnd->device);
|
||||
if (!rdata || !rdata->pnode) {
|
||||
@ -5880,8 +5884,10 @@ lpfc_device_reset_handler(struct scsi_cmnd *cmnd)
|
||||
|
||||
status = lpfc_send_taskmgmt(vport, cmnd, tgt_id, lun_id,
|
||||
FCP_LUN_RESET);
|
||||
if (status != SUCCESS)
|
||||
logit = LOG_TRACE_EVENT;
|
||||
|
||||
lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
|
||||
lpfc_printf_vlog(vport, KERN_ERR, logit,
|
||||
"0713 SCSI layer issued Device Reset (%d, %llu) "
|
||||
"return x%x\n", tgt_id, lun_id, status);
|
||||
|
||||
@ -5920,6 +5926,9 @@ lpfc_target_reset_handler(struct scsi_cmnd *cmnd)
|
||||
uint64_t lun_id = cmnd->device->lun;
|
||||
struct lpfc_scsi_event_header scsi_event;
|
||||
int status;
|
||||
u32 logit = LOG_FCP;
|
||||
unsigned long flags;
|
||||
DECLARE_WAIT_QUEUE_HEAD_ONSTACK(waitq);
|
||||
|
||||
rdata = lpfc_rport_data_from_scsi_device(cmnd->device);
|
||||
if (!rdata || !rdata->pnode) {
|
||||
@ -5938,10 +5947,10 @@ lpfc_target_reset_handler(struct scsi_cmnd *cmnd)
|
||||
lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
|
||||
"0722 Target Reset rport failure: rdata x%px\n", rdata);
|
||||
if (pnode) {
|
||||
spin_lock_irq(&pnode->lock);
|
||||
spin_lock_irqsave(&pnode->lock, flags);
|
||||
pnode->nlp_flag &= ~NLP_NPR_ADISC;
|
||||
pnode->nlp_fcp_info &= ~NLP_FCP_2_DEVICE;
|
||||
spin_unlock_irq(&pnode->lock);
|
||||
spin_unlock_irqrestore(&pnode->lock, flags);
|
||||
}
|
||||
lpfc_reset_flush_io_context(vport, tgt_id, lun_id,
|
||||
LPFC_CTX_TGT);
|
||||
@ -5959,8 +5968,42 @@ lpfc_target_reset_handler(struct scsi_cmnd *cmnd)
|
||||
|
||||
status = lpfc_send_taskmgmt(vport, cmnd, tgt_id, lun_id,
|
||||
FCP_TARGET_RESET);
|
||||
if (status != SUCCESS)
|
||||
logit = LOG_TRACE_EVENT;
|
||||
spin_lock_irqsave(&pnode->lock, flags);
|
||||
if (status != SUCCESS &&
|
||||
(!(pnode->upcall_flags & NLP_WAIT_FOR_LOGO)) &&
|
||||
!pnode->logo_waitq) {
|
||||
pnode->logo_waitq = &waitq;
|
||||
pnode->nlp_fcp_info &= ~NLP_FCP_2_DEVICE;
|
||||
pnode->nlp_flag |= NLP_ISSUE_LOGO;
|
||||
pnode->upcall_flags |= NLP_WAIT_FOR_LOGO;
|
||||
spin_unlock_irqrestore(&pnode->lock, flags);
|
||||
lpfc_unreg_rpi(vport, pnode);
|
||||
wait_event_timeout(waitq,
|
||||
(!(pnode->upcall_flags & NLP_WAIT_FOR_LOGO)),
|
||||
msecs_to_jiffies(vport->cfg_devloss_tmo *
|
||||
1000));
|
||||
|
||||
lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
|
||||
if (pnode->upcall_flags & NLP_WAIT_FOR_LOGO) {
|
||||
lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
|
||||
"0725 SCSI layer TGTRST failed & LOGO TMO "
|
||||
" (%d, %llu) return x%x\n", tgt_id,
|
||||
lun_id, status);
|
||||
spin_lock_irqsave(&pnode->lock, flags);
|
||||
pnode->upcall_flags &= ~NLP_WAIT_FOR_LOGO;
|
||||
} else {
|
||||
spin_lock_irqsave(&pnode->lock, flags);
|
||||
}
|
||||
pnode->logo_waitq = NULL;
|
||||
spin_unlock_irqrestore(&pnode->lock, flags);
|
||||
status = SUCCESS;
|
||||
} else {
|
||||
status = FAILED;
|
||||
spin_unlock_irqrestore(&pnode->lock, flags);
|
||||
}
|
||||
|
||||
lpfc_printf_vlog(vport, KERN_ERR, logit,
|
||||
"0723 SCSI layer issued Target Reset (%d, %llu) "
|
||||
"return x%x\n", tgt_id, lun_id, status);
|
||||
|
||||
@ -5996,6 +6039,7 @@ lpfc_bus_reset_handler(struct scsi_cmnd *cmnd)
|
||||
struct lpfc_scsi_event_header scsi_event;
|
||||
int match;
|
||||
int ret = SUCCESS, status, i;
|
||||
u32 logit = LOG_FCP;
|
||||
|
||||
scsi_event.event_type = FC_REG_SCSI_EVENT;
|
||||
scsi_event.subcategory = LPFC_EVENT_BUSRESET;
|
||||
@ -6056,8 +6100,10 @@ lpfc_bus_reset_handler(struct scsi_cmnd *cmnd)
|
||||
status = lpfc_reset_flush_io_context(vport, 0, 0, LPFC_CTX_HOST);
|
||||
if (status != SUCCESS)
|
||||
ret = FAILED;
|
||||
if (ret == FAILED)
|
||||
logit = LOG_TRACE_EVENT;
|
||||
|
||||
lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
|
||||
lpfc_printf_vlog(vport, KERN_ERR, logit,
|
||||
"0714 SCSI layer issued Bus Reset Data: x%x\n", ret);
|
||||
return ret;
|
||||
}
|
||||
@ -6086,7 +6132,7 @@ lpfc_host_reset_handler(struct scsi_cmnd *cmnd)
|
||||
struct lpfc_hba *phba = vport->phba;
|
||||
int rc, ret = SUCCESS;
|
||||
|
||||
lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
|
||||
lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP,
|
||||
"3172 SCSI layer issued Host Reset Data:\n");
|
||||
|
||||
lpfc_offline_prep(phba, LPFC_MBX_WAIT);
|
||||
@ -6662,6 +6708,7 @@ struct scsi_host_template lpfc_template = {
|
||||
.info = lpfc_info,
|
||||
.queuecommand = lpfc_queuecommand,
|
||||
.eh_timed_out = fc_eh_timed_out,
|
||||
.eh_should_retry_cmd = fc_eh_should_retry_cmd,
|
||||
.eh_abort_handler = lpfc_abort_handler,
|
||||
.eh_device_reset_handler = lpfc_device_reset_handler,
|
||||
.eh_target_reset_handler = lpfc_target_reset_handler,
|
||||
|
@ -1532,15 +1532,19 @@ lpfc_sli_cancel_iocbs(struct lpfc_hba *phba, struct list_head *iocblist,
|
||||
|
||||
while (!list_empty(iocblist)) {
|
||||
list_remove_head(iocblist, piocb, struct lpfc_iocbq, list);
|
||||
if (!piocb->iocb_cmpl) {
|
||||
if (piocb->wqe_cmpl) {
|
||||
if (piocb->iocb_flag & LPFC_IO_NVME)
|
||||
lpfc_nvme_cancel_iocb(phba, piocb);
|
||||
lpfc_nvme_cancel_iocb(phba, piocb,
|
||||
ulpstatus, ulpWord4);
|
||||
else
|
||||
lpfc_sli_release_iocbq(phba, piocb);
|
||||
} else {
|
||||
|
||||
} else if (piocb->iocb_cmpl) {
|
||||
piocb->iocb.ulpStatus = ulpstatus;
|
||||
piocb->iocb.un.ulpWord[4] = ulpWord4;
|
||||
(piocb->iocb_cmpl) (phba, piocb, piocb);
|
||||
} else {
|
||||
lpfc_sli_release_iocbq(phba, piocb);
|
||||
}
|
||||
}
|
||||
return;
|
||||
@ -3007,23 +3011,44 @@ lpfc_nvme_unsol_ls_handler(struct lpfc_hba *phba, struct lpfc_iocbq *piocb)
|
||||
axchg->payload = nvmebuf->dbuf.virt;
|
||||
INIT_LIST_HEAD(&axchg->list);
|
||||
|
||||
if (phba->nvmet_support)
|
||||
if (phba->nvmet_support) {
|
||||
ret = lpfc_nvmet_handle_lsreq(phba, axchg);
|
||||
else
|
||||
spin_lock_irq(&ndlp->lock);
|
||||
if (!ret && !(ndlp->fc4_xpt_flags & NLP_XPT_HAS_HH)) {
|
||||
ndlp->fc4_xpt_flags |= NLP_XPT_HAS_HH;
|
||||
spin_unlock_irq(&ndlp->lock);
|
||||
|
||||
/* This reference is a single occurrence to hold the
|
||||
* node valid until the nvmet transport calls
|
||||
* host_release.
|
||||
*/
|
||||
if (!lpfc_nlp_get(ndlp))
|
||||
goto out_fail;
|
||||
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_NODE,
|
||||
"6206 NVMET unsol ls_req ndlp %p "
|
||||
"DID x%x xflags x%x refcnt %d\n",
|
||||
ndlp, ndlp->nlp_DID,
|
||||
ndlp->fc4_xpt_flags,
|
||||
kref_read(&ndlp->kref));
|
||||
} else {
|
||||
spin_unlock_irq(&ndlp->lock);
|
||||
}
|
||||
} else {
|
||||
ret = lpfc_nvme_handle_lsreq(phba, axchg);
|
||||
}
|
||||
|
||||
/* if zero, LS was successfully handled. If non-zero, LS not handled */
|
||||
if (!ret)
|
||||
return;
|
||||
|
||||
out_fail:
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
|
||||
"6155 Drop NVME LS from DID %06X: SID %06X OXID x%X "
|
||||
"NVMe%s handler failed %d\n",
|
||||
did, sid, oxid,
|
||||
(phba->nvmet_support) ? "T" : "I", ret);
|
||||
|
||||
out_fail:
|
||||
|
||||
/* recycle receive buffer */
|
||||
lpfc_in_buf_free(phba, &nvmebuf->dbuf);
|
||||
|
||||
@ -4221,6 +4246,8 @@ lpfc_sli_abort_iocb_ring(struct lpfc_hba *phba, struct lpfc_sli_ring *pring)
|
||||
lpfc_sli_issue_abort_iotag(phba, pring, iocb, NULL);
|
||||
spin_unlock_irq(&phba->hbalock);
|
||||
}
|
||||
/* Make sure HBA is alive */
|
||||
lpfc_issue_hb_tmo(phba);
|
||||
|
||||
/* Cancel all the IOCBs from the completions list */
|
||||
lpfc_sli_cancel_iocbs(phba, &completions, IOSTAT_LOCAL_REJECT,
|
||||
@ -4359,6 +4386,8 @@ lpfc_sli_brdready_s3(struct lpfc_hba *phba, uint32_t mask)
|
||||
if (lpfc_readl(phba->HSregaddr, &status))
|
||||
return 1;
|
||||
|
||||
phba->hba_flag |= HBA_NEEDS_CFG_PORT;
|
||||
|
||||
/*
|
||||
* Check status register every 100ms for 5 retries, then every
|
||||
* 500ms for 5, then every 2.5 sec for 5, then reset board and
|
||||
@ -4687,6 +4716,7 @@ lpfc_sli_brdreset(struct lpfc_hba *phba)
|
||||
/* perform board reset */
|
||||
phba->fc_eventTag = 0;
|
||||
phba->link_events = 0;
|
||||
phba->hba_flag |= HBA_NEEDS_CFG_PORT;
|
||||
if (phba->pport) {
|
||||
phba->pport->fc_myDID = 0;
|
||||
phba->pport->fc_prevDID = 0;
|
||||
@ -5020,6 +5050,8 @@ lpfc_sli_chipset_init(struct lpfc_hba *phba)
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
phba->hba_flag |= HBA_NEEDS_CFG_PORT;
|
||||
|
||||
/* Clear all interrupt enable conditions */
|
||||
writel(0, phba->HCregaddr);
|
||||
readl(phba->HCregaddr); /* flush */
|
||||
@ -5316,45 +5348,18 @@ int
|
||||
lpfc_sli_hba_setup(struct lpfc_hba *phba)
|
||||
{
|
||||
uint32_t rc;
|
||||
int mode = 3, i;
|
||||
int i;
|
||||
int longs;
|
||||
|
||||
switch (phba->cfg_sli_mode) {
|
||||
case 2:
|
||||
if (phba->cfg_enable_npiv) {
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
|
||||
"1824 NPIV enabled: Override sli_mode "
|
||||
"parameter (%d) to auto (0).\n",
|
||||
phba->cfg_sli_mode);
|
||||
break;
|
||||
}
|
||||
mode = 2;
|
||||
break;
|
||||
case 0:
|
||||
case 3:
|
||||
break;
|
||||
default:
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
|
||||
"1819 Unrecognized sli_mode parameter: %d.\n",
|
||||
phba->cfg_sli_mode);
|
||||
|
||||
break;
|
||||
/* Enable ISR already does config_port because of config_msi mbx */
|
||||
if (phba->hba_flag & HBA_NEEDS_CFG_PORT) {
|
||||
rc = lpfc_sli_config_port(phba, LPFC_SLI_REV3);
|
||||
if (rc)
|
||||
return -EIO;
|
||||
phba->hba_flag &= ~HBA_NEEDS_CFG_PORT;
|
||||
}
|
||||
phba->fcp_embed_io = 0; /* SLI4 FC support only */
|
||||
|
||||
rc = lpfc_sli_config_port(phba, mode);
|
||||
|
||||
if (rc && phba->cfg_sli_mode == 3)
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
|
||||
"1820 Unable to select SLI-3. "
|
||||
"Not supported by adapter.\n");
|
||||
if (rc && mode != 2)
|
||||
rc = lpfc_sli_config_port(phba, 2);
|
||||
else if (rc && mode == 2)
|
||||
rc = lpfc_sli_config_port(phba, 3);
|
||||
if (rc)
|
||||
goto lpfc_sli_hba_setup_error;
|
||||
|
||||
/* Enable PCIe device Advanced Error Reporting (AER) if configured */
|
||||
if (phba->cfg_aer_support == 1 && !(phba->hba_flag & HBA_AER_ENABLED)) {
|
||||
rc = pci_enable_pcie_error_reporting(phba->pcidev);
|
||||
@ -7486,7 +7491,7 @@ static void lpfc_sli4_dip(struct lpfc_hba *phba)
|
||||
return;
|
||||
|
||||
if (bf_get(lpfc_sliport_status_dip, ®_data))
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
|
||||
"2904 Firmware Dump Image Present"
|
||||
" on Adapter");
|
||||
}
|
||||
@ -8041,7 +8046,7 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba)
|
||||
/* Start heart beat timer */
|
||||
mod_timer(&phba->hb_tmofunc,
|
||||
jiffies + msecs_to_jiffies(1000 * LPFC_HB_MBOX_INTERVAL));
|
||||
phba->hb_outstanding = 0;
|
||||
phba->hba_flag &= ~(HBA_HBEAT_INP | HBA_HBEAT_TMO);
|
||||
phba->last_completion_time = jiffies;
|
||||
|
||||
/* start eq_delay heartbeat */
|
||||
@ -8291,8 +8296,10 @@ lpfc_mbox_timeout_handler(struct lpfc_hba *phba)
|
||||
|
||||
struct lpfc_sli *psli = &phba->sli;
|
||||
|
||||
/* If the mailbox completed, process the completion and return */
|
||||
if (lpfc_sli4_process_missed_mbox_completions(phba))
|
||||
/* If the mailbox completed, process the completion */
|
||||
lpfc_sli4_process_missed_mbox_completions(phba);
|
||||
|
||||
if (!(psli->sli_flag & LPFC_SLI_ACTIVE))
|
||||
return;
|
||||
|
||||
if (pmbox != NULL)
|
||||
@ -8333,8 +8340,6 @@ lpfc_mbox_timeout_handler(struct lpfc_hba *phba)
|
||||
psli->sli_flag &= ~LPFC_SLI_ACTIVE;
|
||||
spin_unlock_irq(&phba->hbalock);
|
||||
|
||||
lpfc_sli_abort_fcp_rings(phba);
|
||||
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
|
||||
"0345 Resetting board due to mailbox timeout\n");
|
||||
|
||||
@ -11215,6 +11220,9 @@ lpfc_sli_host_down(struct lpfc_vport *vport)
|
||||
}
|
||||
spin_unlock_irqrestore(&phba->hbalock, flags);
|
||||
|
||||
/* Make sure HBA is alive */
|
||||
lpfc_issue_hb_tmo(phba);
|
||||
|
||||
/* Cancel all the IOCBs from the completions list */
|
||||
lpfc_sli_cancel_iocbs(phba, &completions, IOSTAT_LOCAL_REJECT,
|
||||
IOERR_SLI_DOWN);
|
||||
@ -11805,7 +11813,7 @@ lpfc_sli_validate_fcp_iocb(struct lpfc_iocbq *iocbq, struct lpfc_vport *vport,
|
||||
struct lpfc_io_buf *lpfc_cmd;
|
||||
int rc = 1;
|
||||
|
||||
if (iocbq->vport != vport)
|
||||
if (!iocbq || iocbq->vport != vport)
|
||||
return rc;
|
||||
|
||||
if (!(iocbq->iocb_flag & LPFC_IO_FCP) ||
|
||||
@ -13026,7 +13034,21 @@ lpfc_sli_sp_intr_handler(int irq, void *dev_id)
|
||||
spin_unlock_irqrestore(
|
||||
&phba->pport->work_port_lock,
|
||||
iflag);
|
||||
lpfc_mbox_cmpl_put(phba, pmb);
|
||||
|
||||
/* Do NOT queue MBX_HEARTBEAT to the worker
|
||||
* thread for processing.
|
||||
*/
|
||||
if (pmbox->mbxCommand == MBX_HEARTBEAT) {
|
||||
/* Process mbox now */
|
||||
phba->sli.mbox_active = NULL;
|
||||
phba->sli.sli_flag &=
|
||||
~LPFC_SLI_MBOX_ACTIVE;
|
||||
if (pmb->mbox_cmpl)
|
||||
pmb->mbox_cmpl(phba, pmb);
|
||||
} else {
|
||||
/* Queue to worker thread to process */
|
||||
lpfc_mbox_cmpl_put(phba, pmb);
|
||||
}
|
||||
}
|
||||
} else
|
||||
spin_unlock_irqrestore(&phba->hbalock, iflag);
|
||||
@ -13622,7 +13644,26 @@ lpfc_sli4_sp_handle_mbox_event(struct lpfc_hba *phba, struct lpfc_mcqe *mcqe)
|
||||
phba->pport->work_port_events &= ~WORKER_MBOX_TMO;
|
||||
spin_unlock_irqrestore(&phba->pport->work_port_lock, iflags);
|
||||
|
||||
/* There is mailbox completion work to do */
|
||||
/* Do NOT queue MBX_HEARTBEAT to the worker thread for processing. */
|
||||
if (pmbox->mbxCommand == MBX_HEARTBEAT) {
|
||||
spin_lock_irqsave(&phba->hbalock, iflags);
|
||||
/* Release the mailbox command posting token */
|
||||
phba->sli.sli_flag &= ~LPFC_SLI_MBOX_ACTIVE;
|
||||
phba->sli.mbox_active = NULL;
|
||||
if (bf_get(lpfc_trailer_consumed, mcqe))
|
||||
lpfc_sli4_mq_release(phba->sli4_hba.mbx_wq);
|
||||
spin_unlock_irqrestore(&phba->hbalock, iflags);
|
||||
|
||||
/* Post the next mbox command, if there is one */
|
||||
lpfc_sli4_post_async_mbox(phba);
|
||||
|
||||
/* Process cmpl now */
|
||||
if (pmb->mbox_cmpl)
|
||||
pmb->mbox_cmpl(phba, pmb);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* There is mailbox completion work to queue to the worker thread */
|
||||
spin_lock_irqsave(&phba->hbalock, iflags);
|
||||
__lpfc_mbox_cmpl_put(phba, pmb);
|
||||
phba->work_ha |= HA_MBATT;
|
||||
|
@ -20,7 +20,7 @@
|
||||
* included with this package. *
|
||||
*******************************************************************/
|
||||
|
||||
#define LPFC_DRIVER_VERSION "12.8.0.6"
|
||||
#define LPFC_DRIVER_VERSION "12.8.0.7"
|
||||
#define LPFC_DRIVER_NAME "lpfc"
|
||||
|
||||
/* Used for SLI 2/3 */
|
||||
|
@ -478,7 +478,7 @@ lpfc_vport_create(struct fc_vport *fc_vport, bool disable)
|
||||
rc = VPORT_OK;
|
||||
|
||||
out:
|
||||
lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
|
||||
lpfc_printf_vlog(vport, KERN_ERR, LOG_VPORT,
|
||||
"1825 Vport Created.\n");
|
||||
lpfc_host_attrib_init(lpfc_shost_from_vport(vport));
|
||||
error_out:
|
||||
|
@ -326,7 +326,6 @@ static void mac53c94_interrupt(int irq, void *dev_id)
|
||||
}
|
||||
cmd->SCp.Status = readb(®s->fifo);
|
||||
cmd->SCp.Message = readb(®s->fifo);
|
||||
cmd->result = CMD_ACCEPT_MSG;
|
||||
writeb(CMD_ACCEPT_MSG, ®s->command);
|
||||
state->phase = busfreeing;
|
||||
break;
|
||||
|
@ -1165,7 +1165,7 @@ megaraid_mbox_setup_dma_pools(adapter_t *adapter)
|
||||
* structure
|
||||
* Since passthru and extended passthru commands are exclusive, they
|
||||
* share common memory pool. Passthru structures piggyback on memory
|
||||
* allocted to extended passthru since passthru is smaller of the two
|
||||
* allocated to extended passthru since passthru is smaller of the two
|
||||
*/
|
||||
raid_dev->epthru_pool_handle = dma_pool_create("megaraid mbox pthru",
|
||||
&adapter->pdev->dev, sizeof(mraid_epassthru_t), 128, 0);
|
||||
|
@ -3920,8 +3920,7 @@ megasas_free_host_crash_buffer(struct megasas_instance *instance)
|
||||
{
|
||||
unsigned int i;
|
||||
for (i = 0; i < instance->drv_buf_alloc; i++) {
|
||||
if (instance->crash_buf[i])
|
||||
vfree(instance->crash_buf[i]);
|
||||
vfree(instance->crash_buf[i]);
|
||||
}
|
||||
instance->drv_buf_index = 0;
|
||||
instance->drv_buf_alloc = 0;
|
||||
|
@ -2505,8 +2505,8 @@ _base_check_pcie_native_sgl(struct MPT3SAS_ADAPTER *ioc,
|
||||
}
|
||||
|
||||
/* Check if we need to build a native SG list. */
|
||||
if (base_is_prp_possible(ioc, pcie_device,
|
||||
scmd, sges_left) == 0) {
|
||||
if (!base_is_prp_possible(ioc, pcie_device,
|
||||
scmd, sges_left)) {
|
||||
/* We built a native SG list, just return. */
|
||||
goto out;
|
||||
}
|
||||
|
@ -216,11 +216,11 @@ void mvs_set_sas_addr(struct mvs_info *mvi, int port_id, u32 off_lo,
|
||||
MVS_CHIP_DISP->write_port_cfg_data(mvi, port_id, hi);
|
||||
}
|
||||
|
||||
static void mvs_bytes_dmaed(struct mvs_info *mvi, int i)
|
||||
static void mvs_bytes_dmaed(struct mvs_info *mvi, int i, gfp_t gfp_flags)
|
||||
{
|
||||
struct mvs_phy *phy = &mvi->phy[i];
|
||||
struct asd_sas_phy *sas_phy = &phy->sas_phy;
|
||||
struct sas_ha_struct *sas_ha;
|
||||
|
||||
if (!phy->phy_attached)
|
||||
return;
|
||||
|
||||
@ -229,8 +229,7 @@ static void mvs_bytes_dmaed(struct mvs_info *mvi, int i)
|
||||
return;
|
||||
}
|
||||
|
||||
sas_ha = mvi->sas;
|
||||
sas_ha->notify_phy_event(sas_phy, PHYE_OOB_DONE);
|
||||
sas_notify_phy_event(sas_phy, PHYE_OOB_DONE, gfp_flags);
|
||||
|
||||
if (sas_phy->phy) {
|
||||
struct sas_phy *sphy = sas_phy->phy;
|
||||
@ -262,8 +261,7 @@ static void mvs_bytes_dmaed(struct mvs_info *mvi, int i)
|
||||
|
||||
sas_phy->frame_rcvd_size = phy->frame_rcvd_size;
|
||||
|
||||
mvi->sas->notify_port_event(sas_phy,
|
||||
PORTE_BYTES_DMAED);
|
||||
sas_notify_port_event(sas_phy, PORTE_BYTES_DMAED, gfp_flags);
|
||||
}
|
||||
|
||||
void mvs_scan_start(struct Scsi_Host *shost)
|
||||
@ -279,7 +277,7 @@ void mvs_scan_start(struct Scsi_Host *shost)
|
||||
for (j = 0; j < core_nr; j++) {
|
||||
mvi = ((struct mvs_prv_info *)sha->lldd_ha)->mvi[j];
|
||||
for (i = 0; i < mvi->chip->n_phy; ++i)
|
||||
mvs_bytes_dmaed(mvi, i);
|
||||
mvs_bytes_dmaed(mvi, i, GFP_KERNEL);
|
||||
}
|
||||
mvs_prv->scan_finished = 1;
|
||||
}
|
||||
@ -1880,7 +1878,6 @@ static void mvs_work_queue(struct work_struct *work)
|
||||
struct mvs_info *mvi = mwq->mvi;
|
||||
unsigned long flags;
|
||||
u32 phy_no = (unsigned long) mwq->data;
|
||||
struct sas_ha_struct *sas_ha = mvi->sas;
|
||||
struct mvs_phy *phy = &mvi->phy[phy_no];
|
||||
struct asd_sas_phy *sas_phy = &phy->sas_phy;
|
||||
|
||||
@ -1895,21 +1892,21 @@ static void mvs_work_queue(struct work_struct *work)
|
||||
if (!(tmp & PHY_READY_MASK)) {
|
||||
sas_phy_disconnected(sas_phy);
|
||||
mvs_phy_disconnected(phy);
|
||||
sas_ha->notify_phy_event(sas_phy,
|
||||
PHYE_LOSS_OF_SIGNAL);
|
||||
sas_notify_phy_event(sas_phy,
|
||||
PHYE_LOSS_OF_SIGNAL, GFP_ATOMIC);
|
||||
mv_dprintk("phy%d Removed Device\n", phy_no);
|
||||
} else {
|
||||
MVS_CHIP_DISP->detect_porttype(mvi, phy_no);
|
||||
mvs_update_phyinfo(mvi, phy_no, 1);
|
||||
mvs_bytes_dmaed(mvi, phy_no);
|
||||
mvs_bytes_dmaed(mvi, phy_no, GFP_ATOMIC);
|
||||
mvs_port_notify_formed(sas_phy, 0);
|
||||
mv_dprintk("phy%d Attached Device\n", phy_no);
|
||||
}
|
||||
}
|
||||
} else if (mwq->handler & EXP_BRCT_CHG) {
|
||||
phy->phy_event &= ~EXP_BRCT_CHG;
|
||||
sas_ha->notify_port_event(sas_phy,
|
||||
PORTE_BROADCAST_RCVD);
|
||||
sas_notify_port_event(sas_phy,
|
||||
PORTE_BROADCAST_RCVD, GFP_ATOMIC);
|
||||
mv_dprintk("phy%d Got Broadcast Change\n", phy_no);
|
||||
}
|
||||
list_del(&mwq->entry);
|
||||
@ -2026,7 +2023,7 @@ void mvs_int_port(struct mvs_info *mvi, int phy_no, u32 events)
|
||||
mdelay(10);
|
||||
}
|
||||
|
||||
mvs_bytes_dmaed(mvi, phy_no);
|
||||
mvs_bytes_dmaed(mvi, phy_no, GFP_ATOMIC);
|
||||
/* whether driver is going to handle hot plug */
|
||||
if (phy->phy_event & PHY_PLUG_OUT) {
|
||||
mvs_port_notify_formed(&phy->sas_phy, 0);
|
||||
|
@ -148,6 +148,11 @@ static int ncr_debug = SCSI_NCR_DEBUG_FLAGS;
|
||||
#define DEBUG_FLAGS SCSI_NCR_DEBUG_FLAGS
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Locally used status flag
|
||||
*/
|
||||
#define SAM_STAT_ILLEGAL 0xff
|
||||
|
||||
static inline struct list_head *ncr_list_pop(struct list_head *head)
|
||||
{
|
||||
if (!list_empty(head)) {
|
||||
@ -998,8 +1003,6 @@ typedef u32 tagmap_t;
|
||||
** Other definitions
|
||||
*/
|
||||
|
||||
#define ScsiResult(host_code, scsi_code) (((host_code) << 16) + ((scsi_code) & 0x7f))
|
||||
|
||||
#define initverbose (driver_setup.verbose)
|
||||
#define bootverbose (np->verbose)
|
||||
|
||||
@ -2430,7 +2433,7 @@ static struct script script0 __initdata = {
|
||||
*/
|
||||
SCR_FROM_REG (SS_REG),
|
||||
0,
|
||||
SCR_CALL ^ IFFALSE (DATA (S_GOOD)),
|
||||
SCR_CALL ^ IFFALSE (DATA (SAM_STAT_GOOD)),
|
||||
PADDRH (bad_status),
|
||||
|
||||
#ifndef SCSI_NCR_CCB_DONE_SUPPORT
|
||||
@ -2879,7 +2882,7 @@ static struct scripth scripth0 __initdata = {
|
||||
8,
|
||||
SCR_TO_REG (HS_REG),
|
||||
0,
|
||||
SCR_LOAD_REG (SS_REG, S_GOOD),
|
||||
SCR_LOAD_REG (SS_REG, SAM_STAT_GOOD),
|
||||
0,
|
||||
SCR_JUMP,
|
||||
PADDR (cleanup_ok),
|
||||
@ -3341,15 +3344,15 @@ static struct scripth scripth0 __initdata = {
|
||||
PADDRH (reset),
|
||||
}/*-------------------------< BAD_STATUS >-----------------*/,{
|
||||
/*
|
||||
** If command resulted in either QUEUE FULL,
|
||||
** If command resulted in either TASK_SET FULL,
|
||||
** CHECK CONDITION or COMMAND TERMINATED,
|
||||
** call the C code.
|
||||
*/
|
||||
SCR_INT ^ IFTRUE (DATA (S_QUEUE_FULL)),
|
||||
SCR_INT ^ IFTRUE (DATA (SAM_STAT_TASK_SET_FULL)),
|
||||
SIR_BAD_STATUS,
|
||||
SCR_INT ^ IFTRUE (DATA (S_CHECK_COND)),
|
||||
SCR_INT ^ IFTRUE (DATA (SAM_STAT_CHECK_CONDITION)),
|
||||
SIR_BAD_STATUS,
|
||||
SCR_INT ^ IFTRUE (DATA (S_TERMINATED)),
|
||||
SCR_INT ^ IFTRUE (DATA (SAM_STAT_COMMAND_TERMINATED)),
|
||||
SIR_BAD_STATUS,
|
||||
SCR_RETURN,
|
||||
0,
|
||||
@ -4371,7 +4374,7 @@ static int ncr_queue_command (struct ncb *np, struct scsi_cmnd *cmd)
|
||||
*/
|
||||
cp->actualquirks = 0;
|
||||
cp->host_status = cp->nego_status ? HS_NEGOTIATE : HS_BUSY;
|
||||
cp->scsi_status = S_ILLEGAL;
|
||||
cp->scsi_status = SAM_STAT_ILLEGAL;
|
||||
cp->parity_status = 0;
|
||||
|
||||
cp->xerr_status = XE_OK;
|
||||
@ -4602,7 +4605,7 @@ static int ncr_reset_bus (struct ncb *np, struct scsi_cmnd *cmd, int sync_reset)
|
||||
* in order to keep it alive.
|
||||
*/
|
||||
if (!found && sync_reset && !retrieve_from_waiting_list(0, np, cmd)) {
|
||||
cmd->result = DID_RESET << 16;
|
||||
set_host_byte(cmd, DID_RESET);
|
||||
ncr_queue_done_cmd(np, cmd);
|
||||
}
|
||||
|
||||
@ -4630,7 +4633,7 @@ static int ncr_abort_command (struct ncb *np, struct scsi_cmnd *cmd)
|
||||
* First, look for the scsi command in the waiting list
|
||||
*/
|
||||
if (remove_from_waiting_list(np, cmd)) {
|
||||
cmd->result = ScsiResult(DID_ABORT, 0);
|
||||
set_host_byte(cmd, DID_ABORT);
|
||||
ncr_queue_done_cmd(np, cmd);
|
||||
return SCSI_ABORT_SUCCESS;
|
||||
}
|
||||
@ -4895,7 +4898,8 @@ void ncr_complete (struct ncb *np, struct ccb *cp)
|
||||
** Print out any error for debugging purpose.
|
||||
*/
|
||||
if (DEBUG_FLAGS & (DEBUG_RESULT|DEBUG_TINY)) {
|
||||
if (cp->host_status!=HS_COMPLETE || cp->scsi_status!=S_GOOD) {
|
||||
if (cp->host_status != HS_COMPLETE ||
|
||||
cp->scsi_status != SAM_STAT_GOOD) {
|
||||
PRINT_ADDR(cmd, "ERROR: cmd=%x host_status=%x "
|
||||
"scsi_status=%x\n", cmd->cmnd[0],
|
||||
cp->host_status, cp->scsi_status);
|
||||
@ -4905,15 +4909,16 @@ void ncr_complete (struct ncb *np, struct ccb *cp)
|
||||
/*
|
||||
** Check the status.
|
||||
*/
|
||||
cmd->result = 0;
|
||||
if ( (cp->host_status == HS_COMPLETE)
|
||||
&& (cp->scsi_status == S_GOOD ||
|
||||
cp->scsi_status == S_COND_MET)) {
|
||||
&& (cp->scsi_status == SAM_STAT_GOOD ||
|
||||
cp->scsi_status == SAM_STAT_CONDITION_MET)) {
|
||||
/*
|
||||
* All went well (GOOD status).
|
||||
* CONDITION MET status is returned on
|
||||
* CONDITION MET status is returned on
|
||||
* `Pre-Fetch' or `Search data' success.
|
||||
*/
|
||||
cmd->result = ScsiResult(DID_OK, cp->scsi_status);
|
||||
set_status_byte(cmd, cp->scsi_status);
|
||||
|
||||
/*
|
||||
** @RESID@
|
||||
@ -4944,11 +4949,11 @@ void ncr_complete (struct ncb *np, struct ccb *cp)
|
||||
}
|
||||
}
|
||||
} else if ((cp->host_status == HS_COMPLETE)
|
||||
&& (cp->scsi_status == S_CHECK_COND)) {
|
||||
&& (cp->scsi_status == SAM_STAT_CHECK_CONDITION)) {
|
||||
/*
|
||||
** Check condition code
|
||||
*/
|
||||
cmd->result = DID_OK << 16 | S_CHECK_COND;
|
||||
set_status_byte(cmd, SAM_STAT_CHECK_CONDITION);
|
||||
|
||||
/*
|
||||
** Copy back sense data to caller's buffer.
|
||||
@ -4965,20 +4970,20 @@ void ncr_complete (struct ncb *np, struct ccb *cp)
|
||||
printk (".\n");
|
||||
}
|
||||
} else if ((cp->host_status == HS_COMPLETE)
|
||||
&& (cp->scsi_status == S_CONFLICT)) {
|
||||
&& (cp->scsi_status == SAM_STAT_RESERVATION_CONFLICT)) {
|
||||
/*
|
||||
** Reservation Conflict condition code
|
||||
*/
|
||||
cmd->result = DID_OK << 16 | S_CONFLICT;
|
||||
|
||||
set_status_byte(cmd, SAM_STAT_RESERVATION_CONFLICT);
|
||||
|
||||
} else if ((cp->host_status == HS_COMPLETE)
|
||||
&& (cp->scsi_status == S_BUSY ||
|
||||
cp->scsi_status == S_QUEUE_FULL)) {
|
||||
&& (cp->scsi_status == SAM_STAT_BUSY ||
|
||||
cp->scsi_status == SAM_STAT_TASK_SET_FULL)) {
|
||||
|
||||
/*
|
||||
** Target is busy.
|
||||
*/
|
||||
cmd->result = ScsiResult(DID_OK, cp->scsi_status);
|
||||
set_status_byte(cmd, cp->scsi_status);
|
||||
|
||||
} else if ((cp->host_status == HS_SEL_TIMEOUT)
|
||||
|| (cp->host_status == HS_TIMEOUT)) {
|
||||
@ -4986,21 +4991,24 @@ void ncr_complete (struct ncb *np, struct ccb *cp)
|
||||
/*
|
||||
** No response
|
||||
*/
|
||||
cmd->result = ScsiResult(DID_TIME_OUT, cp->scsi_status);
|
||||
set_status_byte(cmd, cp->scsi_status);
|
||||
set_host_byte(cmd, DID_TIME_OUT);
|
||||
|
||||
} else if (cp->host_status == HS_RESET) {
|
||||
|
||||
/*
|
||||
** SCSI bus reset
|
||||
*/
|
||||
cmd->result = ScsiResult(DID_RESET, cp->scsi_status);
|
||||
set_status_byte(cmd, cp->scsi_status);
|
||||
set_host_byte(cmd, DID_RESET);
|
||||
|
||||
} else if (cp->host_status == HS_ABORTED) {
|
||||
|
||||
/*
|
||||
** Transfer aborted
|
||||
*/
|
||||
cmd->result = ScsiResult(DID_ABORT, cp->scsi_status);
|
||||
set_status_byte(cmd, cp->scsi_status);
|
||||
set_host_byte(cmd, DID_ABORT);
|
||||
|
||||
} else {
|
||||
|
||||
@ -5010,7 +5018,8 @@ void ncr_complete (struct ncb *np, struct ccb *cp)
|
||||
PRINT_ADDR(cmd, "COMMAND FAILED (%x %x) @%p.\n",
|
||||
cp->host_status, cp->scsi_status, cp);
|
||||
|
||||
cmd->result = ScsiResult(DID_ERROR, cp->scsi_status);
|
||||
set_status_byte(cmd, cp->scsi_status);
|
||||
set_host_byte(cmd, DID_ERROR);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -5026,10 +5035,10 @@ void ncr_complete (struct ncb *np, struct ccb *cp)
|
||||
|
||||
if (cp->host_status==HS_COMPLETE) {
|
||||
switch (cp->scsi_status) {
|
||||
case S_GOOD:
|
||||
case SAM_STAT_GOOD:
|
||||
printk (" GOOD");
|
||||
break;
|
||||
case S_CHECK_COND:
|
||||
case SAM_STAT_CHECK_CONDITION:
|
||||
printk (" SENSE:");
|
||||
p = (u_char*) &cmd->sense_buffer;
|
||||
for (i=0; i<14; i++)
|
||||
@ -6564,7 +6573,7 @@ static void ncr_sir_to_redo(struct ncb *np, int num, struct ccb *cp)
|
||||
|
||||
switch(s_status) {
|
||||
default: /* Just for safety, should never happen */
|
||||
case S_QUEUE_FULL:
|
||||
case SAM_STAT_TASK_SET_FULL:
|
||||
/*
|
||||
** Decrease number of tags to the number of
|
||||
** disconnected commands.
|
||||
@ -6588,15 +6597,15 @@ static void ncr_sir_to_redo(struct ncb *np, int num, struct ccb *cp)
|
||||
*/
|
||||
cp->phys.header.savep = cp->startp;
|
||||
cp->host_status = HS_BUSY;
|
||||
cp->scsi_status = S_ILLEGAL;
|
||||
cp->scsi_status = SAM_STAT_ILLEGAL;
|
||||
|
||||
ncr_put_start_queue(np, cp);
|
||||
if (disc_cnt)
|
||||
INB (nc_ctest2); /* Clear SIGP */
|
||||
OUTL_DSP (NCB_SCRIPT_PHYS (np, reselect));
|
||||
return;
|
||||
case S_TERMINATED:
|
||||
case S_CHECK_COND:
|
||||
case SAM_STAT_COMMAND_TERMINATED:
|
||||
case SAM_STAT_CHECK_CONDITION:
|
||||
/*
|
||||
** If we were requesting sense, give up.
|
||||
*/
|
||||
@ -6646,7 +6655,7 @@ static void ncr_sir_to_redo(struct ncb *np, int num, struct ccb *cp)
|
||||
cp->phys.header.wlastp = startp;
|
||||
|
||||
cp->host_status = HS_BUSY;
|
||||
cp->scsi_status = S_ILLEGAL;
|
||||
cp->scsi_status = SAM_STAT_ILLEGAL;
|
||||
cp->auto_sense = s_status;
|
||||
|
||||
cp->start.schedule.l_paddr =
|
||||
@ -8035,7 +8044,7 @@ printk("ncr53c8xx_queue_command\n");
|
||||
spin_lock_irqsave(&np->smp_lock, flags);
|
||||
|
||||
if ((sts = ncr_queue_command(np, cmd)) != DID_OK) {
|
||||
cmd->result = sts << 16;
|
||||
set_host_byte(cmd, sts);
|
||||
#ifdef DEBUG_NCR53C8XX
|
||||
printk("ncr53c8xx : command not queued - result=%d\n", sts);
|
||||
#endif
|
||||
@ -8226,7 +8235,7 @@ static void process_waiting_list(struct ncb *np, int sts)
|
||||
#ifdef DEBUG_WAITING_LIST
|
||||
printk("%s: cmd %lx done forced sts=%d\n", ncr_name(np), (u_long) wcmd, sts);
|
||||
#endif
|
||||
wcmd->result = sts << 16;
|
||||
set_host_byte(wcmd, sts);
|
||||
ncr_queue_done_cmd(np, wcmd);
|
||||
}
|
||||
}
|
||||
|
@ -1238,22 +1238,6 @@ struct scr_tblsel {
|
||||
**-----------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*
|
||||
** Status
|
||||
*/
|
||||
|
||||
#define S_GOOD (0x00)
|
||||
#define S_CHECK_COND (0x02)
|
||||
#define S_COND_MET (0x04)
|
||||
#define S_BUSY (0x08)
|
||||
#define S_INT (0x10)
|
||||
#define S_INT_COND_MET (0x14)
|
||||
#define S_CONFLICT (0x18)
|
||||
#define S_TERMINATED (0x20)
|
||||
#define S_QUEUE_FULL (0x28)
|
||||
#define S_ILLEGAL (0xff)
|
||||
#define S_SENSE (0x80)
|
||||
|
||||
/*
|
||||
* End of ncrreg from FreeBSD
|
||||
*/
|
||||
|
@ -935,7 +935,7 @@ static int nsp32_queuecommand_lck(struct scsi_cmnd *SCpnt, void (*done)(struct s
|
||||
|
||||
SCpnt->scsi_done = done;
|
||||
data->CurrentSC = SCpnt;
|
||||
SCpnt->SCp.Status = CHECK_CONDITION;
|
||||
SCpnt->SCp.Status = SAM_STAT_CHECK_CONDITION;
|
||||
SCpnt->SCp.Message = 0;
|
||||
scsi_set_resid(SCpnt, scsi_bufflen(SCpnt));
|
||||
|
||||
|
@ -1132,7 +1132,7 @@ static irqreturn_t nspintr(int irq, void *dev_id)
|
||||
//*sync_neg = SYNC_NOT_YET;
|
||||
|
||||
/* all command complete and return status */
|
||||
if (tmpSC->SCp.Message == MSG_COMMAND_COMPLETE) {
|
||||
if (tmpSC->SCp.Message == COMMAND_COMPLETE) {
|
||||
tmpSC->result = (DID_OK << 16) |
|
||||
((tmpSC->SCp.Message & 0xff) << 8) |
|
||||
((tmpSC->SCp.Status & 0xff) << 0);
|
||||
@ -1226,9 +1226,9 @@ static irqreturn_t nspintr(int irq, void *dev_id)
|
||||
data->Sync[target].SyncOffset = 0;
|
||||
|
||||
/**/
|
||||
data->MsgBuffer[i] = MSG_EXTENDED; i++;
|
||||
data->MsgBuffer[i] = EXTENDED_MESSAGE; i++;
|
||||
data->MsgBuffer[i] = 3; i++;
|
||||
data->MsgBuffer[i] = MSG_EXT_SDTR; i++;
|
||||
data->MsgBuffer[i] = EXTENDED_SDTR; i++;
|
||||
data->MsgBuffer[i] = 0x0c; i++;
|
||||
data->MsgBuffer[i] = 15; i++;
|
||||
/**/
|
||||
@ -1255,9 +1255,9 @@ static irqreturn_t nspintr(int irq, void *dev_id)
|
||||
//nsp_dbg(NSP_DEBUG_INTR, "sync target=%d,lun=%d",target,lun);
|
||||
|
||||
if (data->MsgLen >= 5 &&
|
||||
data->MsgBuffer[0] == MSG_EXTENDED &&
|
||||
data->MsgBuffer[0] == EXTENDED_MESSAGE &&
|
||||
data->MsgBuffer[1] == 3 &&
|
||||
data->MsgBuffer[2] == MSG_EXT_SDTR ) {
|
||||
data->MsgBuffer[2] == EXTENDED_SDTR ) {
|
||||
data->Sync[target].SyncPeriod = data->MsgBuffer[3];
|
||||
data->Sync[target].SyncOffset = data->MsgBuffer[4];
|
||||
//nsp_dbg(NSP_DEBUG_INTR, "sync ok, %d %d", data->MsgBuffer[3], data->MsgBuffer[4]);
|
||||
@ -1275,7 +1275,7 @@ static irqreturn_t nspintr(int irq, void *dev_id)
|
||||
tmp = -1;
|
||||
for (i = 0; i < data->MsgLen; i++) {
|
||||
tmp = data->MsgBuffer[i];
|
||||
if (data->MsgBuffer[i] == MSG_EXTENDED) {
|
||||
if (data->MsgBuffer[i] == EXTENDED_MESSAGE) {
|
||||
i += (1 + data->MsgBuffer[i+1]);
|
||||
}
|
||||
}
|
||||
|
@ -370,17 +370,6 @@ enum _burst_mode {
|
||||
BURST_MEM32 = 2,
|
||||
};
|
||||
|
||||
/**************************************************************************
|
||||
* SCSI messaage
|
||||
*/
|
||||
#define MSG_COMMAND_COMPLETE 0x00
|
||||
#define MSG_EXTENDED 0x01
|
||||
#define MSG_ABORT 0x06
|
||||
#define MSG_NO_OPERATION 0x08
|
||||
#define MSG_BUS_DEVICE_RESET 0x0c
|
||||
|
||||
#define MSG_EXT_SDTR 0x01
|
||||
|
||||
/* scatter-gather table */
|
||||
# define BUFFER_ADDR ((char *)((sg_virt(SCpnt->SCp.buffer))))
|
||||
|
||||
|
@ -3038,8 +3038,8 @@ void pm8001_mpi_set_nvmd_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
|
||||
complete(pm8001_ha->nvmd_completion);
|
||||
pm8001_dbg(pm8001_ha, MSG, "Set nvm data complete!\n");
|
||||
if ((dlen_status & NVMD_STAT) != 0) {
|
||||
pm8001_dbg(pm8001_ha, FAIL, "Set nvm data error!\n");
|
||||
return;
|
||||
pm8001_dbg(pm8001_ha, FAIL, "Set nvm data error %x\n",
|
||||
dlen_status);
|
||||
}
|
||||
ccb->task = NULL;
|
||||
ccb->ccb_tag = 0xFFFFFFFF;
|
||||
@ -3062,11 +3062,17 @@ pm8001_mpi_get_nvmd_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
|
||||
|
||||
pm8001_dbg(pm8001_ha, MSG, "Get nvm data complete!\n");
|
||||
if ((dlen_status & NVMD_STAT) != 0) {
|
||||
pm8001_dbg(pm8001_ha, FAIL, "Get nvm data error!\n");
|
||||
pm8001_dbg(pm8001_ha, FAIL, "Get nvm data error %x\n",
|
||||
dlen_status);
|
||||
complete(pm8001_ha->nvmd_completion);
|
||||
/* We should free tag during failure also, the tag is not being
|
||||
* freed by requesting path anywhere.
|
||||
*/
|
||||
ccb->task = NULL;
|
||||
ccb->ccb_tag = 0xFFFFFFFF;
|
||||
pm8001_tag_free(pm8001_ha, tag);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ir_tds_bn_dps_das_nvm & IPMode) {
|
||||
/* indirect mode - IR bit set */
|
||||
pm8001_dbg(pm8001_ha, MSG, "Get NVMD success, IR=1\n");
|
||||
@ -3179,7 +3185,7 @@ void pm8001_bytes_dmaed(struct pm8001_hba_info *pm8001_ha, int i)
|
||||
pm8001_dbg(pm8001_ha, MSG, "phy %d byte dmaded.\n", i);
|
||||
|
||||
sas_phy->frame_rcvd_size = phy->frame_rcvd_size;
|
||||
pm8001_ha->sas->notify_port_event(sas_phy, PORTE_BYTES_DMAED);
|
||||
sas_notify_port_event(sas_phy, PORTE_BYTES_DMAED, GFP_ATOMIC);
|
||||
}
|
||||
|
||||
/* Get the link rate speed */
|
||||
@ -3293,7 +3299,6 @@ hw_event_sas_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb)
|
||||
u32 npip_portstate = le32_to_cpu(pPayload->npip_portstate);
|
||||
u8 portstate = (u8)(npip_portstate & 0x0000000F);
|
||||
struct pm8001_port *port = &pm8001_ha->port[port_id];
|
||||
struct sas_ha_struct *sas_ha = pm8001_ha->sas;
|
||||
struct pm8001_phy *phy = &pm8001_ha->phy[phy_id];
|
||||
unsigned long flags;
|
||||
u8 deviceType = pPayload->sas_identify.dev_type;
|
||||
@ -3337,7 +3342,7 @@ hw_event_sas_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb)
|
||||
else if (phy->identify.device_type != SAS_PHY_UNUSED)
|
||||
phy->identify.target_port_protocols = SAS_PROTOCOL_SMP;
|
||||
phy->sas_phy.oob_mode = SAS_OOB_MODE;
|
||||
sas_ha->notify_phy_event(&phy->sas_phy, PHYE_OOB_DONE);
|
||||
sas_notify_phy_event(&phy->sas_phy, PHYE_OOB_DONE, GFP_ATOMIC);
|
||||
spin_lock_irqsave(&phy->sas_phy.frame_rcvd_lock, flags);
|
||||
memcpy(phy->frame_rcvd, &pPayload->sas_identify,
|
||||
sizeof(struct sas_identify_frame)-4);
|
||||
@ -3369,7 +3374,6 @@ hw_event_sata_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb)
|
||||
u32 npip_portstate = le32_to_cpu(pPayload->npip_portstate);
|
||||
u8 portstate = (u8)(npip_portstate & 0x0000000F);
|
||||
struct pm8001_port *port = &pm8001_ha->port[port_id];
|
||||
struct sas_ha_struct *sas_ha = pm8001_ha->sas;
|
||||
struct pm8001_phy *phy = &pm8001_ha->phy[phy_id];
|
||||
unsigned long flags;
|
||||
pm8001_dbg(pm8001_ha, DEVIO, "HW_EVENT_SATA_PHY_UP port id = %d, phy id = %d\n",
|
||||
@ -3381,7 +3385,7 @@ hw_event_sata_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb)
|
||||
phy->phy_type |= PORT_TYPE_SATA;
|
||||
phy->phy_attached = 1;
|
||||
phy->sas_phy.oob_mode = SATA_OOB_MODE;
|
||||
sas_ha->notify_phy_event(&phy->sas_phy, PHYE_OOB_DONE);
|
||||
sas_notify_phy_event(&phy->sas_phy, PHYE_OOB_DONE, GFP_ATOMIC);
|
||||
spin_lock_irqsave(&phy->sas_phy.frame_rcvd_lock, flags);
|
||||
memcpy(phy->frame_rcvd, ((u8 *)&pPayload->sata_fis - 4),
|
||||
sizeof(struct dev_to_host_fis));
|
||||
@ -3728,11 +3732,13 @@ static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void* piomb)
|
||||
break;
|
||||
case HW_EVENT_SATA_SPINUP_HOLD:
|
||||
pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_SATA_SPINUP_HOLD\n");
|
||||
sas_ha->notify_phy_event(&phy->sas_phy, PHYE_SPINUP_HOLD);
|
||||
sas_notify_phy_event(&phy->sas_phy, PHYE_SPINUP_HOLD,
|
||||
GFP_ATOMIC);
|
||||
break;
|
||||
case HW_EVENT_PHY_DOWN:
|
||||
pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_PHY_DOWN\n");
|
||||
sas_ha->notify_phy_event(&phy->sas_phy, PHYE_LOSS_OF_SIGNAL);
|
||||
sas_notify_phy_event(&phy->sas_phy, PHYE_LOSS_OF_SIGNAL,
|
||||
GFP_ATOMIC);
|
||||
phy->phy_attached = 0;
|
||||
phy->phy_state = 0;
|
||||
hw_event_phy_down(pm8001_ha, piomb);
|
||||
@ -3741,7 +3747,8 @@ static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void* piomb)
|
||||
pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_PORT_INVALID\n");
|
||||
sas_phy_disconnected(sas_phy);
|
||||
phy->phy_attached = 0;
|
||||
sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR);
|
||||
sas_notify_port_event(sas_phy, PORTE_LINK_RESET_ERR,
|
||||
GFP_ATOMIC);
|
||||
break;
|
||||
/* the broadcast change primitive received, tell the LIBSAS this event
|
||||
to revalidate the sas domain*/
|
||||
@ -3752,20 +3759,22 @@ static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void* piomb)
|
||||
spin_lock_irqsave(&sas_phy->sas_prim_lock, flags);
|
||||
sas_phy->sas_prim = HW_EVENT_BROADCAST_CHANGE;
|
||||
spin_unlock_irqrestore(&sas_phy->sas_prim_lock, flags);
|
||||
sas_ha->notify_port_event(sas_phy, PORTE_BROADCAST_RCVD);
|
||||
sas_notify_port_event(sas_phy, PORTE_BROADCAST_RCVD,
|
||||
GFP_ATOMIC);
|
||||
break;
|
||||
case HW_EVENT_PHY_ERROR:
|
||||
pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_PHY_ERROR\n");
|
||||
sas_phy_disconnected(&phy->sas_phy);
|
||||
phy->phy_attached = 0;
|
||||
sas_ha->notify_phy_event(&phy->sas_phy, PHYE_OOB_ERROR);
|
||||
sas_notify_phy_event(&phy->sas_phy, PHYE_OOB_ERROR, GFP_ATOMIC);
|
||||
break;
|
||||
case HW_EVENT_BROADCAST_EXP:
|
||||
pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_BROADCAST_EXP\n");
|
||||
spin_lock_irqsave(&sas_phy->sas_prim_lock, flags);
|
||||
sas_phy->sas_prim = HW_EVENT_BROADCAST_EXP;
|
||||
spin_unlock_irqrestore(&sas_phy->sas_prim_lock, flags);
|
||||
sas_ha->notify_port_event(sas_phy, PORTE_BROADCAST_RCVD);
|
||||
sas_notify_port_event(sas_phy, PORTE_BROADCAST_RCVD,
|
||||
GFP_ATOMIC);
|
||||
break;
|
||||
case HW_EVENT_LINK_ERR_INVALID_DWORD:
|
||||
pm8001_dbg(pm8001_ha, MSG,
|
||||
@ -3774,7 +3783,8 @@ static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void* piomb)
|
||||
HW_EVENT_LINK_ERR_INVALID_DWORD, port_id, phy_id, 0, 0);
|
||||
sas_phy_disconnected(sas_phy);
|
||||
phy->phy_attached = 0;
|
||||
sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR);
|
||||
sas_notify_port_event(sas_phy, PORTE_LINK_RESET_ERR,
|
||||
GFP_ATOMIC);
|
||||
break;
|
||||
case HW_EVENT_LINK_ERR_DISPARITY_ERROR:
|
||||
pm8001_dbg(pm8001_ha, MSG,
|
||||
@ -3784,7 +3794,8 @@ static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void* piomb)
|
||||
port_id, phy_id, 0, 0);
|
||||
sas_phy_disconnected(sas_phy);
|
||||
phy->phy_attached = 0;
|
||||
sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR);
|
||||
sas_notify_port_event(sas_phy, PORTE_LINK_RESET_ERR,
|
||||
GFP_ATOMIC);
|
||||
break;
|
||||
case HW_EVENT_LINK_ERR_CODE_VIOLATION:
|
||||
pm8001_dbg(pm8001_ha, MSG,
|
||||
@ -3794,7 +3805,8 @@ static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void* piomb)
|
||||
port_id, phy_id, 0, 0);
|
||||
sas_phy_disconnected(sas_phy);
|
||||
phy->phy_attached = 0;
|
||||
sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR);
|
||||
sas_notify_port_event(sas_phy, PORTE_LINK_RESET_ERR,
|
||||
GFP_ATOMIC);
|
||||
break;
|
||||
case HW_EVENT_LINK_ERR_LOSS_OF_DWORD_SYNCH:
|
||||
pm8001_dbg(pm8001_ha, MSG,
|
||||
@ -3804,7 +3816,8 @@ static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void* piomb)
|
||||
port_id, phy_id, 0, 0);
|
||||
sas_phy_disconnected(sas_phy);
|
||||
phy->phy_attached = 0;
|
||||
sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR);
|
||||
sas_notify_port_event(sas_phy, PORTE_LINK_RESET_ERR,
|
||||
GFP_ATOMIC);
|
||||
break;
|
||||
case HW_EVENT_MALFUNCTION:
|
||||
pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_MALFUNCTION\n");
|
||||
@ -3814,7 +3827,8 @@ static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void* piomb)
|
||||
spin_lock_irqsave(&sas_phy->sas_prim_lock, flags);
|
||||
sas_phy->sas_prim = HW_EVENT_BROADCAST_SES;
|
||||
spin_unlock_irqrestore(&sas_phy->sas_prim_lock, flags);
|
||||
sas_ha->notify_port_event(sas_phy, PORTE_BROADCAST_RCVD);
|
||||
sas_notify_port_event(sas_phy, PORTE_BROADCAST_RCVD,
|
||||
GFP_ATOMIC);
|
||||
break;
|
||||
case HW_EVENT_INBOUND_CRC_ERROR:
|
||||
pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_INBOUND_CRC_ERROR\n");
|
||||
@ -3824,13 +3838,14 @@ static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void* piomb)
|
||||
break;
|
||||
case HW_EVENT_HARD_RESET_RECEIVED:
|
||||
pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_HARD_RESET_RECEIVED\n");
|
||||
sas_ha->notify_port_event(sas_phy, PORTE_HARD_RESET);
|
||||
sas_notify_port_event(sas_phy, PORTE_HARD_RESET, GFP_ATOMIC);
|
||||
break;
|
||||
case HW_EVENT_ID_FRAME_TIMEOUT:
|
||||
pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_ID_FRAME_TIMEOUT\n");
|
||||
sas_phy_disconnected(sas_phy);
|
||||
phy->phy_attached = 0;
|
||||
sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR);
|
||||
sas_notify_port_event(sas_phy, PORTE_LINK_RESET_ERR,
|
||||
GFP_ATOMIC);
|
||||
break;
|
||||
case HW_EVENT_LINK_ERR_PHY_RESET_FAILED:
|
||||
pm8001_dbg(pm8001_ha, MSG,
|
||||
@ -3840,20 +3855,23 @@ static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void* piomb)
|
||||
port_id, phy_id, 0, 0);
|
||||
sas_phy_disconnected(sas_phy);
|
||||
phy->phy_attached = 0;
|
||||
sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR);
|
||||
sas_notify_port_event(sas_phy, PORTE_LINK_RESET_ERR,
|
||||
GFP_ATOMIC);
|
||||
break;
|
||||
case HW_EVENT_PORT_RESET_TIMER_TMO:
|
||||
pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_PORT_RESET_TIMER_TMO\n");
|
||||
sas_phy_disconnected(sas_phy);
|
||||
phy->phy_attached = 0;
|
||||
sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR);
|
||||
sas_notify_port_event(sas_phy, PORTE_LINK_RESET_ERR,
|
||||
GFP_ATOMIC);
|
||||
break;
|
||||
case HW_EVENT_PORT_RECOVERY_TIMER_TMO:
|
||||
pm8001_dbg(pm8001_ha, MSG,
|
||||
"HW_EVENT_PORT_RECOVERY_TIMER_TMO\n");
|
||||
sas_phy_disconnected(sas_phy);
|
||||
phy->phy_attached = 0;
|
||||
sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR);
|
||||
sas_notify_port_event(sas_phy, PORTE_LINK_RESET_ERR,
|
||||
GFP_ATOMIC);
|
||||
break;
|
||||
case HW_EVENT_PORT_RECOVER:
|
||||
pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_PORT_RECOVER\n");
|
||||
@ -4998,4 +5016,5 @@ const struct pm8001_dispatch pm8001_8001_dispatch = {
|
||||
.fw_flash_update_req = pm8001_chip_fw_flash_update_req,
|
||||
.set_dev_state_req = pm8001_chip_set_dev_state_req,
|
||||
.sas_re_init_req = pm8001_chip_sas_re_initialization,
|
||||
.fatal_errors = pm80xx_fatal_errors,
|
||||
};
|
||||
|
@ -423,7 +423,7 @@ static int pm8001_alloc(struct pm8001_hba_info *pm8001_ha,
|
||||
err_out_nodev:
|
||||
for (i = 0; i < pm8001_ha->max_memcnt; i++) {
|
||||
if (pm8001_ha->memoryMap.region[i].virt_ptr != NULL) {
|
||||
pci_free_consistent(pm8001_ha->pdev,
|
||||
dma_free_coherent(&pm8001_ha->pdev->dev,
|
||||
(pm8001_ha->memoryMap.region[i].total_len +
|
||||
pm8001_ha->memoryMap.region[i].alignment),
|
||||
pm8001_ha->memoryMap.region[i].virt_ptr,
|
||||
@ -466,9 +466,12 @@ static int pm8001_ioremap(struct pm8001_hba_info *pm8001_ha)
|
||||
pm8001_ha->io_mem[logicalBar].memvirtaddr =
|
||||
ioremap(pm8001_ha->io_mem[logicalBar].membase,
|
||||
pm8001_ha->io_mem[logicalBar].memsize);
|
||||
pm8001_dbg(pm8001_ha, INIT,
|
||||
"PCI: bar %d, logicalBar %d\n",
|
||||
if (!pm8001_ha->io_mem[logicalBar].memvirtaddr) {
|
||||
pm8001_dbg(pm8001_ha, INIT,
|
||||
"Failed to ioremap bar %d, logicalBar %d",
|
||||
bar, logicalBar);
|
||||
return -ENOMEM;
|
||||
}
|
||||
pm8001_dbg(pm8001_ha, INIT,
|
||||
"base addr %llx virt_addr=%llx len=%d\n",
|
||||
(u64)pm8001_ha->io_mem[logicalBar].membase,
|
||||
@ -540,9 +543,11 @@ static struct pm8001_hba_info *pm8001_pci_alloc(struct pci_dev *pdev,
|
||||
tasklet_init(&pm8001_ha->tasklet[j], pm8001_tasklet,
|
||||
(unsigned long)&(pm8001_ha->irq_vector[j]));
|
||||
#endif
|
||||
pm8001_ioremap(pm8001_ha);
|
||||
if (pm8001_ioremap(pm8001_ha))
|
||||
goto failed_pci_alloc;
|
||||
if (!pm8001_alloc(pm8001_ha, ent))
|
||||
return pm8001_ha;
|
||||
failed_pci_alloc:
|
||||
pm8001_free(pm8001_ha);
|
||||
return NULL;
|
||||
}
|
||||
@ -1192,12 +1197,13 @@ pm8001_init_ccb_tag(struct pm8001_hba_info *pm8001_ha, struct Scsi_Host *shost,
|
||||
goto err_out_noccb;
|
||||
}
|
||||
for (i = 0; i < ccb_count; i++) {
|
||||
pm8001_ha->ccb_info[i].buf_prd = pci_alloc_consistent(pdev,
|
||||
pm8001_ha->ccb_info[i].buf_prd = dma_alloc_coherent(&pdev->dev,
|
||||
sizeof(struct pm8001_prd) * PM8001_MAX_DMA_SG,
|
||||
&pm8001_ha->ccb_info[i].ccb_dma_handle);
|
||||
&pm8001_ha->ccb_info[i].ccb_dma_handle,
|
||||
GFP_KERNEL);
|
||||
if (!pm8001_ha->ccb_info[i].buf_prd) {
|
||||
pm8001_dbg(pm8001_ha, FAIL,
|
||||
"pm80xx: ccb prd memory allocation error\n");
|
||||
"ccb prd memory allocation error\n");
|
||||
goto err_out;
|
||||
}
|
||||
pm8001_ha->ccb_info[i].task = NULL;
|
||||
|
@ -158,7 +158,6 @@ int pm8001_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func,
|
||||
int rc = 0, phy_id = sas_phy->id;
|
||||
struct pm8001_hba_info *pm8001_ha = NULL;
|
||||
struct sas_phy_linkrates *rates;
|
||||
struct sas_ha_struct *sas_ha;
|
||||
struct pm8001_phy *phy;
|
||||
DECLARE_COMPLETION_ONSTACK(completion);
|
||||
unsigned long flags;
|
||||
@ -207,19 +206,17 @@ int pm8001_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func,
|
||||
if (pm8001_ha->chip_id != chip_8001) {
|
||||
if (pm8001_ha->phy[phy_id].phy_state ==
|
||||
PHY_STATE_LINK_UP_SPCV) {
|
||||
sas_ha = pm8001_ha->sas;
|
||||
sas_phy_disconnected(&phy->sas_phy);
|
||||
sas_ha->notify_phy_event(&phy->sas_phy,
|
||||
PHYE_LOSS_OF_SIGNAL);
|
||||
sas_notify_phy_event(&phy->sas_phy,
|
||||
PHYE_LOSS_OF_SIGNAL, GFP_KERNEL);
|
||||
phy->phy_attached = 0;
|
||||
}
|
||||
} else {
|
||||
if (pm8001_ha->phy[phy_id].phy_state ==
|
||||
PHY_STATE_LINK_UP_SPC) {
|
||||
sas_ha = pm8001_ha->sas;
|
||||
sas_phy_disconnected(&phy->sas_phy);
|
||||
sas_ha->notify_phy_event(&phy->sas_phy,
|
||||
PHYE_LOSS_OF_SIGNAL);
|
||||
sas_notify_phy_event(&phy->sas_phy,
|
||||
PHYE_LOSS_OF_SIGNAL, GFP_KERNEL);
|
||||
phy->phy_attached = 0;
|
||||
}
|
||||
}
|
||||
@ -1183,12 +1180,21 @@ int pm8001_abort_task(struct sas_task *task)
|
||||
int rc = TMF_RESP_FUNC_FAILED, ret;
|
||||
u32 phy_id;
|
||||
struct sas_task_slow slow_task;
|
||||
|
||||
if (unlikely(!task || !task->lldd_task || !task->dev))
|
||||
return TMF_RESP_FUNC_FAILED;
|
||||
|
||||
dev = task->dev;
|
||||
pm8001_dev = dev->lldd_dev;
|
||||
pm8001_ha = pm8001_find_ha_by_dev(dev);
|
||||
phy_id = pm8001_dev->attached_phy;
|
||||
|
||||
if (PM8001_CHIP_DISP->fatal_errors(pm8001_ha)) {
|
||||
// If the controller is seeing fatal errors
|
||||
// abort task will not get a response from the controller
|
||||
return TMF_RESP_FUNC_FAILED;
|
||||
}
|
||||
|
||||
ret = pm8001_find_tag(task, &tag);
|
||||
if (ret == 0) {
|
||||
pm8001_info(pm8001_ha, "no tag for task:%p\n", task);
|
||||
@ -1344,4 +1350,3 @@ int pm8001_clear_task_set(struct domain_device *dev, u8 *lun)
|
||||
tmf_task.tmf = TMF_CLEAR_TASK_SET;
|
||||
return pm8001_issue_ssp_tmf(dev, lun, &tmf_task);
|
||||
}
|
||||
|
||||
|
@ -215,6 +215,7 @@ struct pm8001_dispatch {
|
||||
int (*sas_diag_execute_req)(struct pm8001_hba_info *pm8001_ha,
|
||||
u32 state);
|
||||
int (*sas_re_init_req)(struct pm8001_hba_info *pm8001_ha);
|
||||
int (*fatal_errors)(struct pm8001_hba_info *pm8001_ha);
|
||||
};
|
||||
|
||||
struct pm8001_chip_info {
|
||||
@ -725,6 +726,7 @@ ssize_t pm80xx_get_fatal_dump(struct device *cdev,
|
||||
ssize_t pm80xx_get_non_fatal_dump(struct device *cdev,
|
||||
struct device_attribute *attr, char *buf);
|
||||
ssize_t pm8001_get_gsm_dump(struct device *cdev, u32, char *buf);
|
||||
int pm80xx_fatal_errors(struct pm8001_hba_info *pm8001_ha);
|
||||
/* ctl shared API */
|
||||
extern struct device_attribute *pm8001_host_attrs[];
|
||||
|
||||
|
@ -349,37 +349,37 @@ ssize_t pm80xx_get_fatal_dump(struct device *cdev,
|
||||
sprintf(
|
||||
pm8001_ha->forensic_info.data_buf.direct_data,
|
||||
"%08x ", 0xFFFFFFFF);
|
||||
pm8001_cw32(pm8001_ha, 0,
|
||||
return((char *)pm8001_ha->forensic_info.data_buf.direct_data -
|
||||
(char *)buf);
|
||||
}
|
||||
/* reset fatal_forensic_shift_offset back to zero and reset MEMBASE 2 register to zero */
|
||||
pm8001_ha->fatal_forensic_shift_offset = 0; /* location in 64k region */
|
||||
pm8001_cw32(pm8001_ha, 0,
|
||||
MEMBASE_II_SHIFT_REGISTER,
|
||||
pm8001_ha->fatal_forensic_shift_offset);
|
||||
}
|
||||
/* Read the next block of the debug data.*/
|
||||
length_to_read = pm8001_mr32(fatal_table_address,
|
||||
MPI_FATAL_EDUMP_TABLE_ACCUM_LEN) -
|
||||
pm8001_ha->forensic_preserved_accumulated_transfer;
|
||||
if (length_to_read != 0x0) {
|
||||
pm8001_ha->forensic_fatal_step = 0;
|
||||
goto moreData;
|
||||
} else {
|
||||
pm8001_ha->forensic_info.data_buf.direct_data +=
|
||||
sprintf(
|
||||
pm8001_ha->forensic_info.data_buf.direct_data,
|
||||
}
|
||||
/* Read the next block of the debug data.*/
|
||||
length_to_read = pm8001_mr32(fatal_table_address,
|
||||
MPI_FATAL_EDUMP_TABLE_ACCUM_LEN) -
|
||||
pm8001_ha->forensic_preserved_accumulated_transfer;
|
||||
if (length_to_read != 0x0) {
|
||||
pm8001_ha->forensic_fatal_step = 0;
|
||||
goto moreData;
|
||||
} else {
|
||||
pm8001_ha->forensic_info.data_buf.direct_data +=
|
||||
sprintf(pm8001_ha->forensic_info.data_buf.direct_data,
|
||||
"%08x ", 4);
|
||||
pm8001_ha->forensic_info.data_buf.read_len
|
||||
= 0xFFFFFFFF;
|
||||
pm8001_ha->forensic_info.data_buf.direct_len
|
||||
= 0;
|
||||
pm8001_ha->forensic_info.data_buf.direct_offset
|
||||
= 0;
|
||||
pm8001_ha->forensic_info.data_buf.read_len = 0;
|
||||
}
|
||||
pm8001_ha->forensic_info.data_buf.read_len = 0xFFFFFFFF;
|
||||
pm8001_ha->forensic_info.data_buf.direct_len = 0;
|
||||
pm8001_ha->forensic_info.data_buf.direct_offset = 0;
|
||||
pm8001_ha->forensic_info.data_buf.read_len = 0;
|
||||
}
|
||||
}
|
||||
offset = (int)((char *)pm8001_ha->forensic_info.data_buf.direct_data
|
||||
- (char *)buf);
|
||||
pm8001_dbg(pm8001_ha, IO, "get_fatal_spcv: return4 0x%x\n", offset);
|
||||
return (char *)pm8001_ha->forensic_info.data_buf.direct_data -
|
||||
(char *)buf;
|
||||
return ((char *)pm8001_ha->forensic_info.data_buf.direct_data -
|
||||
(char *)buf);
|
||||
}
|
||||
|
||||
/* pm80xx_get_non_fatal_dump - dump the nonfatal data from the dma
|
||||
@ -997,7 +997,7 @@ static int mpi_init_check(struct pm8001_hba_info *pm8001_ha)
|
||||
max_wait_count = SPC_DOORBELL_CLEAR_TIMEOUT;
|
||||
}
|
||||
do {
|
||||
udelay(1);
|
||||
msleep(FW_READY_INTERVAL);
|
||||
value = pm8001_cr32(pm8001_ha, 0, MSGU_IBDB_SET);
|
||||
value &= SPCv_MSGU_CFG_TABLE_UPDATE;
|
||||
} while ((value != 0) && (--max_wait_count));
|
||||
@ -1010,9 +1010,9 @@ static int mpi_init_check(struct pm8001_hba_info *pm8001_ha)
|
||||
return -EBUSY;
|
||||
}
|
||||
/* check the MPI-State for initialization upto 100ms*/
|
||||
max_wait_count = 100 * 1000;/* 100 msec */
|
||||
max_wait_count = 5;/* 100 msec */
|
||||
do {
|
||||
udelay(1);
|
||||
msleep(FW_READY_INTERVAL);
|
||||
gst_len_mpistate =
|
||||
pm8001_mr32(pm8001_ha->general_stat_tbl_addr,
|
||||
GST_GSTLEN_MPIS_OFFSET);
|
||||
@ -1039,6 +1039,7 @@ static int check_fw_ready(struct pm8001_hba_info *pm8001_ha)
|
||||
u32 value;
|
||||
u32 max_wait_count;
|
||||
u32 max_wait_time;
|
||||
u32 expected_mask;
|
||||
int ret = 0;
|
||||
|
||||
/* reset / PCIe ready */
|
||||
@ -1048,74 +1049,39 @@ static int check_fw_ready(struct pm8001_hba_info *pm8001_ha)
|
||||
value = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_1);
|
||||
} while ((value == 0xFFFFFFFF) && (--max_wait_count));
|
||||
|
||||
/* check ila status */
|
||||
max_wait_time = max_wait_count = 50; /* 1000 milli sec */
|
||||
do {
|
||||
msleep(FW_READY_INTERVAL);
|
||||
value = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_1);
|
||||
} while (((value & SCRATCH_PAD_ILA_READY) !=
|
||||
SCRATCH_PAD_ILA_READY) && (--max_wait_count));
|
||||
if (!max_wait_count)
|
||||
ret = -1;
|
||||
else {
|
||||
pm8001_dbg(pm8001_ha, MSG,
|
||||
" ila ready status in %d millisec\n",
|
||||
(max_wait_time - max_wait_count));
|
||||
}
|
||||
|
||||
/* check RAAE status */
|
||||
max_wait_time = max_wait_count = 90; /* 1800 milli sec */
|
||||
do {
|
||||
msleep(FW_READY_INTERVAL);
|
||||
value = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_1);
|
||||
} while (((value & SCRATCH_PAD_RAAE_READY) !=
|
||||
SCRATCH_PAD_RAAE_READY) && (--max_wait_count));
|
||||
if (!max_wait_count)
|
||||
ret = -1;
|
||||
else {
|
||||
pm8001_dbg(pm8001_ha, MSG,
|
||||
" raae ready status in %d millisec\n",
|
||||
(max_wait_time - max_wait_count));
|
||||
}
|
||||
|
||||
/* check iop0 status */
|
||||
max_wait_time = max_wait_count = 30; /* 600 milli sec */
|
||||
do {
|
||||
msleep(FW_READY_INTERVAL);
|
||||
value = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_1);
|
||||
} while (((value & SCRATCH_PAD_IOP0_READY) != SCRATCH_PAD_IOP0_READY) &&
|
||||
(--max_wait_count));
|
||||
if (!max_wait_count)
|
||||
ret = -1;
|
||||
else {
|
||||
pm8001_dbg(pm8001_ha, MSG,
|
||||
" iop0 ready status in %d millisec\n",
|
||||
(max_wait_time - max_wait_count));
|
||||
}
|
||||
|
||||
/* check iop1 status only for 16 port controllers */
|
||||
/* check ila, RAAE and iops status */
|
||||
if ((pm8001_ha->chip_id != chip_8008) &&
|
||||
(pm8001_ha->chip_id != chip_8009)) {
|
||||
/* 200 milli sec */
|
||||
max_wait_time = max_wait_count = 10;
|
||||
do {
|
||||
msleep(FW_READY_INTERVAL);
|
||||
value = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_1);
|
||||
} while (((value & SCRATCH_PAD_IOP1_READY) !=
|
||||
SCRATCH_PAD_IOP1_READY) && (--max_wait_count));
|
||||
if (!max_wait_count)
|
||||
ret = -1;
|
||||
else {
|
||||
pm8001_dbg(pm8001_ha, MSG,
|
||||
"iop1 ready status in %d millisec\n",
|
||||
(max_wait_time - max_wait_count));
|
||||
}
|
||||
max_wait_time = max_wait_count = 180; /* 3600 milli sec */
|
||||
expected_mask = SCRATCH_PAD_ILA_READY |
|
||||
SCRATCH_PAD_RAAE_READY |
|
||||
SCRATCH_PAD_IOP0_READY |
|
||||
SCRATCH_PAD_IOP1_READY;
|
||||
} else {
|
||||
max_wait_time = max_wait_count = 170; /* 3400 milli sec */
|
||||
expected_mask = SCRATCH_PAD_ILA_READY |
|
||||
SCRATCH_PAD_RAAE_READY |
|
||||
SCRATCH_PAD_IOP0_READY;
|
||||
}
|
||||
do {
|
||||
msleep(FW_READY_INTERVAL);
|
||||
value = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_1);
|
||||
} while (((value & expected_mask) !=
|
||||
expected_mask) && (--max_wait_count));
|
||||
if (!max_wait_count) {
|
||||
pm8001_dbg(pm8001_ha, INIT,
|
||||
"At least one FW component failed to load within %d millisec: Scratchpad1: 0x%x\n",
|
||||
max_wait_time * FW_READY_INTERVAL, value);
|
||||
ret = -1;
|
||||
} else {
|
||||
pm8001_dbg(pm8001_ha, MSG,
|
||||
"All FW components ready by %d ms\n",
|
||||
(max_wait_time - max_wait_count) * FW_READY_INTERVAL);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void init_pci_device_addresses(struct pm8001_hba_info *pm8001_ha)
|
||||
static int init_pci_device_addresses(struct pm8001_hba_info *pm8001_ha)
|
||||
{
|
||||
void __iomem *base_addr;
|
||||
u32 value;
|
||||
@ -1124,15 +1090,48 @@ static void init_pci_device_addresses(struct pm8001_hba_info *pm8001_ha)
|
||||
u32 pcilogic;
|
||||
|
||||
value = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_0);
|
||||
|
||||
/**
|
||||
* lower 26 bits of SCRATCHPAD0 register describes offset within the
|
||||
* PCIe BAR where the MPI configuration table is present
|
||||
*/
|
||||
offset = value & 0x03FFFFFF; /* scratch pad 0 TBL address */
|
||||
|
||||
pm8001_dbg(pm8001_ha, DEV, "Scratchpad 0 Offset: 0x%x value 0x%x\n",
|
||||
offset, value);
|
||||
/**
|
||||
* Upper 6 bits describe the offset within PCI config space where BAR
|
||||
* is located.
|
||||
*/
|
||||
pcilogic = (value & 0xFC000000) >> 26;
|
||||
pcibar = get_pci_bar_index(pcilogic);
|
||||
pm8001_dbg(pm8001_ha, INIT, "Scratchpad 0 PCI BAR: %d\n", pcibar);
|
||||
|
||||
/**
|
||||
* Make sure the offset falls inside the ioremapped PCI BAR
|
||||
*/
|
||||
if (offset > pm8001_ha->io_mem[pcibar].memsize) {
|
||||
pm8001_dbg(pm8001_ha, FAIL,
|
||||
"Main cfg tbl offset outside %u > %u\n",
|
||||
offset, pm8001_ha->io_mem[pcibar].memsize);
|
||||
return -EBUSY;
|
||||
}
|
||||
pm8001_ha->main_cfg_tbl_addr = base_addr =
|
||||
pm8001_ha->io_mem[pcibar].memvirtaddr + offset;
|
||||
|
||||
/**
|
||||
* Validate main configuration table address: first DWord should read
|
||||
* "PMCS"
|
||||
*/
|
||||
value = pm8001_mr32(pm8001_ha->main_cfg_tbl_addr, 0);
|
||||
if (memcmp(&value, "PMCS", 4) != 0) {
|
||||
pm8001_dbg(pm8001_ha, FAIL,
|
||||
"BAD main config signature 0x%x\n",
|
||||
value);
|
||||
return -EBUSY;
|
||||
}
|
||||
pm8001_dbg(pm8001_ha, INIT,
|
||||
"VALID main config signature 0x%x\n", value);
|
||||
pm8001_ha->general_stat_tbl_addr =
|
||||
base_addr + (pm8001_cr32(pm8001_ha, pcibar, offset + 0x18) &
|
||||
0xFFFFFF);
|
||||
@ -1171,6 +1170,7 @@ static void init_pci_device_addresses(struct pm8001_hba_info *pm8001_ha)
|
||||
pm8001_dbg(pm8001_ha, INIT, "addr - pspa %p ivt %p\n",
|
||||
pm8001_ha->pspa_q_tbl_addr,
|
||||
pm8001_ha->ivt_tbl_addr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1438,7 +1438,12 @@ static int pm80xx_chip_init(struct pm8001_hba_info *pm8001_ha)
|
||||
pm8001_ha->controller_fatal_error = false;
|
||||
|
||||
/* Initialize pci space address eg: mpi offset */
|
||||
init_pci_device_addresses(pm8001_ha);
|
||||
ret = init_pci_device_addresses(pm8001_ha);
|
||||
if (ret) {
|
||||
pm8001_dbg(pm8001_ha, FAIL,
|
||||
"Failed to init pci addresses");
|
||||
return ret;
|
||||
}
|
||||
init_default_table_values(pm8001_ha);
|
||||
read_main_config_table(pm8001_ha);
|
||||
read_general_status_table(pm8001_ha);
|
||||
@ -1482,7 +1487,15 @@ static int mpi_uninit_check(struct pm8001_hba_info *pm8001_ha)
|
||||
u32 max_wait_count;
|
||||
u32 value;
|
||||
u32 gst_len_mpistate;
|
||||
init_pci_device_addresses(pm8001_ha);
|
||||
int ret;
|
||||
|
||||
ret = init_pci_device_addresses(pm8001_ha);
|
||||
if (ret) {
|
||||
pm8001_dbg(pm8001_ha, FAIL,
|
||||
"Failed to init pci addresses");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Write bit1=1 to Inbound DoorBell Register to tell the SPC FW the
|
||||
table is stop */
|
||||
pm8001_cw32(pm8001_ha, 0, MSGU_IBDB_SET, SPCv_MSGU_CFG_TABLE_RESET);
|
||||
@ -1525,6 +1538,41 @@ static int mpi_uninit_check(struct pm8001_hba_info *pm8001_ha)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* pm80xx_fatal_errors - returns non zero *ONLY* when fatal errors
|
||||
* @pm8001_ha: our hba card information
|
||||
*
|
||||
* Fatal errors are recoverable only after a host reboot.
|
||||
*/
|
||||
int
|
||||
pm80xx_fatal_errors(struct pm8001_hba_info *pm8001_ha)
|
||||
{
|
||||
int ret = 0;
|
||||
u32 scratch_pad_rsvd0 = pm8001_cr32(pm8001_ha, 0,
|
||||
MSGU_HOST_SCRATCH_PAD_6);
|
||||
u32 scratch_pad_rsvd1 = pm8001_cr32(pm8001_ha, 0,
|
||||
MSGU_HOST_SCRATCH_PAD_7);
|
||||
u32 scratch_pad1 = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_1);
|
||||
u32 scratch_pad2 = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_2);
|
||||
u32 scratch_pad3 = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_3);
|
||||
|
||||
if (pm8001_ha->chip_id != chip_8006 &&
|
||||
pm8001_ha->chip_id != chip_8074 &&
|
||||
pm8001_ha->chip_id != chip_8076) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (MSGU_SCRATCHPAD1_STATE_FATAL_ERROR(scratch_pad1)) {
|
||||
pm8001_dbg(pm8001_ha, FAIL,
|
||||
"Fatal error SCRATCHPAD1 = 0x%x SCRATCHPAD2 = 0x%x SCRATCHPAD3 = 0x%x SCRATCHPAD_RSVD0 = 0x%x SCRATCHPAD_RSVD1 = 0x%x\n",
|
||||
scratch_pad1, scratch_pad2, scratch_pad3,
|
||||
scratch_pad_rsvd0, scratch_pad_rsvd1);
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* pm8001_chip_soft_rst - soft reset the PM8001 chip, so that the clear all
|
||||
* the FW register status to the originated status.
|
||||
@ -2385,10 +2433,11 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
|
||||
return;
|
||||
}
|
||||
|
||||
if (unlikely(status))
|
||||
pm8001_dbg(pm8001_ha, IOERR,
|
||||
"status:0x%x, tag:0x%x, task::0x%p\n",
|
||||
status, tag, t);
|
||||
if (status != IO_SUCCESS) {
|
||||
pm8001_dbg(pm8001_ha, FAIL,
|
||||
"IO failed device_id %u status 0x%x tag %d\n",
|
||||
pm8001_dev->device_id, status, tag);
|
||||
}
|
||||
|
||||
/* Print sas address of IO failed device */
|
||||
if ((status != IO_SUCCESS) && (status != IO_OVERFLOW) &&
|
||||
@ -2710,7 +2759,9 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
|
||||
atomic_dec(&pm8001_dev->running_req);
|
||||
break;
|
||||
default:
|
||||
pm8001_dbg(pm8001_ha, DEVIO, "Unknown status 0x%x\n", status);
|
||||
pm8001_dbg(pm8001_ha, DEVIO,
|
||||
"Unknown status device_id %u status 0x%x tag %d\n",
|
||||
pm8001_dev->device_id, status, tag);
|
||||
/* not allowed case. Therefore, return failed status */
|
||||
ts->resp = SAS_TASK_COMPLETE;
|
||||
ts->stat = SAS_DEV_NO_RESPONSE;
|
||||
@ -3243,7 +3294,6 @@ hw_event_sas_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb)
|
||||
u8 portstate = (u8)(phyid_npip_portstate & 0x0000000F);
|
||||
|
||||
struct pm8001_port *port = &pm8001_ha->port[port_id];
|
||||
struct sas_ha_struct *sas_ha = pm8001_ha->sas;
|
||||
struct pm8001_phy *phy = &pm8001_ha->phy[phy_id];
|
||||
unsigned long flags;
|
||||
u8 deviceType = pPayload->sas_identify.dev_type;
|
||||
@ -3288,7 +3338,7 @@ hw_event_sas_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb)
|
||||
else if (phy->identify.device_type != SAS_PHY_UNUSED)
|
||||
phy->identify.target_port_protocols = SAS_PROTOCOL_SMP;
|
||||
phy->sas_phy.oob_mode = SAS_OOB_MODE;
|
||||
sas_ha->notify_phy_event(&phy->sas_phy, PHYE_OOB_DONE);
|
||||
sas_notify_phy_event(&phy->sas_phy, PHYE_OOB_DONE, GFP_ATOMIC);
|
||||
spin_lock_irqsave(&phy->sas_phy.frame_rcvd_lock, flags);
|
||||
memcpy(phy->frame_rcvd, &pPayload->sas_identify,
|
||||
sizeof(struct sas_identify_frame)-4);
|
||||
@ -3322,7 +3372,6 @@ hw_event_sata_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb)
|
||||
u8 portstate = (u8)(phyid_npip_portstate & 0x0000000F);
|
||||
|
||||
struct pm8001_port *port = &pm8001_ha->port[port_id];
|
||||
struct sas_ha_struct *sas_ha = pm8001_ha->sas;
|
||||
struct pm8001_phy *phy = &pm8001_ha->phy[phy_id];
|
||||
unsigned long flags;
|
||||
pm8001_dbg(pm8001_ha, DEVIO,
|
||||
@ -3336,7 +3385,7 @@ hw_event_sata_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb)
|
||||
phy->phy_type |= PORT_TYPE_SATA;
|
||||
phy->phy_attached = 1;
|
||||
phy->sas_phy.oob_mode = SATA_OOB_MODE;
|
||||
sas_ha->notify_phy_event(&phy->sas_phy, PHYE_OOB_DONE);
|
||||
sas_notify_phy_event(&phy->sas_phy, PHYE_OOB_DONE, GFP_ATOMIC);
|
||||
spin_lock_irqsave(&phy->sas_phy.frame_rcvd_lock, flags);
|
||||
memcpy(phy->frame_rcvd, ((u8 *)&pPayload->sata_fis - 4),
|
||||
sizeof(struct dev_to_host_fis));
|
||||
@ -3418,11 +3467,9 @@ hw_event_phy_down(struct pm8001_hba_info *pm8001_ha, void *piomb)
|
||||
break;
|
||||
|
||||
}
|
||||
if (port_sata && (portstate != PORT_IN_RESET)) {
|
||||
struct sas_ha_struct *sas_ha = pm8001_ha->sas;
|
||||
|
||||
sas_ha->notify_phy_event(&phy->sas_phy, PHYE_LOSS_OF_SIGNAL);
|
||||
}
|
||||
if (port_sata && (portstate != PORT_IN_RESET))
|
||||
sas_notify_phy_event(&phy->sas_phy, PHYE_LOSS_OF_SIGNAL,
|
||||
GFP_ATOMIC);
|
||||
}
|
||||
|
||||
static int mpi_phy_start_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
|
||||
@ -3520,7 +3567,8 @@ static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void *piomb)
|
||||
break;
|
||||
case HW_EVENT_SATA_SPINUP_HOLD:
|
||||
pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_SATA_SPINUP_HOLD\n");
|
||||
sas_ha->notify_phy_event(&phy->sas_phy, PHYE_SPINUP_HOLD);
|
||||
sas_notify_phy_event(&phy->sas_phy, PHYE_SPINUP_HOLD,
|
||||
GFP_ATOMIC);
|
||||
break;
|
||||
case HW_EVENT_PHY_DOWN:
|
||||
pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_PHY_DOWN\n");
|
||||
@ -3536,7 +3584,8 @@ static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void *piomb)
|
||||
pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_PORT_INVALID\n");
|
||||
sas_phy_disconnected(sas_phy);
|
||||
phy->phy_attached = 0;
|
||||
sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR);
|
||||
sas_notify_port_event(sas_phy, PORTE_LINK_RESET_ERR,
|
||||
GFP_ATOMIC);
|
||||
break;
|
||||
/* the broadcast change primitive received, tell the LIBSAS this event
|
||||
to revalidate the sas domain*/
|
||||
@ -3547,20 +3596,22 @@ static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void *piomb)
|
||||
spin_lock_irqsave(&sas_phy->sas_prim_lock, flags);
|
||||
sas_phy->sas_prim = HW_EVENT_BROADCAST_CHANGE;
|
||||
spin_unlock_irqrestore(&sas_phy->sas_prim_lock, flags);
|
||||
sas_ha->notify_port_event(sas_phy, PORTE_BROADCAST_RCVD);
|
||||
sas_notify_port_event(sas_phy, PORTE_BROADCAST_RCVD,
|
||||
GFP_ATOMIC);
|
||||
break;
|
||||
case HW_EVENT_PHY_ERROR:
|
||||
pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_PHY_ERROR\n");
|
||||
sas_phy_disconnected(&phy->sas_phy);
|
||||
phy->phy_attached = 0;
|
||||
sas_ha->notify_phy_event(&phy->sas_phy, PHYE_OOB_ERROR);
|
||||
sas_notify_phy_event(&phy->sas_phy, PHYE_OOB_ERROR, GFP_ATOMIC);
|
||||
break;
|
||||
case HW_EVENT_BROADCAST_EXP:
|
||||
pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_BROADCAST_EXP\n");
|
||||
spin_lock_irqsave(&sas_phy->sas_prim_lock, flags);
|
||||
sas_phy->sas_prim = HW_EVENT_BROADCAST_EXP;
|
||||
spin_unlock_irqrestore(&sas_phy->sas_prim_lock, flags);
|
||||
sas_ha->notify_port_event(sas_phy, PORTE_BROADCAST_RCVD);
|
||||
sas_notify_port_event(sas_phy, PORTE_BROADCAST_RCVD,
|
||||
GFP_ATOMIC);
|
||||
break;
|
||||
case HW_EVENT_LINK_ERR_INVALID_DWORD:
|
||||
pm8001_dbg(pm8001_ha, MSG,
|
||||
@ -3597,7 +3648,8 @@ static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void *piomb)
|
||||
spin_lock_irqsave(&sas_phy->sas_prim_lock, flags);
|
||||
sas_phy->sas_prim = HW_EVENT_BROADCAST_SES;
|
||||
spin_unlock_irqrestore(&sas_phy->sas_prim_lock, flags);
|
||||
sas_ha->notify_port_event(sas_phy, PORTE_BROADCAST_RCVD);
|
||||
sas_notify_port_event(sas_phy, PORTE_BROADCAST_RCVD,
|
||||
GFP_ATOMIC);
|
||||
break;
|
||||
case HW_EVENT_INBOUND_CRC_ERROR:
|
||||
pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_INBOUND_CRC_ERROR\n");
|
||||
@ -3607,13 +3659,14 @@ static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void *piomb)
|
||||
break;
|
||||
case HW_EVENT_HARD_RESET_RECEIVED:
|
||||
pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_HARD_RESET_RECEIVED\n");
|
||||
sas_ha->notify_port_event(sas_phy, PORTE_HARD_RESET);
|
||||
sas_notify_port_event(sas_phy, PORTE_HARD_RESET, GFP_ATOMIC);
|
||||
break;
|
||||
case HW_EVENT_ID_FRAME_TIMEOUT:
|
||||
pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_ID_FRAME_TIMEOUT\n");
|
||||
sas_phy_disconnected(sas_phy);
|
||||
phy->phy_attached = 0;
|
||||
sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR);
|
||||
sas_notify_port_event(sas_phy, PORTE_LINK_RESET_ERR,
|
||||
GFP_ATOMIC);
|
||||
break;
|
||||
case HW_EVENT_LINK_ERR_PHY_RESET_FAILED:
|
||||
pm8001_dbg(pm8001_ha, MSG,
|
||||
@ -3623,7 +3676,8 @@ static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void *piomb)
|
||||
port_id, phy_id, 0, 0);
|
||||
sas_phy_disconnected(sas_phy);
|
||||
phy->phy_attached = 0;
|
||||
sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR);
|
||||
sas_notify_port_event(sas_phy, PORTE_LINK_RESET_ERR,
|
||||
GFP_ATOMIC);
|
||||
break;
|
||||
case HW_EVENT_PORT_RESET_TIMER_TMO:
|
||||
pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_PORT_RESET_TIMER_TMO\n");
|
||||
@ -3631,7 +3685,8 @@ static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void *piomb)
|
||||
port_id, phy_id, 0, 0);
|
||||
sas_phy_disconnected(sas_phy);
|
||||
phy->phy_attached = 0;
|
||||
sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR);
|
||||
sas_notify_port_event(sas_phy, PORTE_LINK_RESET_ERR,
|
||||
GFP_ATOMIC);
|
||||
if (pm8001_ha->phy[phy_id].reset_completion) {
|
||||
pm8001_ha->phy[phy_id].port_reset_status =
|
||||
PORT_RESET_TMO;
|
||||
@ -3648,8 +3703,8 @@ static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void *piomb)
|
||||
for (i = 0; i < pm8001_ha->chip->n_phy; i++) {
|
||||
if (port->wide_port_phymap & (1 << i)) {
|
||||
phy = &pm8001_ha->phy[i];
|
||||
sas_ha->notify_phy_event(&phy->sas_phy,
|
||||
PHYE_LOSS_OF_SIGNAL);
|
||||
sas_notify_phy_event(&phy->sas_phy,
|
||||
PHYE_LOSS_OF_SIGNAL, GFP_ATOMIC);
|
||||
port->wide_port_phymap &= ~(1 << i);
|
||||
}
|
||||
}
|
||||
@ -4959,4 +5014,5 @@ const struct pm8001_dispatch pm8001_80xx_dispatch = {
|
||||
.set_nvmd_req = pm8001_chip_set_nvmd_req,
|
||||
.fw_flash_update_req = pm8001_chip_fw_flash_update_req,
|
||||
.set_dev_state_req = pm8001_chip_set_dev_state_req,
|
||||
.fatal_errors = pm80xx_fatal_errors,
|
||||
};
|
||||
|
@ -220,8 +220,8 @@
|
||||
#define SAS_DOPNRJT_RTRY_TMO 128
|
||||
#define SAS_COPNRJT_RTRY_TMO 128
|
||||
|
||||
#define SPCV_DOORBELL_CLEAR_TIMEOUT (30 * 1000 * 1000) /* 30 sec */
|
||||
#define SPC_DOORBELL_CLEAR_TIMEOUT (15 * 1000 * 1000) /* 15 sec */
|
||||
#define SPCV_DOORBELL_CLEAR_TIMEOUT (30 * 50) /* 30 sec */
|
||||
#define SPC_DOORBELL_CLEAR_TIMEOUT (15 * 50) /* 15 sec */
|
||||
|
||||
/*
|
||||
Making ORR bigger than IT NEXUS LOSS which is 2000000us = 2 second.
|
||||
@ -1368,6 +1368,19 @@ typedef struct SASProtocolTimerConfig SASProtocolTimerConfig_t;
|
||||
#define MSGU_HOST_SCRATCH_PAD_6 0x6C
|
||||
#define MSGU_HOST_SCRATCH_PAD_7 0x70
|
||||
|
||||
#define MSGU_SCRATCHPAD1_RAAE_STATE_ERR(x) ((x & 0x3) == 0x2)
|
||||
#define MSGU_SCRATCHPAD1_ILA_STATE_ERR(x) (((x >> 2) & 0x3) == 0x2)
|
||||
#define MSGU_SCRATCHPAD1_BOOTLDR_STATE_ERR(x) ((((x >> 4) & 0x7) == 0x7) || \
|
||||
(((x >> 4) & 0x7) == 0x4))
|
||||
#define MSGU_SCRATCHPAD1_IOP0_STATE_ERR(x) (((x >> 10) & 0x3) == 0x2)
|
||||
#define MSGU_SCRATCHPAD1_IOP1_STATE_ERR(x) (((x >> 12) & 0x3) == 0x2)
|
||||
#define MSGU_SCRATCHPAD1_STATE_FATAL_ERROR(x) \
|
||||
(MSGU_SCRATCHPAD1_RAAE_STATE_ERR(x) || \
|
||||
MSGU_SCRATCHPAD1_ILA_STATE_ERR(x) || \
|
||||
MSGU_SCRATCHPAD1_BOOTLDR_STATE_ERR(x) || \
|
||||
MSGU_SCRATCHPAD1_IOP0_STATE_ERR(x) || \
|
||||
MSGU_SCRATCHPAD1_IOP1_STATE_ERR(x))
|
||||
|
||||
/* bit definition for ODMR register */
|
||||
#define ODMR_MASK_ALL 0xFFFFFFFF/* mask all
|
||||
interrupt vector */
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user