mirror of
https://github.com/torvalds/linux.git
synced 2025-12-07 20:06:24 +00:00
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:
@@ -1161,3 +1161,14 @@ Description: This entry shows the configured size of WriteBooster buffer.
|
|||||||
0400h corresponds to 4GB.
|
0400h corresponds to 4GB.
|
||||||
|
|
||||||
The file is read only.
|
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
|
# drivers/scsi/Makefile
|
||||||
CFLAGS_aha152x.o = -DAHA152X_STAT -DAUTOCONF
|
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
|
$(AFLAGS_$@) is a similar feature for source files in assembly
|
||||||
languages.
|
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``
|
CG_MAGIC 0x00090255 ufs_cylinder_group ``include/linux/ufs_fs.h``
|
||||||
RPORT_MAGIC 0x00525001 r_port ``drivers/char/rocket_int.h``
|
RPORT_MAGIC 0x00525001 r_port ``drivers/char/rocket_int.h``
|
||||||
LSEMAGIC 0x05091998 lse ``drivers/fc4/fc.c``
|
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``
|
RIEBL_MAGIC 0x09051990 ``drivers/net/atarilance.c``
|
||||||
NBD_REQUEST_MAGIC 0x12560953 nbd_request ``include/linux/nbd.h``
|
NBD_REQUEST_MAGIC 0x12560953 nbd_request ``include/linux/nbd.h``
|
||||||
RED_MAGIC2 0x170fc2a5 (any) ``mm/slab.c``
|
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``
|
NBD_REPLY_MAGIC 0x96744668 nbd_reply ``include/linux/nbd.h``
|
||||||
ENI155_MAGIC 0xa54b872d midway_eprom ``drivers/atm/eni.h``
|
ENI155_MAGIC 0xa54b872d midway_eprom ``drivers/atm/eni.h``
|
||||||
CODA_MAGIC 0xC0DAC0DA coda_file_info ``fs/coda/coda_fs_i.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``
|
YAM_MAGIC 0xF10A7654 yam_port ``drivers/net/hamradio/yam.c``
|
||||||
CCB_MAGIC 0xf2691ad2 ccb ``drivers/scsi/ncr53c8xx.c``
|
CCB_MAGIC 0xf2691ad2 ccb ``drivers/scsi/ncr53c8xx.c``
|
||||||
QUEUE_MAGIC_FREE 0xf7e1c9a3 queue_entry ``drivers/scsi/arm/queue.c``
|
QUEUE_MAGIC_FREE 0xf7e1c9a3 queue_entry ``drivers/scsi/arm/queue.c``
|
||||||
|
|||||||
@@ -189,13 +189,8 @@ num_phys
|
|||||||
The event interface::
|
The event interface::
|
||||||
|
|
||||||
/* LLDD calls these to notify the class of an event. */
|
/* LLDD calls these to notify the class of an event. */
|
||||||
void (*notify_ha_event)(struct sas_ha_struct *, enum ha_event);
|
void sas_notify_port_event(struct sas_phy *, enum port_event, gfp_t);
|
||||||
void (*notify_port_event)(struct sas_phy *, enum port_event);
|
void sas_notify_phy_event(struct sas_phy *, enum phy_event, gfp_t);
|
||||||
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.
|
|
||||||
|
|
||||||
The port notification::
|
The port notification::
|
||||||
|
|
||||||
|
|||||||
@@ -38,9 +38,6 @@ parameters may be changed at runtime by the command
|
|||||||
See drivers/scsi/BusLogic.c, comment before function
|
See drivers/scsi/BusLogic.c, comment before function
|
||||||
BusLogic_ParseDriverOptions().
|
BusLogic_ParseDriverOptions().
|
||||||
|
|
||||||
gdth= [HW,SCSI]
|
|
||||||
See header of drivers/scsi/gdth.c.
|
|
||||||
|
|
||||||
gvp11= [HW,SCSI]
|
gvp11= [HW,SCSI]
|
||||||
|
|
||||||
ips= [HW,SCSI] Adaptec / IBM ServeRAID controller
|
ips= [HW,SCSI] Adaptec / IBM ServeRAID controller
|
||||||
|
|||||||
@@ -157,7 +157,6 @@ Code Seq# Include File Comments
|
|||||||
'I' all linux/isdn.h conflict!
|
'I' all linux/isdn.h conflict!
|
||||||
'I' 00-0F drivers/isdn/divert/isdn_divert.h conflict!
|
'I' 00-0F drivers/isdn/divert/isdn_divert.h conflict!
|
||||||
'I' 40-4F linux/mISDNif.h conflict!
|
'I' 40-4F linux/mISDNif.h conflict!
|
||||||
'J' 00-1F drivers/scsi/gdth_ioctl.h
|
|
||||||
'K' all linux/kd.h
|
'K' all linux/kd.h
|
||||||
'L' 00-1F linux/loop.h conflict!
|
'L' 00-1F linux/loop.h conflict!
|
||||||
'L' 10-1F drivers/scsi/mpt3sas/mpt3sas_ctl.h conflict!
|
'L' 10-1F drivers/scsi/mpt3sas/mpt3sas_ctl.h conflict!
|
||||||
|
|||||||
@@ -7363,13 +7363,6 @@ M: Kieran Bingham <kbingham@kernel.org>
|
|||||||
S: Supported
|
S: Supported
|
||||||
F: scripts/gdb/
|
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
|
GEMTEK FM RADIO RECEIVER DRIVER
|
||||||
M: Hans Verkuil <hverkuil@xs4all.nl>
|
M: Hans Verkuil <hverkuil@xs4all.nl>
|
||||||
L: linux-media@vger.kernel.org
|
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
|
F: include/linux/mfd/intel_pmc_bxt.h
|
||||||
|
|
||||||
INTEL C600 SERIES SAS CONTROLLER DRIVER
|
INTEL C600 SERIES SAS CONTROLLER DRIVER
|
||||||
M: Intel SCU Linux support <intel-linux-scu@intel.com>
|
|
||||||
M: Artur Paszkiewicz <artur.paszkiewicz@intel.com>
|
M: Artur Paszkiewicz <artur.paszkiewicz@intel.com>
|
||||||
L: linux-scsi@vger.kernel.org
|
L: linux-scsi@vger.kernel.org
|
||||||
S: Supported
|
S: Supported
|
||||||
|
|||||||
@@ -313,7 +313,7 @@
|
|||||||
* define.
|
* define.
|
||||||
* Added BIOS Page 4 structure.
|
* Added BIOS Page 4 structure.
|
||||||
* Added MPI_RAID_PHYS_DISK1_PATH_MAX define for RAID
|
* 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
|
* 01-15-07 01.05.17 Added additional bit defines for ExtFlags field of
|
||||||
* Manufacturing Page 4.
|
* Manufacturing Page 4.
|
||||||
* Added Solid State Drives Supported bit to IOC Page 6
|
* Added Solid State Drives Supported bit to IOC Page 6
|
||||||
|
|||||||
@@ -513,7 +513,7 @@ mpi_cnfg.h
|
|||||||
* define.
|
* define.
|
||||||
* Added BIOS Page 4 structure.
|
* Added BIOS Page 4 structure.
|
||||||
* Added MPI_RAID_PHYS_DISK1_PATH_MAX define for RAID
|
* 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
|
* 01-15-07 01.05.17 Added additional bit defines for ExtFlags field of
|
||||||
* Manufacturing Page 4.
|
* Manufacturing Page 4.
|
||||||
* Added Solid State Drives Supported bit to IOC Page 6
|
* 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;
|
u32 sense_len, resid;
|
||||||
u8 rsp_flags;
|
u8 rsp_flags;
|
||||||
|
|
||||||
set_msg_byte(scsi, COMMAND_COMPLETE);
|
|
||||||
scsi->result |= fcp_rsp->resp.fr_status;
|
scsi->result |= fcp_rsp->resp.fr_status;
|
||||||
|
|
||||||
rsp_flags = fcp_rsp->resp.fr_flags;
|
rsp_flags = fcp_rsp->resp.fr_flags;
|
||||||
|
|||||||
@@ -434,23 +434,37 @@ static twa_message_type twa_error_table[] = {
|
|||||||
#define TW_RESID_OUT(x) ((x >> 4) & 0xff)
|
#define TW_RESID_OUT(x) ((x >> 4) & 0xff)
|
||||||
|
|
||||||
/* request_id: 12, lun: 4 */
|
/* 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)
|
#define TW_LUN_OUT(lun) ((lun >> 12) & 0xf)
|
||||||
|
|
||||||
/* Macros */
|
/* Macros */
|
||||||
#define TW_CONTROL_REG_ADDR(x) (x->base_addr)
|
#define TW_CONTROL_REG_ADDR(x) (x->base_addr)
|
||||||
#define TW_STATUS_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + 0x4)
|
#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(x) \
|
||||||
#define TW_COMMAND_QUEUE_REG_ADDR_LARGE(x) ((unsigned char __iomem *)x->base_addr + 0x20)
|
(sizeof(dma_addr_t) > 4 ? ((unsigned char __iomem *)x->base_addr + 0x20) : ((unsigned char __iomem *)x->base_addr + 0x8))
|
||||||
#define TW_RESPONSE_QUEUE_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + 0xC)
|
#define TW_COMMAND_QUEUE_REG_ADDR_LARGE(x) \
|
||||||
#define TW_RESPONSE_QUEUE_REG_ADDR_LARGE(x) ((unsigned char __iomem *)x->base_addr + 0x30)
|
((unsigned char __iomem *)x->base_addr + 0x20)
|
||||||
#define TW_CLEAR_ALL_INTERRUPTS(x) (writel(TW_STATUS_VALID_INTERRUPT, TW_CONTROL_REG_ADDR(x)))
|
#define TW_RESPONSE_QUEUE_REG_ADDR(x) \
|
||||||
#define TW_CLEAR_ATTENTION_INTERRUPT(x) (writel(TW_CONTROL_CLEAR_ATTENTION_INTERRUPT, TW_CONTROL_REG_ADDR(x)))
|
((unsigned char __iomem *)x->base_addr + 0xC)
|
||||||
#define TW_CLEAR_HOST_INTERRUPT(x) (writel(TW_CONTROL_CLEAR_HOST_INTERRUPT, TW_CONTROL_REG_ADDR(x)))
|
#define TW_RESPONSE_QUEUE_REG_ADDR_LARGE(x) \
|
||||||
#define TW_DISABLE_INTERRUPTS(x) (writel(TW_CONTROL_DISABLE_INTERRUPTS, TW_CONTROL_REG_ADDR(x)))
|
((unsigned char __iomem *)x->base_addr + 0x30)
|
||||||
#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_CLEAR_ALL_INTERRUPTS(x) \
|
||||||
#define TW_MASK_COMMAND_INTERRUPT(x) (writel(TW_CONTROL_MASK_COMMAND_INTERRUPT, TW_CONTROL_REG_ADDR(x)))
|
(writel(TW_STATUS_VALID_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_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_SOFT_RESET(x) (writel(TW_CONTROL_ISSUE_SOFT_RESET | \
|
||||||
TW_CONTROL_CLEAR_HOST_INTERRUPT | \
|
TW_CONTROL_CLEAR_HOST_INTERRUPT | \
|
||||||
TW_CONTROL_CLEAR_ATTENTION_INTERRUPT | \
|
TW_CONTROL_CLEAR_ATTENTION_INTERRUPT | \
|
||||||
|
|||||||
@@ -167,25 +167,41 @@ static char *twl_aen_severity_table[] =
|
|||||||
#define TW_NOTMFA_OUT(x) (x & 0x1)
|
#define TW_NOTMFA_OUT(x) (x & 0x1)
|
||||||
|
|
||||||
/* request_id: 12, lun: 4 */
|
/* 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)
|
#define TW_LUN_OUT(lun) ((lun >> 12) & 0xf)
|
||||||
|
|
||||||
/* Register access macros */
|
/* Register access macros */
|
||||||
#define TWL_STATUS_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_STATUS)
|
#define TWL_STATUS_REG_ADDR(x) \
|
||||||
#define TWL_HOBQPL_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_HOBQPL)
|
((unsigned char __iomem *)x->base_addr + TWL_STATUS)
|
||||||
#define TWL_HOBQPH_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_HOBQPH)
|
#define TWL_HOBQPL_REG_ADDR(x) \
|
||||||
#define TWL_HOBDB_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_HOBDB)
|
((unsigned char __iomem *)x->base_addr + TWL_HOBQPL)
|
||||||
#define TWL_HOBDBC_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_HOBDBC)
|
#define TWL_HOBQPH_REG_ADDR(x) \
|
||||||
#define TWL_HIMASK_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_HIMASK)
|
((unsigned char __iomem *)x->base_addr + TWL_HOBQPH)
|
||||||
#define TWL_HISTAT_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_HISTAT)
|
#define TWL_HOBDB_REG_ADDR(x) \
|
||||||
#define TWL_HIBQPH_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_HIBQPH)
|
((unsigned char __iomem *)x->base_addr + TWL_HOBDB)
|
||||||
#define TWL_HIBQPL_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_HIBQPL)
|
#define TWL_HOBDBC_REG_ADDR(x) \
|
||||||
#define TWL_HIBDB_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_HIBDB)
|
((unsigned char __iomem *)x->base_addr + TWL_HOBDBC)
|
||||||
#define TWL_SCRPD3_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_SCRPD3)
|
#define TWL_HIMASK_REG_ADDR(x) \
|
||||||
#define TWL_MASK_INTERRUPTS(x) (writel(~0, TWL_HIMASK_REG_ADDR(tw_dev)))
|
((unsigned char __iomem *)x->base_addr + TWL_HIMASK)
|
||||||
#define TWL_UNMASK_INTERRUPTS(x) (writel(~TWL_HISTATUS_VALID_INTERRUPT, TWL_HIMASK_REG_ADDR(tw_dev)))
|
#define TWL_HISTAT_REG_ADDR(x) \
|
||||||
#define TWL_CLEAR_DB_INTERRUPT(x) (writel(~0, TWL_HOBDBC_REG_ADDR(tw_dev)))
|
((unsigned char __iomem *)x->base_addr + TWL_HISTAT)
|
||||||
#define TWL_SOFT_RESET(x) (writel(TWL_ISSUE_SOFT_RESET, TWL_HIBDB_REG_ADDR(tw_dev)))
|
#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 */
|
/* Macros */
|
||||||
#define TW_PRINTK(h,a,b,c) { \
|
#define TW_PRINTK(h,a,b,c) { \
|
||||||
|
|||||||
@@ -1979,7 +1979,6 @@ static int tw_scsi_queue_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_c
|
|||||||
printk(KERN_NOTICE "3w-xxxx: scsi%d: Unknown scsi opcode: 0x%x\n", tw_dev->host->host_no, *command);
|
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_dev->state[request_id] = TW_S_COMPLETED;
|
||||||
tw_state_request_finish(tw_dev, request_id);
|
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);
|
scsi_build_sense_buffer(1, SCpnt->sense_buffer, ILLEGAL_REQUEST, 0x20, 0);
|
||||||
done(SCpnt);
|
done(SCpnt);
|
||||||
retval = 0;
|
retval = 0;
|
||||||
|
|||||||
@@ -250,13 +250,22 @@ static unsigned char tw_sense_table[][4] =
|
|||||||
#define TW_STATUS_REG_ADDR(x) (x->base_addr + 0x4)
|
#define TW_STATUS_REG_ADDR(x) (x->base_addr + 0x4)
|
||||||
#define TW_COMMAND_QUEUE_REG_ADDR(x) (x->base_addr + 0x8)
|
#define TW_COMMAND_QUEUE_REG_ADDR(x) (x->base_addr + 0x8)
|
||||||
#define TW_RESPONSE_QUEUE_REG_ADDR(x) (x->base_addr + 0xC)
|
#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_ALL_INTERRUPTS(x) \
|
||||||
#define TW_CLEAR_ATTENTION_INTERRUPT(x) (outl(TW_CONTROL_CLEAR_ATTENTION_INTERRUPT, TW_CONTROL_REG_ADDR(x)))
|
(outl(TW_STATUS_VALID_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_CLEAR_ATTENTION_INTERRUPT(x) \
|
||||||
#define TW_DISABLE_INTERRUPTS(x) (outl(TW_CONTROL_DISABLE_INTERRUPTS, TW_CONTROL_REG_ADDR(x)))
|
(outl(TW_CONTROL_CLEAR_ATTENTION_INTERRUPT, 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_CLEAR_HOST_INTERRUPT(x) \
|
||||||
#define TW_MASK_COMMAND_INTERRUPT(x) (outl(TW_CONTROL_MASK_COMMAND_INTERRUPT, TW_CONTROL_REG_ADDR(x)))
|
(outl(TW_CONTROL_CLEAR_HOST_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_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 | \
|
#define TW_SOFT_RESET(x) (outl(TW_CONTROL_ISSUE_SOFT_RESET | \
|
||||||
TW_CONTROL_CLEAR_HOST_INTERRUPT | \
|
TW_CONTROL_CLEAR_HOST_INTERRUPT | \
|
||||||
TW_CONTROL_CLEAR_ATTENTION_INTERRUPT | \
|
TW_CONTROL_CLEAR_ATTENTION_INTERRUPT | \
|
||||||
|
|||||||
@@ -669,20 +669,6 @@ config SCSI_FDOMAIN_ISA
|
|||||||
To compile this driver as a module, choose M here: the
|
To compile this driver as a module, choose M here: the
|
||||||
module will be called fdomain_isa.
|
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
|
config SCSI_ISCI
|
||||||
tristate "Intel(R) C600 Series Chipset SAS Controller"
|
tristate "Intel(R) C600 Series Chipset SAS Controller"
|
||||||
depends on PCI && SCSI
|
depends on PCI && SCSI
|
||||||
@@ -1159,6 +1145,7 @@ config SCSI_LPFC
|
|||||||
depends on NVME_TARGET_FC || NVME_TARGET_FC=n
|
depends on NVME_TARGET_FC || NVME_TARGET_FC=n
|
||||||
depends on NVME_FC || NVME_FC=n
|
depends on NVME_FC || NVME_FC=n
|
||||||
select CRC_T10DIF
|
select CRC_T10DIF
|
||||||
|
select IRQ_POLL
|
||||||
help
|
help
|
||||||
This lpfc driver supports the Emulex LightPulse
|
This lpfc driver supports the Emulex LightPulse
|
||||||
Family of Fibre Channel PCI host adapters.
|
Family of Fibre Channel PCI host adapters.
|
||||||
@@ -1182,6 +1169,7 @@ config SCSI_SIM710
|
|||||||
config SCSI_DC395x
|
config SCSI_DC395x
|
||||||
tristate "Tekram DC395(U/UW/F) and DC315(U) SCSI support"
|
tristate "Tekram DC395(U/UW/F) and DC315(U) SCSI support"
|
||||||
depends on PCI && SCSI
|
depends on PCI && SCSI
|
||||||
|
select SCSI_SPI_ATTRS
|
||||||
help
|
help
|
||||||
This driver supports PCI SCSI host adapters based on the ASIC
|
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.
|
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_aha152x.o = -DAHA152X_STAT -DAUTOCONF
|
||||||
CFLAGS_gdth.o = # -DDEBUG_GDTH=2 -D__SERIAL__ -D__COM2__ -DGDTH_STATISTICS
|
|
||||||
|
|
||||||
obj-$(CONFIG_PCMCIA) += pcmcia/
|
obj-$(CONFIG_PCMCIA) += pcmcia/
|
||||||
|
|
||||||
@@ -103,7 +102,6 @@ obj-$(CONFIG_SCSI_MPT3SAS) += mpt3sas/
|
|||||||
obj-$(CONFIG_SCSI_UFSHCD) += ufs/
|
obj-$(CONFIG_SCSI_UFSHCD) += ufs/
|
||||||
obj-$(CONFIG_SCSI_ACARD) += atp870u.o
|
obj-$(CONFIG_SCSI_ACARD) += atp870u.o
|
||||||
obj-$(CONFIG_SCSI_SUNESP) += esp_scsi.o sun_esp.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_INITIO) += initio.o
|
||||||
obj-$(CONFIG_SCSI_INIA100) += a100u2w.o
|
obj-$(CONFIG_SCSI_INIA100) += a100u2w.o
|
||||||
obj-$(CONFIG_SCSI_QLOGICPTI) += qlogicpti.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);
|
aac_fib_complete(fibptr);
|
||||||
scsicmd->scsi_done(scsicmd);
|
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);
|
aac_fib_complete(fibptr);
|
||||||
scsicmd->scsi_done(scsicmd);
|
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) {
|
if (lba & 0xffffffff00000000LL) {
|
||||||
int cid = scmd_id(cmd);
|
int cid = scmd_id(cmd);
|
||||||
dprintk((KERN_DEBUG "aacraid: Illegal lba\n"));
|
dprintk((KERN_DEBUG "aacraid: Illegal lba\n"));
|
||||||
cmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
|
cmd->result = DID_OK << 16 | SAM_STAT_CHECK_CONDITION;
|
||||||
SAM_STAT_CHECK_CONDITION;
|
|
||||||
set_sense(&dev->fsa_dev[cid].sense_data,
|
set_sense(&dev->fsa_dev[cid].sense_data,
|
||||||
HARDWARE_ERROR, SENCODE_INTERNAL_TARGET_FAILURE,
|
HARDWARE_ERROR, SENCODE_INTERNAL_TARGET_FAILURE,
|
||||||
ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0);
|
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);
|
readreply = (struct aac_read_reply *)fib_data(fibptr);
|
||||||
switch (le32_to_cpu(readreply->status)) {
|
switch (le32_to_cpu(readreply->status)) {
|
||||||
case ST_OK:
|
case ST_OK:
|
||||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
|
scsicmd->result = DID_OK << 16 | SAM_STAT_GOOD;
|
||||||
SAM_STAT_GOOD;
|
|
||||||
dev->fsa_dev[cid].sense_data.sense_key = NO_SENSE;
|
dev->fsa_dev[cid].sense_data.sense_key = NO_SENSE;
|
||||||
break;
|
break;
|
||||||
case ST_NOT_READY:
|
case ST_NOT_READY:
|
||||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
|
scsicmd->result = DID_OK << 16 | SAM_STAT_CHECK_CONDITION;
|
||||||
SAM_STAT_CHECK_CONDITION;
|
|
||||||
set_sense(&dev->fsa_dev[cid].sense_data, NOT_READY,
|
set_sense(&dev->fsa_dev[cid].sense_data, NOT_READY,
|
||||||
SENCODE_BECOMING_READY, ASENCODE_BECOMING_READY, 0, 0);
|
SENCODE_BECOMING_READY, ASENCODE_BECOMING_READY, 0, 0);
|
||||||
memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data,
|
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));
|
SCSI_SENSE_BUFFERSIZE));
|
||||||
break;
|
break;
|
||||||
case ST_MEDERR:
|
case ST_MEDERR:
|
||||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
|
scsicmd->result = DID_OK << 16 | SAM_STAT_CHECK_CONDITION;
|
||||||
SAM_STAT_CHECK_CONDITION;
|
|
||||||
set_sense(&dev->fsa_dev[cid].sense_data, MEDIUM_ERROR,
|
set_sense(&dev->fsa_dev[cid].sense_data, MEDIUM_ERROR,
|
||||||
SENCODE_UNRECOVERED_READ_ERROR, ASENCODE_NO_SENSE, 0, 0);
|
SENCODE_UNRECOVERED_READ_ERROR, ASENCODE_NO_SENSE, 0, 0);
|
||||||
memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data,
|
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",
|
printk(KERN_WARNING "io_callback: io failed, status = %d\n",
|
||||||
le32_to_cpu(readreply->status));
|
le32_to_cpu(readreply->status));
|
||||||
#endif
|
#endif
|
||||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
|
scsicmd->result = DID_OK << 16 | SAM_STAT_CHECK_CONDITION;
|
||||||
SAM_STAT_CHECK_CONDITION;
|
|
||||||
set_sense(&dev->fsa_dev[cid].sense_data,
|
set_sense(&dev->fsa_dev[cid].sense_data,
|
||||||
HARDWARE_ERROR, SENCODE_INTERNAL_TARGET_FAILURE,
|
HARDWARE_ERROR, SENCODE_INTERNAL_TARGET_FAILURE,
|
||||||
ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0);
|
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)) {
|
if ((lba + count) > (dev->fsa_dev[scmd_id(scsicmd)].size)) {
|
||||||
cid = scmd_id(scsicmd);
|
cid = scmd_id(scsicmd);
|
||||||
dprintk((KERN_DEBUG "aacraid: Illegal lba\n"));
|
dprintk((KERN_DEBUG "aacraid: Illegal lba\n"));
|
||||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
|
scsicmd->result = DID_OK << 16 | SAM_STAT_CHECK_CONDITION;
|
||||||
SAM_STAT_CHECK_CONDITION;
|
|
||||||
set_sense(&dev->fsa_dev[cid].sense_data,
|
set_sense(&dev->fsa_dev[cid].sense_data,
|
||||||
ILLEGAL_REQUEST, SENCODE_LBA_OUT_OF_RANGE,
|
ILLEGAL_REQUEST, SENCODE_LBA_OUT_OF_RANGE,
|
||||||
ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0);
|
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
|
* 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);
|
scsicmd->scsi_done(scsicmd);
|
||||||
aac_fib_complete(cmd_fibcontext);
|
aac_fib_complete(cmd_fibcontext);
|
||||||
aac_fib_free(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)) {
|
if ((lba + count) > (dev->fsa_dev[scmd_id(scsicmd)].size)) {
|
||||||
cid = scmd_id(scsicmd);
|
cid = scmd_id(scsicmd);
|
||||||
dprintk((KERN_DEBUG "aacraid: Illegal lba\n"));
|
dprintk((KERN_DEBUG "aacraid: Illegal lba\n"));
|
||||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
|
scsicmd->result = DID_OK << 16 | SAM_STAT_CHECK_CONDITION;
|
||||||
SAM_STAT_CHECK_CONDITION;
|
|
||||||
set_sense(&dev->fsa_dev[cid].sense_data,
|
set_sense(&dev->fsa_dev[cid].sense_data,
|
||||||
ILLEGAL_REQUEST, SENCODE_LBA_OUT_OF_RANGE,
|
ILLEGAL_REQUEST, SENCODE_LBA_OUT_OF_RANGE,
|
||||||
ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0);
|
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
|
* 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);
|
scsicmd->scsi_done(scsicmd);
|
||||||
|
|
||||||
aac_fib_complete(cmd_fibcontext);
|
aac_fib_complete(cmd_fibcontext);
|
||||||
@@ -2615,8 +2608,7 @@ static void synchronize_callback(void *context, struct fib *fibptr)
|
|||||||
|
|
||||||
synchronizereply = fib_data(fibptr);
|
synchronizereply = fib_data(fibptr);
|
||||||
if (le32_to_cpu(synchronizereply->status) == CT_OK)
|
if (le32_to_cpu(synchronizereply->status) == CT_OK)
|
||||||
cmd->result = DID_OK << 16 |
|
cmd->result = DID_OK << 16 | SAM_STAT_GOOD;
|
||||||
COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
|
|
||||||
else {
|
else {
|
||||||
struct scsi_device *sdev = cmd->device;
|
struct scsi_device *sdev = cmd->device;
|
||||||
struct aac_dev *dev = fibptr->dev;
|
struct aac_dev *dev = fibptr->dev;
|
||||||
@@ -2624,8 +2616,7 @@ static void synchronize_callback(void *context, struct fib *fibptr)
|
|||||||
printk(KERN_WARNING
|
printk(KERN_WARNING
|
||||||
"synchronize_callback: synchronize failed, status = %d\n",
|
"synchronize_callback: synchronize failed, status = %d\n",
|
||||||
le32_to_cpu(synchronizereply->status));
|
le32_to_cpu(synchronizereply->status));
|
||||||
cmd->result = DID_OK << 16 |
|
cmd->result = DID_OK << 16 | SAM_STAT_CHECK_CONDITION;
|
||||||
COMMAND_COMPLETE << 8 | SAM_STAT_CHECK_CONDITION;
|
|
||||||
set_sense(&dev->fsa_dev[cid].sense_data,
|
set_sense(&dev->fsa_dev[cid].sense_data,
|
||||||
HARDWARE_ERROR, SENCODE_INTERNAL_TARGET_FAILURE,
|
HARDWARE_ERROR, SENCODE_INTERNAL_TARGET_FAILURE,
|
||||||
ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0);
|
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);
|
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_complete(fibptr);
|
||||||
aac_fib_free(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 &
|
if (!(aac->supplement_adapter_info.supported_options2 &
|
||||||
AAC_OPTION_POWER_MANAGEMENT)) {
|
AAC_OPTION_POWER_MANAGEMENT)) {
|
||||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
|
scsicmd->result = DID_OK << 16 | SAM_STAT_GOOD;
|
||||||
SAM_STAT_GOOD;
|
|
||||||
scsicmd->scsi_done(scsicmd);
|
scsicmd->scsi_done(scsicmd);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -2848,7 +2838,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
|
|||||||
(scsicmd->cmnd[0] != TEST_UNIT_READY))
|
(scsicmd->cmnd[0] != TEST_UNIT_READY))
|
||||||
{
|
{
|
||||||
dprintk((KERN_WARNING "Only INQUIRY & TUR command supported for controller, rcvd = 0x%x.\n", scsicmd->cmnd[0]));
|
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,
|
set_sense(&dev->fsa_dev[cid].sense_data,
|
||||||
ILLEGAL_REQUEST, SENCODE_INVALID_COMMAND,
|
ILLEGAL_REQUEST, SENCODE_INVALID_COMMAND,
|
||||||
ASENCODE_INVALID_COMMAND, 0, 0);
|
ASENCODE_INVALID_COMMAND, 0, 0);
|
||||||
@@ -2877,8 +2867,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
|
|||||||
|
|
||||||
case SYNCHRONIZE_CACHE:
|
case SYNCHRONIZE_CACHE:
|
||||||
if (((aac_cache & 6) == 6) && dev->cache_protected) {
|
if (((aac_cache & 6) == 6) && dev->cache_protected) {
|
||||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
|
scsicmd->result = DID_OK << 16 | SAM_STAT_GOOD;
|
||||||
SAM_STAT_GOOD;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* Issue FIB to tell Firmware to flush it's cache */
|
/* 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];
|
arr[1] = scsicmd->cmnd[2];
|
||||||
scsi_sg_copy_from_buffer(scsicmd, &inq_data,
|
scsi_sg_copy_from_buffer(scsicmd, &inq_data,
|
||||||
sizeof(inq_data));
|
sizeof(inq_data));
|
||||||
scsicmd->result = DID_OK << 16 |
|
scsicmd->result = DID_OK << 16 | SAM_STAT_GOOD;
|
||||||
COMMAND_COMPLETE << 8 |
|
|
||||||
SAM_STAT_GOOD;
|
|
||||||
} else if (scsicmd->cmnd[2] == 0x80) {
|
} else if (scsicmd->cmnd[2] == 0x80) {
|
||||||
/* unit serial number page */
|
/* unit serial number page */
|
||||||
arr[3] = setinqserial(dev, &arr[4],
|
arr[3] = setinqserial(dev, &arr[4],
|
||||||
@@ -2920,9 +2907,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
|
|||||||
if (aac_wwn != 2)
|
if (aac_wwn != 2)
|
||||||
return aac_get_container_serial(
|
return aac_get_container_serial(
|
||||||
scsicmd);
|
scsicmd);
|
||||||
scsicmd->result = DID_OK << 16 |
|
scsicmd->result = DID_OK << 16 | SAM_STAT_GOOD;
|
||||||
COMMAND_COMPLETE << 8 |
|
|
||||||
SAM_STAT_GOOD;
|
|
||||||
} else if (scsicmd->cmnd[2] == 0x83) {
|
} else if (scsicmd->cmnd[2] == 0x83) {
|
||||||
/* vpd page 0x83 - Device Identification Page */
|
/* vpd page 0x83 - Device Identification Page */
|
||||||
char *sno = (char *)&inq_data;
|
char *sno = (char *)&inq_data;
|
||||||
@@ -2931,14 +2916,10 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
|
|||||||
if (aac_wwn != 2)
|
if (aac_wwn != 2)
|
||||||
return aac_get_container_serial(
|
return aac_get_container_serial(
|
||||||
scsicmd);
|
scsicmd);
|
||||||
scsicmd->result = DID_OK << 16 |
|
scsicmd->result = DID_OK << 16 | SAM_STAT_GOOD;
|
||||||
COMMAND_COMPLETE << 8 |
|
|
||||||
SAM_STAT_GOOD;
|
|
||||||
} else {
|
} else {
|
||||||
/* vpd page not implemented */
|
/* vpd page not implemented */
|
||||||
scsicmd->result = DID_OK << 16 |
|
scsicmd->result = DID_OK << 16 | SAM_STAT_CHECK_CONDITION;
|
||||||
COMMAND_COMPLETE << 8 |
|
|
||||||
SAM_STAT_CHECK_CONDITION;
|
|
||||||
set_sense(&dev->fsa_dev[cid].sense_data,
|
set_sense(&dev->fsa_dev[cid].sense_data,
|
||||||
ILLEGAL_REQUEST, SENCODE_INVALID_CDB_FIELD,
|
ILLEGAL_REQUEST, SENCODE_INVALID_CDB_FIELD,
|
||||||
ASENCODE_NO_SENSE, 7, 2);
|
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 */
|
inq_data.inqd_pdt = INQD_PDT_PROC; /* Processor device */
|
||||||
scsi_sg_copy_from_buffer(scsicmd, &inq_data,
|
scsi_sg_copy_from_buffer(scsicmd, &inq_data,
|
||||||
sizeof(inq_data));
|
sizeof(inq_data));
|
||||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
|
scsicmd->result = DID_OK << 16 | SAM_STAT_GOOD;
|
||||||
SAM_STAT_GOOD;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (dev->in_reset)
|
if (dev->in_reset)
|
||||||
@@ -3014,8 +2994,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
|
|||||||
/* Do not cache partition table for arrays */
|
/* Do not cache partition table for arrays */
|
||||||
scsicmd->device->removable = 1;
|
scsicmd->device->removable = 1;
|
||||||
|
|
||||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
|
scsicmd->result = DID_OK << 16 | SAM_STAT_GOOD;
|
||||||
SAM_STAT_GOOD;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3041,8 +3020,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
|
|||||||
scsi_sg_copy_from_buffer(scsicmd, cp, sizeof(cp));
|
scsi_sg_copy_from_buffer(scsicmd, cp, sizeof(cp));
|
||||||
/* Do not cache partition table for arrays */
|
/* Do not cache partition table for arrays */
|
||||||
scsicmd->device->removable = 1;
|
scsicmd->device->removable = 1;
|
||||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
|
scsicmd->result = DID_OK << 16 | SAM_STAT_GOOD;
|
||||||
SAM_STAT_GOOD;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3121,8 +3099,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
|
|||||||
scsi_sg_copy_from_buffer(scsicmd,
|
scsi_sg_copy_from_buffer(scsicmd,
|
||||||
(char *)&mpd,
|
(char *)&mpd,
|
||||||
mode_buf_length);
|
mode_buf_length);
|
||||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
|
scsicmd->result = DID_OK << 16 | SAM_STAT_GOOD;
|
||||||
SAM_STAT_GOOD;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MODE_SENSE_10:
|
case MODE_SENSE_10:
|
||||||
@@ -3199,8 +3176,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
|
|||||||
(char *)&mpd10,
|
(char *)&mpd10,
|
||||||
mode_buf_length);
|
mode_buf_length);
|
||||||
|
|
||||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
|
scsicmd->result = DID_OK << 16 | SAM_STAT_GOOD;
|
||||||
SAM_STAT_GOOD;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case REQUEST_SENSE:
|
case REQUEST_SENSE:
|
||||||
@@ -3209,8 +3185,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
|
|||||||
sizeof(struct sense_data));
|
sizeof(struct sense_data));
|
||||||
memset(&dev->fsa_dev[cid].sense_data, 0,
|
memset(&dev->fsa_dev[cid].sense_data, 0,
|
||||||
sizeof(struct sense_data));
|
sizeof(struct sense_data));
|
||||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
|
scsicmd->result = DID_OK << 16 | SAM_STAT_GOOD;
|
||||||
SAM_STAT_GOOD;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ALLOW_MEDIUM_REMOVAL:
|
case ALLOW_MEDIUM_REMOVAL:
|
||||||
@@ -3220,16 +3195,14 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
|
|||||||
else
|
else
|
||||||
fsa_dev_ptr[cid].locked = 0;
|
fsa_dev_ptr[cid].locked = 0;
|
||||||
|
|
||||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
|
scsicmd->result = DID_OK << 16 | SAM_STAT_GOOD;
|
||||||
SAM_STAT_GOOD;
|
|
||||||
break;
|
break;
|
||||||
/*
|
/*
|
||||||
* These commands are all No-Ops
|
* These commands are all No-Ops
|
||||||
*/
|
*/
|
||||||
case TEST_UNIT_READY:
|
case TEST_UNIT_READY:
|
||||||
if (fsa_dev_ptr[cid].sense_data.sense_key == NOT_READY) {
|
if (fsa_dev_ptr[cid].sense_data.sense_key == NOT_READY) {
|
||||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
|
scsicmd->result = DID_OK << 16 | SAM_STAT_CHECK_CONDITION;
|
||||||
SAM_STAT_CHECK_CONDITION;
|
|
||||||
set_sense(&dev->fsa_dev[cid].sense_data,
|
set_sense(&dev->fsa_dev[cid].sense_data,
|
||||||
NOT_READY, SENCODE_BECOMING_READY,
|
NOT_READY, SENCODE_BECOMING_READY,
|
||||||
ASENCODE_BECOMING_READY, 0, 0);
|
ASENCODE_BECOMING_READY, 0, 0);
|
||||||
@@ -3246,8 +3219,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
|
|||||||
case REZERO_UNIT:
|
case REZERO_UNIT:
|
||||||
case REASSIGN_BLOCKS:
|
case REASSIGN_BLOCKS:
|
||||||
case SEEK_10:
|
case SEEK_10:
|
||||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
|
scsicmd->result = DID_OK << 16 | SAM_STAT_GOOD;
|
||||||
SAM_STAT_GOOD;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case START_STOP:
|
case START_STOP:
|
||||||
@@ -3259,8 +3231,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
|
|||||||
*/
|
*/
|
||||||
dprintk((KERN_WARNING "Unhandled SCSI Command: 0x%x.\n",
|
dprintk((KERN_WARNING "Unhandled SCSI Command: 0x%x.\n",
|
||||||
scsicmd->cmnd[0]));
|
scsicmd->cmnd[0]));
|
||||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
|
scsicmd->result = DID_OK << 16 | SAM_STAT_CHECK_CONDITION;
|
||||||
SAM_STAT_CHECK_CONDITION;
|
|
||||||
set_sense(&dev->fsa_dev[cid].sense_data,
|
set_sense(&dev->fsa_dev[cid].sense_data,
|
||||||
ILLEGAL_REQUEST, SENCODE_INVALID_COMMAND,
|
ILLEGAL_REQUEST, SENCODE_INVALID_COMMAND,
|
||||||
ASENCODE_INVALID_COMMAND, 0, 0);
|
ASENCODE_INVALID_COMMAND, 0, 0);
|
||||||
@@ -3441,9 +3412,7 @@ static void aac_srb_callback(void *context, struct fib * fibptr)
|
|||||||
le32_to_cpu(srbreply->status));
|
le32_to_cpu(srbreply->status));
|
||||||
len = min_t(u32, le32_to_cpu(srbreply->sense_data_size),
|
len = min_t(u32, le32_to_cpu(srbreply->sense_data_size),
|
||||||
SCSI_SENSE_BUFFERSIZE);
|
SCSI_SENSE_BUFFERSIZE);
|
||||||
scsicmd->result = DID_ERROR << 16
|
scsicmd->result = DID_ERROR << 16 | SAM_STAT_CHECK_CONDITION;
|
||||||
| COMMAND_COMPLETE << 8
|
|
||||||
| SAM_STAT_CHECK_CONDITION;
|
|
||||||
memcpy(scsicmd->sense_buffer,
|
memcpy(scsicmd->sense_buffer,
|
||||||
srbreply->sense_data, len);
|
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_ERROR_RECOVERY:
|
||||||
case SRB_STATUS_PENDING:
|
case SRB_STATUS_PENDING:
|
||||||
case SRB_STATUS_SUCCESS:
|
case SRB_STATUS_SUCCESS:
|
||||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8;
|
scsicmd->result = DID_OK << 16;
|
||||||
break;
|
break;
|
||||||
case SRB_STATUS_DATA_OVERRUN:
|
case SRB_STATUS_DATA_OVERRUN:
|
||||||
switch (scsicmd->cmnd[0]) {
|
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");
|
pr_warn("aacraid: SCSI CMD underflow\n");
|
||||||
else
|
else
|
||||||
pr_warn("aacraid: SCSI CMD Data Overrun\n");
|
pr_warn("aacraid: SCSI CMD Data Overrun\n");
|
||||||
scsicmd->result = DID_ERROR << 16
|
scsicmd->result = DID_ERROR << 16;
|
||||||
| COMMAND_COMPLETE << 8;
|
|
||||||
break;
|
break;
|
||||||
case INQUIRY:
|
case INQUIRY:
|
||||||
scsicmd->result = DID_OK << 16
|
scsicmd->result = DID_OK << 16;
|
||||||
| COMMAND_COMPLETE << 8;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8;
|
scsicmd->result = DID_OK << 16;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SRB_STATUS_ABORTED:
|
case SRB_STATUS_ABORTED:
|
||||||
scsicmd->result = DID_ABORT << 16 | ABORT << 8;
|
scsicmd->result = DID_ABORT << 16;
|
||||||
break;
|
break;
|
||||||
case SRB_STATUS_ABORT_FAILED:
|
case SRB_STATUS_ABORT_FAILED:
|
||||||
/*
|
/*
|
||||||
* Not sure about this one - but assuming the
|
* Not sure about this one - but assuming the
|
||||||
* hba was trying to abort for some reason
|
* hba was trying to abort for some reason
|
||||||
*/
|
*/
|
||||||
scsicmd->result = DID_ERROR << 16 | ABORT << 8;
|
scsicmd->result = DID_ERROR << 16;
|
||||||
break;
|
break;
|
||||||
case SRB_STATUS_PARITY_ERROR:
|
case SRB_STATUS_PARITY_ERROR:
|
||||||
scsicmd->result = DID_PARITY << 16
|
scsicmd->result = DID_PARITY << 16;
|
||||||
| MSG_PARITY_ERROR << 8;
|
|
||||||
break;
|
break;
|
||||||
case SRB_STATUS_NO_DEVICE:
|
case SRB_STATUS_NO_DEVICE:
|
||||||
case SRB_STATUS_INVALID_PATH_ID:
|
case SRB_STATUS_INVALID_PATH_ID:
|
||||||
case SRB_STATUS_INVALID_TARGET_ID:
|
case SRB_STATUS_INVALID_TARGET_ID:
|
||||||
case SRB_STATUS_INVALID_LUN:
|
case SRB_STATUS_INVALID_LUN:
|
||||||
case SRB_STATUS_SELECTION_TIMEOUT:
|
case SRB_STATUS_SELECTION_TIMEOUT:
|
||||||
scsicmd->result = DID_NO_CONNECT << 16
|
scsicmd->result = DID_NO_CONNECT << 16;
|
||||||
| COMMAND_COMPLETE << 8;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SRB_STATUS_COMMAND_TIMEOUT:
|
case SRB_STATUS_COMMAND_TIMEOUT:
|
||||||
case SRB_STATUS_TIMEOUT:
|
case SRB_STATUS_TIMEOUT:
|
||||||
scsicmd->result = DID_TIME_OUT << 16
|
scsicmd->result = DID_TIME_OUT << 16;
|
||||||
| COMMAND_COMPLETE << 8;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SRB_STATUS_BUSY:
|
case SRB_STATUS_BUSY:
|
||||||
scsicmd->result = DID_BUS_BUSY << 16
|
scsicmd->result = DID_BUS_BUSY << 16;
|
||||||
| COMMAND_COMPLETE << 8;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SRB_STATUS_BUS_RESET:
|
case SRB_STATUS_BUS_RESET:
|
||||||
scsicmd->result = DID_RESET << 16
|
scsicmd->result = DID_RESET << 16;
|
||||||
| COMMAND_COMPLETE << 8;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SRB_STATUS_MESSAGE_REJECTED:
|
case SRB_STATUS_MESSAGE_REJECTED:
|
||||||
scsicmd->result = DID_ERROR << 16
|
scsicmd->result = DID_ERROR << 16;
|
||||||
| MESSAGE_REJECT << 8;
|
|
||||||
break;
|
break;
|
||||||
case SRB_STATUS_REQUEST_FLUSHED:
|
case SRB_STATUS_REQUEST_FLUSHED:
|
||||||
case SRB_STATUS_ERROR:
|
case SRB_STATUS_ERROR:
|
||||||
@@ -3561,19 +3522,14 @@ static void aac_srb_callback(void *context, struct fib * fibptr)
|
|||||||
|| (scsicmd->cmnd[0] == ATA_16)) {
|
|| (scsicmd->cmnd[0] == ATA_16)) {
|
||||||
|
|
||||||
if (scsicmd->cmnd[2] & (0x01 << 5)) {
|
if (scsicmd->cmnd[2] & (0x01 << 5)) {
|
||||||
scsicmd->result = DID_OK << 16
|
scsicmd->result = DID_OK << 16;
|
||||||
| COMMAND_COMPLETE << 8;
|
|
||||||
break;
|
|
||||||
} else {
|
} else {
|
||||||
scsicmd->result = DID_ERROR << 16
|
scsicmd->result = DID_ERROR << 16;
|
||||||
| COMMAND_COMPLETE << 8;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
scsicmd->result = DID_ERROR << 16
|
scsicmd->result = DID_ERROR << 16;
|
||||||
| COMMAND_COMPLETE << 8;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (le32_to_cpu(srbreply->scsi_status)
|
if (le32_to_cpu(srbreply->scsi_status)
|
||||||
== SAM_STAT_CHECK_CONDITION) {
|
== SAM_STAT_CHECK_CONDITION) {
|
||||||
@@ -3609,7 +3565,7 @@ static void hba_resp_task_complete(struct aac_dev *dev,
|
|||||||
|
|
||||||
switch (err->status) {
|
switch (err->status) {
|
||||||
case SAM_STAT_GOOD:
|
case SAM_STAT_GOOD:
|
||||||
scsicmd->result |= DID_OK << 16 | COMMAND_COMPLETE << 8;
|
scsicmd->result |= DID_OK << 16;
|
||||||
break;
|
break;
|
||||||
case SAM_STAT_CHECK_CONDITION:
|
case SAM_STAT_CHECK_CONDITION:
|
||||||
{
|
{
|
||||||
@@ -3620,19 +3576,19 @@ static void hba_resp_task_complete(struct aac_dev *dev,
|
|||||||
if (len)
|
if (len)
|
||||||
memcpy(scsicmd->sense_buffer,
|
memcpy(scsicmd->sense_buffer,
|
||||||
err->sense_response_buf, len);
|
err->sense_response_buf, len);
|
||||||
scsicmd->result |= DID_OK << 16 | COMMAND_COMPLETE << 8;
|
scsicmd->result |= DID_OK << 16;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SAM_STAT_BUSY:
|
case SAM_STAT_BUSY:
|
||||||
scsicmd->result |= DID_BUS_BUSY << 16 | COMMAND_COMPLETE << 8;
|
scsicmd->result |= DID_BUS_BUSY << 16;
|
||||||
break;
|
break;
|
||||||
case SAM_STAT_TASK_ABORTED:
|
case SAM_STAT_TASK_ABORTED:
|
||||||
scsicmd->result |= DID_ABORT << 16 | ABORT << 8;
|
scsicmd->result |= DID_ABORT << 16;
|
||||||
break;
|
break;
|
||||||
case SAM_STAT_RESERVATION_CONFLICT:
|
case SAM_STAT_RESERVATION_CONFLICT:
|
||||||
case SAM_STAT_TASK_SET_FULL:
|
case SAM_STAT_TASK_SET_FULL:
|
||||||
default:
|
default:
|
||||||
scsicmd->result |= DID_ERROR << 16 | COMMAND_COMPLETE << 8;
|
scsicmd->result |= DID_ERROR << 16;
|
||||||
break;
|
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].devtype = AAC_DEVTYPE_ARC_RAW;
|
||||||
dev->hba_map[bus][cid].rmw_nexus = 0xffffffff;
|
dev->hba_map[bus][cid].rmw_nexus = 0xffffffff;
|
||||||
}
|
}
|
||||||
scsicmd->result = DID_NO_CONNECT << 16 | COMMAND_COMPLETE << 8;
|
scsicmd->result = DID_NO_CONNECT << 16;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case HBA_RESP_STAT_IO_ERROR:
|
case HBA_RESP_STAT_IO_ERROR:
|
||||||
case HBA_RESP_STAT_NO_PATH_TO_DEVICE:
|
case HBA_RESP_STAT_NO_PATH_TO_DEVICE:
|
||||||
scsicmd->result = DID_OK << 16 |
|
scsicmd->result = DID_OK << 16 | SAM_STAT_BUSY;
|
||||||
COMMAND_COMPLETE << 8 | SAM_STAT_BUSY;
|
|
||||||
break;
|
break;
|
||||||
case HBA_RESP_STAT_IO_ABORTED:
|
case HBA_RESP_STAT_IO_ABORTED:
|
||||||
scsicmd->result = DID_ABORT << 16 | ABORT << 8;
|
scsicmd->result = DID_ABORT << 16;
|
||||||
break;
|
break;
|
||||||
case HBA_RESP_STAT_INVALID_DEVICE:
|
case HBA_RESP_STAT_INVALID_DEVICE:
|
||||||
scsicmd->result = DID_NO_CONNECT << 16 | COMMAND_COMPLETE << 8;
|
scsicmd->result = DID_NO_CONNECT << 16;
|
||||||
break;
|
break;
|
||||||
case HBA_RESP_STAT_UNDERRUN:
|
case HBA_RESP_STAT_UNDERRUN:
|
||||||
/* UNDERRUN is OK */
|
/* UNDERRUN is OK */
|
||||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8;
|
scsicmd->result = DID_OK << 16;
|
||||||
break;
|
break;
|
||||||
case HBA_RESP_STAT_OVERRUN:
|
case HBA_RESP_STAT_OVERRUN:
|
||||||
default:
|
default:
|
||||||
scsicmd->result = DID_ERROR << 16 | COMMAND_COMPLETE << 8;
|
scsicmd->result = DID_ERROR << 16;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3705,7 +3660,7 @@ void aac_hba_callback(void *context, struct fib *fibptr)
|
|||||||
|
|
||||||
if (fibptr->flags & FIB_CONTEXT_FLAG_FASTRESP) {
|
if (fibptr->flags & FIB_CONTEXT_FLAG_FASTRESP) {
|
||||||
/* fast response */
|
/* fast response */
|
||||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8;
|
scsicmd->result = DID_OK << 16;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3717,17 +3672,17 @@ void aac_hba_callback(void *context, struct fib *fibptr)
|
|||||||
hba_resp_task_failure(dev, scsicmd, err);
|
hba_resp_task_failure(dev, scsicmd, err);
|
||||||
break;
|
break;
|
||||||
case HBA_RESP_SVCRES_TMF_REJECTED:
|
case HBA_RESP_SVCRES_TMF_REJECTED:
|
||||||
scsicmd->result = DID_ERROR << 16 | MESSAGE_REJECT << 8;
|
scsicmd->result = DID_ERROR << 16;
|
||||||
break;
|
break;
|
||||||
case HBA_RESP_SVCRES_TMF_LUN_INVALID:
|
case HBA_RESP_SVCRES_TMF_LUN_INVALID:
|
||||||
scsicmd->result = DID_NO_CONNECT << 16 | COMMAND_COMPLETE << 8;
|
scsicmd->result = DID_NO_CONNECT << 16;
|
||||||
break;
|
break;
|
||||||
case HBA_RESP_SVCRES_TMF_COMPLETE:
|
case HBA_RESP_SVCRES_TMF_COMPLETE:
|
||||||
case HBA_RESP_SVCRES_TMF_SUCCEEDED:
|
case HBA_RESP_SVCRES_TMF_SUCCEEDED:
|
||||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8;
|
scsicmd->result = DID_OK << 16;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
scsicmd->result = DID_ERROR << 16 | COMMAND_COMPLETE << 8;
|
scsicmd->result = DID_ERROR << 16;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2085,12 +2085,6 @@ do { \
|
|||||||
#define ASC_BUSY 0
|
#define ASC_BUSY 0
|
||||||
#define ASC_ERROR (-1)
|
#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)
|
#define ASC_STATS(shost, counter) ASC_STATS_ADD(shost, counter, 1)
|
||||||
#ifndef ADVANSYS_STATS
|
#ifndef ADVANSYS_STATS
|
||||||
#define ASC_STATS_ADD(shost, counter, count)
|
#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.
|
* 'done_status' contains the command's ending status.
|
||||||
*/
|
*/
|
||||||
|
scp->result = 0;
|
||||||
switch (scsiqp->done_status) {
|
switch (scsiqp->done_status) {
|
||||||
case QD_NO_ERROR:
|
case QD_NO_ERROR:
|
||||||
ASC_DBG(2, "QD_NO_ERROR\n");
|
ASC_DBG(2, "QD_NO_ERROR\n");
|
||||||
scp->result = 0;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check for an underrun condition.
|
* 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");
|
ASC_DBG(2, "QD_WITH_ERROR\n");
|
||||||
switch (scsiqp->host_status) {
|
switch (scsiqp->host_status) {
|
||||||
case QHSTA_NO_ERROR:
|
case QHSTA_NO_ERROR:
|
||||||
|
set_status_byte(scp, scsiqp->scsi_status);
|
||||||
if (scsiqp->scsi_status == SAM_STAT_CHECK_CONDITION) {
|
if (scsiqp->scsi_status == SAM_STAT_CHECK_CONDITION) {
|
||||||
ASC_DBG(2, "SAM_STAT_CHECK_CONDITION\n");
|
ASC_DBG(2, "SAM_STAT_CHECK_CONDITION\n");
|
||||||
ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
|
ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
|
||||||
SCSI_SENSE_BUFFERSIZE);
|
SCSI_SENSE_BUFFERSIZE);
|
||||||
/*
|
set_driver_byte(scp, DRIVER_SENSE);
|
||||||
* 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);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/* Some other QHSTA error occurred. */
|
/* Some other QHSTA error occurred. */
|
||||||
ASC_DBG(1, "host_status 0x%x\n", scsiqp->host_status);
|
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;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case QD_ABORTED_BY_HOST:
|
case QD_ABORTED_BY_HOST:
|
||||||
ASC_DBG(1, "QD_ABORTED_BY_HOST\n");
|
ASC_DBG(1, "QD_ABORTED_BY_HOST\n");
|
||||||
scp->result =
|
set_status_byte(scp, scsiqp->scsi_status);
|
||||||
HOST_BYTE(DID_ABORT) | STATUS_BYTE(scsiqp->scsi_status);
|
set_host_byte(scp, DID_ABORT);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ASC_DBG(1, "done_status 0x%x\n", scsiqp->done_status);
|
ASC_DBG(1, "done_status 0x%x\n", scsiqp->done_status);
|
||||||
scp->result =
|
set_status_byte(scp, scsiqp->scsi_status);
|
||||||
HOST_BYTE(DID_ERROR) | STATUS_BYTE(scsiqp->scsi_status);
|
set_host_byte(scp, DID_ERROR);
|
||||||
break;
|
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.
|
* 'qdonep' contains the command's ending status.
|
||||||
*/
|
*/
|
||||||
|
scp->result = 0;
|
||||||
switch (qdonep->d3.done_stat) {
|
switch (qdonep->d3.done_stat) {
|
||||||
case QD_NO_ERROR:
|
case QD_NO_ERROR:
|
||||||
ASC_DBG(2, "QD_NO_ERROR\n");
|
ASC_DBG(2, "QD_NO_ERROR\n");
|
||||||
scp->result = 0;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check for an underrun condition.
|
* 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");
|
ASC_DBG(2, "QD_WITH_ERROR\n");
|
||||||
switch (qdonep->d3.host_stat) {
|
switch (qdonep->d3.host_stat) {
|
||||||
case QHSTA_NO_ERROR:
|
case QHSTA_NO_ERROR:
|
||||||
|
set_status_byte(scp, qdonep->d3.scsi_stat);
|
||||||
if (qdonep->d3.scsi_stat == SAM_STAT_CHECK_CONDITION) {
|
if (qdonep->d3.scsi_stat == SAM_STAT_CHECK_CONDITION) {
|
||||||
ASC_DBG(2, "SAM_STAT_CHECK_CONDITION\n");
|
ASC_DBG(2, "SAM_STAT_CHECK_CONDITION\n");
|
||||||
ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
|
ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
|
||||||
SCSI_SENSE_BUFFERSIZE);
|
SCSI_SENSE_BUFFERSIZE);
|
||||||
/*
|
set_driver_byte(scp, DRIVER_SENSE);
|
||||||
* 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);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/* QHSTA error occurred */
|
/* QHSTA error occurred */
|
||||||
ASC_DBG(1, "host_stat 0x%x\n", qdonep->d3.host_stat);
|
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;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case QD_ABORTED_BY_HOST:
|
case QD_ABORTED_BY_HOST:
|
||||||
ASC_DBG(1, "QD_ABORTED_BY_HOST\n");
|
ASC_DBG(1, "QD_ABORTED_BY_HOST\n");
|
||||||
scp->result =
|
set_status_byte(scp, qdonep->d3.scsi_stat);
|
||||||
HOST_BYTE(DID_ABORT) | MSG_BYTE(qdonep->d3.
|
set_msg_byte(scp, qdonep->d3.scsi_msg);
|
||||||
scsi_msg) |
|
set_host_byte(scp, DID_ABORT);
|
||||||
STATUS_BYTE(qdonep->d3.scsi_stat);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ASC_DBG(1, "done_stat 0x%x\n", qdonep->d3.done_stat);
|
ASC_DBG(1, "done_stat 0x%x\n", qdonep->d3.done_stat);
|
||||||
scp->result =
|
set_status_byte(scp, qdonep->d3.scsi_stat);
|
||||||
HOST_BYTE(DID_ERROR) | MSG_BYTE(qdonep->d3.
|
set_msg_byte(scp, qdonep->d3.scsi_msg);
|
||||||
scsi_msg) |
|
set_host_byte(scp, DID_ERROR);
|
||||||
STATUS_BYTE(qdonep->d3.scsi_stat);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -7558,7 +7522,7 @@ static int asc_build_req(struct asc_board *boardp, struct scsi_cmnd *scp,
|
|||||||
"sg_tablesize %d\n", use_sg,
|
"sg_tablesize %d\n", use_sg,
|
||||||
scp->device->host->sg_tablesize);
|
scp->device->host->sg_tablesize);
|
||||||
scsi_dma_unmap(scp);
|
scsi_dma_unmap(scp);
|
||||||
scp->result = HOST_BYTE(DID_ERROR);
|
set_host_byte(scp, DID_ERROR);
|
||||||
return ASC_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);
|
use_sg * sizeof(struct asc_sg_list), GFP_ATOMIC);
|
||||||
if (!asc_sg_head) {
|
if (!asc_sg_head) {
|
||||||
scsi_dma_unmap(scp);
|
scsi_dma_unmap(scp);
|
||||||
scp->result = HOST_BYTE(DID_SOFT_ERROR);
|
set_host_byte(scp, DID_SOFT_ERROR);
|
||||||
return ASC_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,
|
"ADV_MAX_SG_LIST %d\n", use_sg,
|
||||||
scp->device->host->sg_tablesize);
|
scp->device->host->sg_tablesize);
|
||||||
scsi_dma_unmap(scp);
|
scsi_dma_unmap(scp);
|
||||||
scp->result = HOST_BYTE(DID_ERROR);
|
set_host_byte(scp, DID_ERROR);
|
||||||
reqp->cmndp = NULL;
|
reqp->cmndp = NULL;
|
||||||
scp->host_scribble = 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);
|
ret = adv_get_sglist(boardp, reqp, scsiqp, scp, use_sg);
|
||||||
if (ret != ADV_SUCCESS) {
|
if (ret != ADV_SUCCESS) {
|
||||||
scsi_dma_unmap(scp);
|
scsi_dma_unmap(scp);
|
||||||
scp->result = HOST_BYTE(DID_ERROR);
|
set_host_byte(scp, DID_ERROR);
|
||||||
reqp->cmndp = NULL;
|
reqp->cmndp = NULL;
|
||||||
scp->host_scribble = 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, "
|
scmd_printk(KERN_ERR, scp, "ExeScsiQueue() ASC_ERROR, "
|
||||||
"err_code 0x%x\n", err_code);
|
"err_code 0x%x\n", err_code);
|
||||||
ASC_STATS(scp->device->host, exe_error);
|
ASC_STATS(scp->device->host, exe_error);
|
||||||
scp->result = HOST_BYTE(DID_ERROR);
|
set_host_byte(scp, DID_ERROR);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
scmd_printk(KERN_ERR, scp, "ExeScsiQueue() unknown, "
|
scmd_printk(KERN_ERR, scp, "ExeScsiQueue() unknown, "
|
||||||
"err_code 0x%x\n", err_code);
|
"err_code 0x%x\n", err_code);
|
||||||
ASC_STATS(scp->device->host, exe_unknown);
|
ASC_STATS(scp->device->host, exe_unknown);
|
||||||
scp->result = HOST_BYTE(DID_ERROR);
|
set_host_byte(scp, DID_ERROR);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -119,8 +119,10 @@ static int aha1542_out(unsigned int base, u8 *buf, int len)
|
|||||||
return 0;
|
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)
|
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;
|
break;
|
||||||
|
|
||||||
case 0x11: /* Selection time out-The initiator selection or target
|
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;
|
hosterr = DID_TIME_OUT;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x12: /* Data overrun/underrun-The target attempted to transfer more data
|
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
|
* than was allocated by the Data Length field or the sum of the
|
||||||
Scatter / Gather Data Length fields. */
|
* Scatter / Gather Data Length fields.
|
||||||
|
*/
|
||||||
|
|
||||||
case 0x13: /* Unexpected bus free-The target dropped the SCSI BSY at an unexpected time. */
|
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
|
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.
|
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
|
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
|
* of linked CCB's does not specify the same logical unit number as
|
||||||
the first. */
|
* the first.
|
||||||
|
*/
|
||||||
case 0x18: /* Invalid Target Direction received from Host-The direction of a
|
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
|
case 0x19: /* Duplicate CCB Received in Target Mode-More than once CCB was
|
||||||
received to service data transfer between the same target LUN
|
* received to service data transfer between the same target LUN
|
||||||
and initiator SCSI ID in the same direction. */
|
* and initiator SCSI ID in the same direction.
|
||||||
|
*/
|
||||||
|
|
||||||
case 0x1a: /* Invalid CCB or Segment List Parameter-A segment list with a zero
|
case 0x1a: /* Invalid CCB or Segment List Parameter-A segment list with a zero
|
||||||
length segment or invalid segment list boundaries was received.
|
* length segment or invalid segment list boundaries was received.
|
||||||
A CCB parameter was invalid. */
|
* A CCB parameter was invalid.
|
||||||
|
*/
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printk("Aha1542: %x %x\n", hosterr, scsierr);
|
printk("Aha1542: %x %x\n", hosterr, scsierr);
|
||||||
#endif
|
#endif
|
||||||
@@ -178,9 +188,10 @@ static int makecode(unsigned hosterr, unsigned scsierr)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x14: /* Target bus phase sequence failure-An invalid bus phase or bus
|
case 0x14: /* Target bus phase sequence failure-An invalid bus phase or bus
|
||||||
phase sequence was requested by the target. The host adapter
|
* phase sequence was requested by the target. The host adapter
|
||||||
will generate a SCSI Reset Condition, notifying the host with
|
* will generate a SCSI Reset Condition, notifying the host with
|
||||||
a SCRD interrupt */
|
* a SCRD interrupt
|
||||||
|
*/
|
||||||
hosterr = DID_RESET;
|
hosterr = DID_RESET;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -216,8 +227,10 @@ static int aha1542_test_port(struct Scsi_Host *sh)
|
|||||||
if (inb(INTRFLAGS(sh->io_port)) & INTRMASK)
|
if (inb(INTRFLAGS(sh->io_port)) & INTRMASK)
|
||||||
return 0;
|
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);
|
aha1542_outb(sh->io_port, CMD_INQUIRY);
|
||||||
|
|
||||||
@@ -292,10 +305,12 @@ static irqreturn_t aha1542_interrupt(int irq, void *dev_id)
|
|||||||
while (1) {
|
while (1) {
|
||||||
flag = inb(INTRFLAGS(sh->io_port));
|
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
|
* Check for unusual interrupts. If any of these happen, we should
|
||||||
is sufficient. A SCSI reset detected is something that we really
|
* probably do something special, but for now just printing a message
|
||||||
need to deal with in some way. */
|
* is sufficient. A SCSI reset detected is something that we really
|
||||||
|
* need to deal with in some way.
|
||||||
|
*/
|
||||||
if (flag & ~MBIF) {
|
if (flag & ~MBIF) {
|
||||||
if (flag & MBOA)
|
if (flag & MBOA)
|
||||||
printk("MBOF ");
|
printk("MBOF ");
|
||||||
@@ -355,9 +370,11 @@ static irqreturn_t aha1542_interrupt(int irq, void *dev_id)
|
|||||||
}
|
}
|
||||||
my_done = tmp_cmd->scsi_done;
|
my_done = tmp_cmd->scsi_done;
|
||||||
aha1542_free_cmd(tmp_cmd);
|
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
|
* Fetch the sense data, and tuck it away, in the required slot. The
|
||||||
we will still have it in the cdb when we come back */
|
* 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)
|
if (ccb[mbo].tarstat == 2)
|
||||||
memcpy(tmp_cmd->sense_buffer, &ccb[mbo].cdb[ccb[mbo].cdblen],
|
memcpy(tmp_cmd->sense_buffer, &ccb[mbo].cdb[ccb[mbo].cdblen],
|
||||||
SCSI_SENSE_BUFFERSIZE);
|
SCSI_SENSE_BUFFERSIZE);
|
||||||
@@ -383,7 +400,8 @@ static irqreturn_t aha1542_interrupt(int irq, void *dev_id)
|
|||||||
#endif
|
#endif
|
||||||
tmp_cmd->result = errstatus;
|
tmp_cmd->result = errstatus;
|
||||||
aha1542->int_cmds[mbo] = NULL; /* This effectively frees up the mailbox slot, as
|
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);
|
my_done(tmp_cmd);
|
||||||
number_serviced++;
|
number_serviced++;
|
||||||
};
|
};
|
||||||
@@ -433,8 +451,10 @@ static int aha1542_queuecommand(struct Scsi_Host *sh, struct scsi_cmnd *cmd)
|
|||||||
goto out_free_chain;
|
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);
|
spin_lock_irqsave(sh->host_lock, flags);
|
||||||
mbo = aha1542->aha1542_last_mbo_used + 1;
|
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");
|
panic("Unable to find empty mailbox for aha1542.\n");
|
||||||
|
|
||||||
aha1542->int_cmds[mbo] = cmd; /* This will effectively prevent someone else from
|
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;
|
aha1542->aha1542_last_mbo_used = mbo;
|
||||||
|
|
||||||
@@ -565,8 +586,10 @@ static int aha1542_getconfig(struct Scsi_Host *sh)
|
|||||||
sh->dma_channel = 0;
|
sh->dma_channel = 0;
|
||||||
break;
|
break;
|
||||||
case 0:
|
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;
|
sh->dma_channel = 0xFF;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -600,8 +623,10 @@ static int aha1542_getconfig(struct Scsi_Host *sh)
|
|||||||
return 0;
|
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)
|
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 */
|
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
|
* For an AHA1740 series board, we ignore the board since there is a
|
||||||
is operating in the 1542 emulation mode. Since there is an extended mode
|
* hardware bug which can lead to wrong blocks being returned if the board
|
||||||
driver, we simply ignore the board and let the 1740 driver pick it up.
|
* 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) {
|
if (inquiry_result[0] == 0x43) {
|
||||||
@@ -666,8 +692,10 @@ static int aha1542_query(struct Scsi_Host *sh)
|
|||||||
return 1;
|
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);
|
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");
|
panic("Unable to find empty mailbox for aha1542.\n");
|
||||||
|
|
||||||
aha1542->int_cmds[mbo] = cmd; /* This will effectively
|
aha1542->int_cmds[mbo] = cmd; /* This will effectively
|
||||||
prevent someone else from
|
* prevent someone else from
|
||||||
screwing with this cdb. */
|
* screwing with this cdb.
|
||||||
|
*/
|
||||||
|
|
||||||
aha1542->aha1542_last_mbo_used = mbo;
|
aha1542->aha1542_last_mbo_used = mbo;
|
||||||
|
|
||||||
@@ -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);
|
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]);
|
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_CDB 12
|
||||||
#define MAX_SENSE 14
|
#define MAX_SENSE 14
|
||||||
|
|
||||||
struct ccb { /* Command Control Block 5.3 */
|
/* Command Control Block (CCB), 5.3 */
|
||||||
u8 op; /* Command Control Block Operation Code */
|
struct ccb {
|
||||||
u8 idlun; /* op=0,2:Target Id, op=1:Initiator Id */
|
u8 op; /* Command Control Block Operation Code: */
|
||||||
/* Outbound data transfer, length is checked*/
|
/* 0x00: SCSI Initiator CCB, 0x01: SCSI Target CCB, */
|
||||||
/* Inbound data transfer, length is checked */
|
/* 0x02: SCSI Initiator CCB with Scatter/Gather, */
|
||||||
/* Logical Unit Number */
|
/* 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 cdblen; /* SCSI Command Length */
|
||||||
u8 rsalen; /* Request Sense Allocation Length/Disable */
|
u8 rsalen; /* Request Sense Allocation Length/Disable Auto Sense */
|
||||||
u8 datalen[3]; /* Data Length (msb, .., lsb) */
|
u8 datalen[3]; /* Data Length (MSB, ..., LSB) */
|
||||||
u8 dataptr[3]; /* Data Pointer */
|
u8 dataptr[3]; /* Data Pointer (MSB, ..., LSB) */
|
||||||
u8 linkptr[3]; /* Link Pointer */
|
u8 linkptr[3]; /* Link Pointer (MSB, ..., LSB) */
|
||||||
u8 commlinkid; /* Command Linking Identifier */
|
u8 commlinkid; /* Command Linking Identifier */
|
||||||
u8 hastat; /* Host Adapter Status (HASTAT) */
|
u8 hastat; /* Host Adapter Status (HASTAT) */
|
||||||
u8 tarstat; /* Target Device Status */
|
u8 tarstat; /* Target Device Status (TARSTAT) */
|
||||||
u8 reserved[2];
|
u8 reserved[2];
|
||||||
u8 cdb[MAX_CDB+MAX_SENSE]; /* SCSI Command Descriptor Block */
|
u8 cdb[MAX_CDB + MAX_SENSE]; /* SCSI Command Descriptor Block */
|
||||||
/* REQUEST SENSE */
|
/* followed by the Auto Sense data */
|
||||||
};
|
};
|
||||||
|
|
||||||
#define AHA1542_REGION_SIZE 4
|
#define AHA1542_REGION_SIZE 4
|
||||||
|
|||||||
@@ -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[] =
|
static const struct ahd_phase_table_entry ahd_phase_table[] =
|
||||||
{
|
{
|
||||||
{ P_DATAOUT, MSG_NOOP, "in Data-out phase" },
|
{ P_DATAOUT, NOP, "in Data-out phase" },
|
||||||
{ P_DATAIN, MSG_INITIATOR_DET_ERR, "in Data-in phase" },
|
{ P_DATAIN, INITIATOR_ERROR, "in Data-in phase" },
|
||||||
{ P_DATAOUT_DT, MSG_NOOP, "in DT Data-out phase" },
|
{ P_DATAOUT_DT, NOP, "in DT Data-out phase" },
|
||||||
{ P_DATAIN_DT, MSG_INITIATOR_DET_ERR, "in DT Data-in phase" },
|
{ P_DATAIN_DT, INITIATOR_ERROR, "in DT Data-in phase" },
|
||||||
{ P_COMMAND, MSG_NOOP, "in Command phase" },
|
{ P_COMMAND, NOP, "in Command phase" },
|
||||||
{ P_MESGOUT, MSG_NOOP, "in Message-out phase" },
|
{ P_MESGOUT, NOP, "in Message-out phase" },
|
||||||
{ P_STATUS, MSG_INITIATOR_DET_ERR, "in Status phase" },
|
{ P_STATUS, INITIATOR_ERROR, "in Status phase" },
|
||||||
{ P_MESGIN, MSG_PARITY_ERROR, "in Message-in phase" },
|
{ P_MESGIN, MSG_PARITY_ERROR, "in Message-in phase" },
|
||||||
{ P_BUSFREE, MSG_NOOP, "while idle" },
|
{ P_BUSFREE, NOP, "while idle" },
|
||||||
{ 0, MSG_NOOP, "in unknown phase" }
|
{ 0, NOP, "in unknown phase" }
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1126,7 +1126,7 @@ ahd_restart(struct ahd_softc *ahd)
|
|||||||
/* No more pending messages */
|
/* No more pending messages */
|
||||||
ahd_clear_msg_state(ahd);
|
ahd_clear_msg_state(ahd);
|
||||||
ahd_outb(ahd, SCSISIGO, 0); /* De-assert BSY */
|
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, SXFRCTL1, ahd_inb(ahd, SXFRCTL1) & ~BITBUCKET);
|
||||||
ahd_outb(ahd, SEQINTCTL, 0);
|
ahd_outb(ahd, SEQINTCTL, 0);
|
||||||
ahd_outb(ahd, LASTPHASE, P_BUSFREE);
|
ahd_outb(ahd, LASTPHASE, P_BUSFREE);
|
||||||
@@ -2007,7 +2007,7 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat)
|
|||||||
*/
|
*/
|
||||||
ahd_assert_atn(ahd);
|
ahd_assert_atn(ahd);
|
||||||
ahd_outb(ahd, MSG_OUT, HOST_MSG);
|
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_len = 1;
|
||||||
ahd->msgout_index = 0;
|
ahd->msgout_index = 0;
|
||||||
ahd->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
|
ahd->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
|
||||||
@@ -2094,8 +2094,7 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat)
|
|||||||
ahd->msg_type =
|
ahd->msg_type =
|
||||||
MSG_TYPE_TARGET_MSGOUT;
|
MSG_TYPE_TARGET_MSGOUT;
|
||||||
ahd->msgin_index = 0;
|
ahd->msgin_index = 0;
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
ahd_setup_target_msgin(ahd,
|
ahd_setup_target_msgin(ahd,
|
||||||
&devinfo,
|
&devinfo,
|
||||||
scb);
|
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("SXFRCTL0 == 0x%x\n", ahd_inb(ahd, SXFRCTL0));
|
||||||
printk("SEQCTL0 == 0x%x\n", ahd_inb(ahd, SEQCTL0));
|
printk("SEQCTL0 == 0x%x\n", ahd_inb(ahd, SEQCTL0));
|
||||||
ahd_dump_card_state(ahd);
|
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_len = 1;
|
||||||
ahd->msgout_index = 0;
|
ahd->msgout_index = 0;
|
||||||
ahd->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
|
ahd->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
|
||||||
@@ -2692,7 +2691,7 @@ ahd_handle_transmission_error(struct ahd_softc *ahd)
|
|||||||
lastphase = ahd_inb(ahd, LASTPHASE);
|
lastphase = ahd_inb(ahd, LASTPHASE);
|
||||||
curphase = ahd_inb(ahd, SCSISIGI) & PHASE_MASK;
|
curphase = ahd_inb(ahd, SCSISIGI) & PHASE_MASK;
|
||||||
perrdiag = ahd_inb(ahd, PERRDIAG);
|
perrdiag = ahd_inb(ahd, PERRDIAG);
|
||||||
msg_out = MSG_INITIATOR_DET_ERR;
|
msg_out = INITIATOR_ERROR;
|
||||||
ahd_outb(ahd, CLRSINT1, CLRSCSIPERR);
|
ahd_outb(ahd, CLRSINT1, CLRSCSIPERR);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -2828,10 +2827,10 @@ ahd_handle_transmission_error(struct ahd_softc *ahd)
|
|||||||
* get a parity error on "in" phases, so all we
|
* get a parity error on "in" phases, so all we
|
||||||
* need to do is stuff the message buffer with
|
* need to do is stuff the message buffer with
|
||||||
* the appropriate message. "In" phases have set
|
* 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;
|
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;
|
scb->flags |= SCB_TRANSMISSION_ERROR;
|
||||||
ahd_outb(ahd, MSG_OUT, HOST_MSG);
|
ahd_outb(ahd, MSG_OUT, HOST_MSG);
|
||||||
ahd_outb(ahd, CLRINT, CLRSCSIINT);
|
ahd_outb(ahd, CLRINT, CLRSCSIINT);
|
||||||
@@ -3051,8 +3050,8 @@ ahd_handle_nonpkt_busfree(struct ahd_softc *ahd)
|
|||||||
u_int tag;
|
u_int tag;
|
||||||
|
|
||||||
tag = SCB_LIST_NULL;
|
tag = SCB_LIST_NULL;
|
||||||
if (ahd_sent_msg(ahd, AHDMSG_1B, MSG_ABORT_TAG, TRUE)
|
if (ahd_sent_msg(ahd, AHDMSG_1B, ABORT_TASK, TRUE)
|
||||||
|| ahd_sent_msg(ahd, AHDMSG_1B, MSG_ABORT, TRUE)) {
|
|| ahd_sent_msg(ahd, AHDMSG_1B, ABORT_TASK_SET, TRUE)) {
|
||||||
int found;
|
int found;
|
||||||
int sent_msg;
|
int sent_msg;
|
||||||
|
|
||||||
@@ -3067,9 +3066,9 @@ ahd_handle_nonpkt_busfree(struct ahd_softc *ahd)
|
|||||||
ahd_print_path(ahd, scb);
|
ahd_print_path(ahd, scb);
|
||||||
printk("SCB %d - Abort%s Completed.\n",
|
printk("SCB %d - Abort%s Completed.\n",
|
||||||
SCB_GET_TAG(scb),
|
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);
|
tag = SCB_GET_TAG(scb);
|
||||||
|
|
||||||
if ((scb->flags & SCB_EXTERNAL_RESET) != 0) {
|
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);
|
printk("found == 0x%x\n", found);
|
||||||
printerror = 0;
|
printerror = 0;
|
||||||
} else if (ahd_sent_msg(ahd, AHDMSG_1B,
|
} else if (ahd_sent_msg(ahd, AHDMSG_1B,
|
||||||
MSG_BUS_DEV_RESET, TRUE)) {
|
TARGET_RESET, TRUE)) {
|
||||||
ahd_handle_devreset(ahd, &devinfo, CAM_LUN_WILDCARD,
|
ahd_handle_devreset(ahd, &devinfo, CAM_LUN_WILDCARD,
|
||||||
CAM_BDR_SENT, "Bus Device Reset",
|
CAM_BDR_SENT, "Bus Device Reset",
|
||||||
/*verbose_level*/0);
|
/*verbose_level*/0);
|
||||||
printerror = 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) {
|
&& ppr_busfree == 0) {
|
||||||
struct ahd_initiator_tinfo *tinfo;
|
struct ahd_initiator_tinfo *tinfo;
|
||||||
struct ahd_tmode_tstate *tstate;
|
struct ahd_tmode_tstate *tstate;
|
||||||
@@ -3152,7 +3151,7 @@ ahd_handle_nonpkt_busfree(struct ahd_softc *ahd)
|
|||||||
}
|
}
|
||||||
printerror = 0;
|
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) {
|
&& ppr_busfree == 0) {
|
||||||
/*
|
/*
|
||||||
* Negotiation Rejected. Go-narrow and
|
* Negotiation Rejected. Go-narrow and
|
||||||
@@ -3177,7 +3176,7 @@ ahd_handle_nonpkt_busfree(struct ahd_softc *ahd)
|
|||||||
ahd_qinfifo_requeue_tail(ahd, scb);
|
ahd_qinfifo_requeue_tail(ahd, scb);
|
||||||
}
|
}
|
||||||
printerror = 0;
|
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) {
|
&& ppr_busfree == 0) {
|
||||||
/*
|
/*
|
||||||
* Negotiation Rejected. Go-async and
|
* Negotiation Rejected. Go-async and
|
||||||
@@ -3205,7 +3204,7 @@ ahd_handle_nonpkt_busfree(struct ahd_softc *ahd)
|
|||||||
printerror = 0;
|
printerror = 0;
|
||||||
} else if ((ahd->msg_flags & MSG_FLAG_EXPECT_IDE_BUSFREE) != 0
|
} else if ((ahd->msg_flags & MSG_FLAG_EXPECT_IDE_BUSFREE) != 0
|
||||||
&& ahd_sent_msg(ahd, AHDMSG_1B,
|
&& ahd_sent_msg(ahd, AHDMSG_1B,
|
||||||
MSG_INITIATOR_DET_ERR, TRUE)) {
|
INITIATOR_ERROR, TRUE)) {
|
||||||
|
|
||||||
#ifdef AHD_DEBUG
|
#ifdef AHD_DEBUG
|
||||||
if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
|
if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
|
||||||
@@ -3214,7 +3213,7 @@ ahd_handle_nonpkt_busfree(struct ahd_softc *ahd)
|
|||||||
printerror = 0;
|
printerror = 0;
|
||||||
} else if ((ahd->msg_flags & MSG_FLAG_EXPECT_QASREJ_BUSFREE)
|
} else if ((ahd->msg_flags & MSG_FLAG_EXPECT_QASREJ_BUSFREE)
|
||||||
&& ahd_sent_msg(ahd, AHDMSG_1B,
|
&& ahd_sent_msg(ahd, AHDMSG_1B,
|
||||||
MSG_MESSAGE_REJECT, TRUE)) {
|
MESSAGE_REJECT, TRUE)) {
|
||||||
|
|
||||||
#ifdef AHD_DEBUG
|
#ifdef AHD_DEBUG
|
||||||
if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
|
if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
|
||||||
@@ -3368,7 +3367,7 @@ proto_violation_reset:
|
|||||||
ahd_outb(ahd, MSG_OUT, HOST_MSG);
|
ahd_outb(ahd, MSG_OUT, HOST_MSG);
|
||||||
if (scb == NULL) {
|
if (scb == NULL) {
|
||||||
ahd_print_devinfo(ahd, &devinfo);
|
ahd_print_devinfo(ahd, &devinfo);
|
||||||
ahd->msgout_buf[0] = MSG_ABORT_TASK;
|
ahd->msgout_buf[0] = ABORT_TASK;
|
||||||
ahd->msgout_len = 1;
|
ahd->msgout_len = 1;
|
||||||
ahd->msgout_index = 0;
|
ahd->msgout_index = 0;
|
||||||
ahd->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
|
ahd->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
|
||||||
@@ -3446,7 +3445,6 @@ ahd_clear_critical_section(struct ahd_softc *ahd)
|
|||||||
|
|
||||||
cs = ahd->critical_sections;
|
cs = ahd->critical_sections;
|
||||||
for (i = 0; i < ahd->num_critical_sections; i++, cs++) {
|
for (i = 0; i < ahd->num_critical_sections; i++, cs++) {
|
||||||
|
|
||||||
if (cs->begin < seqaddr && cs->end >= seqaddr)
|
if (cs->begin < seqaddr && cs->end >= seqaddr)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -4391,7 +4389,7 @@ ahd_setup_initiator_msgout(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
|
|||||||
} else if (scb == NULL) {
|
} else if (scb == NULL) {
|
||||||
printk("%s: WARNING. No pending message for "
|
printk("%s: WARNING. No pending message for "
|
||||||
"I_T msgin. Issuing NO-OP\n", ahd_name(ahd));
|
"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->msgout_len++;
|
||||||
ahd->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
|
ahd->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
|
||||||
return;
|
return;
|
||||||
@@ -4417,7 +4415,7 @@ ahd_setup_initiator_msgout(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (scb->flags & SCB_DEVICE_RESET) {
|
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->msgout_len++;
|
||||||
ahd_print_path(ahd, scb);
|
ahd_print_path(ahd, scb);
|
||||||
printk("Bus Device Reset Message Sent\n");
|
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) {
|
} else if ((scb->flags & SCB_ABORT) != 0) {
|
||||||
|
|
||||||
if ((scb->hscb->control & TAG_ENB) != 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 {
|
} else {
|
||||||
ahd->msgout_buf[ahd->msgout_index++] = MSG_ABORT;
|
ahd->msgout_buf[ahd->msgout_index++] = ABORT_TASK_SET;
|
||||||
}
|
}
|
||||||
ahd->msgout_len++;
|
ahd->msgout_len++;
|
||||||
ahd_print_path(ahd, scb);
|
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, CLRSINT1, CLRATNO);
|
||||||
}
|
}
|
||||||
ahd_outb(ahd, MSG_OUT, MSG_NOOP);
|
ahd_outb(ahd, MSG_OUT, NOP);
|
||||||
ahd_outb(ahd, SEQ_FLAGS2,
|
ahd_outb(ahd, SEQ_FLAGS2,
|
||||||
ahd_inb(ahd, SEQ_FLAGS2) & ~TARGET_MSG_PENDING);
|
ahd_inb(ahd, SEQ_FLAGS2) & ~TARGET_MSG_PENDING);
|
||||||
ahd_restore_modes(ahd, saved_modes);
|
ahd_restore_modes(ahd, saved_modes);
|
||||||
@@ -4747,7 +4745,7 @@ reswitch:
|
|||||||
* with a busfree.
|
* with a busfree.
|
||||||
*/
|
*/
|
||||||
if ((ahd->msg_flags & MSG_FLAG_PACKETIZED) != 0
|
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->msg_flags |= MSG_FLAG_EXPECT_IDE_BUSFREE;
|
||||||
|
|
||||||
ahd_outb(ahd, RETURN_2, ahd->send_msg_perror);
|
ahd_outb(ahd, RETURN_2, ahd->send_msg_perror);
|
||||||
@@ -5025,7 +5023,7 @@ ahd_sent_msg(struct ahd_softc *ahd, ahd_msgtype type, u_int msgval, int full)
|
|||||||
index = 0;
|
index = 0;
|
||||||
|
|
||||||
while (index < ahd->msgout_len) {
|
while (index < ahd->msgout_len) {
|
||||||
if (ahd->msgout_buf[index] == MSG_EXTENDED) {
|
if (ahd->msgout_buf[index] == EXTENDED_MESSAGE) {
|
||||||
u_int end_index;
|
u_int end_index;
|
||||||
|
|
||||||
end_index = index + 1 + ahd->msgout_buf[index + 1];
|
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;
|
found = TRUE;
|
||||||
}
|
}
|
||||||
index = end_index;
|
index = end_index;
|
||||||
} else if (ahd->msgout_buf[index] >= MSG_SIMPLE_TASK
|
} else if (ahd->msgout_buf[index] >= SIMPLE_QUEUE_TAG
|
||||||
&& ahd->msgout_buf[index] <= MSG_IGN_WIDE_RESIDUE) {
|
&& ahd->msgout_buf[index] <= IGNORE_WIDE_RESIDUE) {
|
||||||
|
|
||||||
/* Skip tag type and tag id or residue param*/
|
/* Skip tag type and tag id or residue param*/
|
||||||
index += 2;
|
index += 2;
|
||||||
@@ -5091,30 +5089,30 @@ ahd_parse_msg(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
|
|||||||
* extended message type.
|
* extended message type.
|
||||||
*/
|
*/
|
||||||
switch (ahd->msgin_buf[0]) {
|
switch (ahd->msgin_buf[0]) {
|
||||||
case MSG_DISCONNECT:
|
case DISCONNECT:
|
||||||
case MSG_SAVEDATAPOINTER:
|
case SAVE_POINTERS:
|
||||||
case MSG_CMDCOMPLETE:
|
case COMMAND_COMPLETE:
|
||||||
case MSG_RESTOREPOINTERS:
|
case RESTORE_POINTERS:
|
||||||
case MSG_IGN_WIDE_RESIDUE:
|
case IGNORE_WIDE_RESIDUE:
|
||||||
/*
|
/*
|
||||||
* End our message loop as these are messages
|
* End our message loop as these are messages
|
||||||
* the sequencer handles on its own.
|
* the sequencer handles on its own.
|
||||||
*/
|
*/
|
||||||
done = MSGLOOP_TERMINATED;
|
done = MSGLOOP_TERMINATED;
|
||||||
break;
|
break;
|
||||||
case MSG_MESSAGE_REJECT:
|
case MESSAGE_REJECT:
|
||||||
response = ahd_handle_msg_reject(ahd, devinfo);
|
response = ahd_handle_msg_reject(ahd, devinfo);
|
||||||
fallthrough;
|
fallthrough;
|
||||||
case MSG_NOOP:
|
case NOP:
|
||||||
done = MSGLOOP_MSGCOMPLETE;
|
done = MSGLOOP_MSGCOMPLETE;
|
||||||
break;
|
break;
|
||||||
case MSG_EXTENDED:
|
case EXTENDED_MESSAGE:
|
||||||
{
|
{
|
||||||
/* Wait for enough of the message to begin validation */
|
/* Wait for enough of the message to begin validation */
|
||||||
if (ahd->msgin_index < 2)
|
if (ahd->msgin_index < 2)
|
||||||
break;
|
break;
|
||||||
switch (ahd->msgin_buf[2]) {
|
switch (ahd->msgin_buf[2]) {
|
||||||
case MSG_EXT_SDTR:
|
case EXTENDED_SDTR:
|
||||||
{
|
{
|
||||||
u_int period;
|
u_int period;
|
||||||
u_int ppr_options;
|
u_int ppr_options;
|
||||||
@@ -5162,7 +5160,7 @@ ahd_parse_msg(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
|
|||||||
* and didn't have to fall down to async
|
* and didn't have to fall down to async
|
||||||
* transfers.
|
* 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 */
|
/* We started it */
|
||||||
if (saved_offset != offset) {
|
if (saved_offset != offset) {
|
||||||
/* Went too low - force async */
|
/* Went too low - force async */
|
||||||
@@ -5189,7 +5187,7 @@ ahd_parse_msg(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
|
|||||||
done = MSGLOOP_MSGCOMPLETE;
|
done = MSGLOOP_MSGCOMPLETE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MSG_EXT_WDTR:
|
case EXTENDED_WDTR:
|
||||||
{
|
{
|
||||||
u_int bus_width;
|
u_int bus_width;
|
||||||
u_int saved_width;
|
u_int saved_width;
|
||||||
@@ -5223,7 +5221,7 @@ ahd_parse_msg(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
|
|||||||
saved_width, bus_width);
|
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
|
* Don't send a WDTR back to the
|
||||||
* target, since we asked first.
|
* target, since we asked first.
|
||||||
@@ -5285,7 +5283,7 @@ ahd_parse_msg(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
|
|||||||
done = MSGLOOP_MSGCOMPLETE;
|
done = MSGLOOP_MSGCOMPLETE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MSG_EXT_PPR:
|
case EXTENDED_PPR:
|
||||||
{
|
{
|
||||||
u_int period;
|
u_int period;
|
||||||
u_int offset;
|
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,
|
ahd_validate_offset(ahd, tinfo, period, &offset,
|
||||||
bus_width, devinfo->role);
|
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
|
* If we are unable to do any of the
|
||||||
* requested options (we went too low),
|
* requested options (we went too low),
|
||||||
@@ -5403,7 +5401,7 @@ ahd_parse_msg(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#ifdef AHD_TARGET_MODE
|
#ifdef AHD_TARGET_MODE
|
||||||
case MSG_BUS_DEV_RESET:
|
case TARGET_RESET:
|
||||||
ahd_handle_devreset(ahd, devinfo, CAM_LUN_WILDCARD,
|
ahd_handle_devreset(ahd, devinfo, CAM_LUN_WILDCARD,
|
||||||
CAM_BDR_SENT,
|
CAM_BDR_SENT,
|
||||||
"Bus Device Reset Received",
|
"Bus Device Reset Received",
|
||||||
@@ -5411,9 +5409,9 @@ ahd_parse_msg(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
|
|||||||
ahd_restart(ahd);
|
ahd_restart(ahd);
|
||||||
done = MSGLOOP_TERMINATED;
|
done = MSGLOOP_TERMINATED;
|
||||||
break;
|
break;
|
||||||
case MSG_ABORT_TAG:
|
case ABORT_TASK:
|
||||||
case MSG_ABORT:
|
case ABORT_TASK_SET:
|
||||||
case MSG_CLEAR_QUEUE:
|
case CLEAR_TASK_SET:
|
||||||
{
|
{
|
||||||
int tag;
|
int tag;
|
||||||
|
|
||||||
@@ -5423,7 +5421,7 @@ ahd_parse_msg(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
tag = SCB_LIST_NULL;
|
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);
|
tag = ahd_inb(ahd, INITIATOR_TAG);
|
||||||
ahd_abort_scbs(ahd, devinfo->target, devinfo->channel,
|
ahd_abort_scbs(ahd, devinfo->target, devinfo->channel,
|
||||||
devinfo->lun, tag, ROLE_TARGET,
|
devinfo->lun, tag, ROLE_TARGET,
|
||||||
@@ -5447,7 +5445,7 @@ ahd_parse_msg(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
case MSG_QAS_REQUEST:
|
case QAS_REQUEST:
|
||||||
#ifdef AHD_DEBUG
|
#ifdef AHD_DEBUG
|
||||||
if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
|
if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
|
||||||
printk("%s: QAS request. SCSISIGI == 0x%x\n",
|
printk("%s: QAS request. SCSISIGI == 0x%x\n",
|
||||||
@@ -5455,7 +5453,7 @@ ahd_parse_msg(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
|
|||||||
#endif
|
#endif
|
||||||
ahd->msg_flags |= MSG_FLAG_EXPECT_QASREJ_BUSFREE;
|
ahd->msg_flags |= MSG_FLAG_EXPECT_QASREJ_BUSFREE;
|
||||||
fallthrough;
|
fallthrough;
|
||||||
case MSG_TERM_IO_PROC:
|
case TERMINATE_IO_PROC:
|
||||||
default:
|
default:
|
||||||
reject = TRUE;
|
reject = TRUE;
|
||||||
break;
|
break;
|
||||||
@@ -5467,7 +5465,7 @@ ahd_parse_msg(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
|
|||||||
*/
|
*/
|
||||||
ahd->msgout_index = 0;
|
ahd->msgout_index = 0;
|
||||||
ahd->msgout_len = 1;
|
ahd->msgout_len = 1;
|
||||||
ahd->msgout_buf[0] = MSG_MESSAGE_REJECT;
|
ahd->msgout_buf[0] = MESSAGE_REJECT;
|
||||||
done = MSGLOOP_MSGCOMPLETE;
|
done = MSGLOOP_MSGCOMPLETE;
|
||||||
response = TRUE;
|
response = TRUE;
|
||||||
}
|
}
|
||||||
@@ -5506,8 +5504,8 @@ ahd_handle_msg_reject(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
|
|||||||
/* Might be necessary */
|
/* Might be necessary */
|
||||||
last_msg = ahd_inb(ahd, LAST_MSG);
|
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, EXTENDED_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*/TRUE)
|
||||||
&& tinfo->goal.period <= AHD_SYNCRATE_PACED) {
|
&& tinfo->goal.period <= AHD_SYNCRATE_PACED) {
|
||||||
/*
|
/*
|
||||||
* Target may not like our SPI-4 PPR Options.
|
* 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_build_transfer_msg(ahd, devinfo);
|
||||||
ahd->msgout_index = 0;
|
ahd->msgout_index = 0;
|
||||||
response = 1;
|
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 */
|
/* note 8bit xfers */
|
||||||
printk("(%s:%c:%d:%d): refuses WIDE negotiation. Using "
|
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;
|
ahd->msgout_index = 0;
|
||||||
response = 1;
|
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 */
|
/* note asynch xfers and clear flag */
|
||||||
ahd_set_syncrate(ahd, devinfo, /*period*/0,
|
ahd_set_syncrate(ahd, devinfo, /*period*/0,
|
||||||
/*offset*/0, /*ppr_options*/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",
|
"Using asynchronous transfers\n",
|
||||||
ahd_name(ahd), devinfo->channel,
|
ahd_name(ahd), devinfo->channel,
|
||||||
devinfo->target, devinfo->lun);
|
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 tag_type;
|
||||||
int mask;
|
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. "
|
printk("(%s:%c:%d:%d): refuses tagged commands. "
|
||||||
"Performing non-tagged I/O\n", ahd_name(ahd),
|
"Performing non-tagged I/O\n", ahd_name(ahd),
|
||||||
devinfo->channel, devinfo->target, devinfo->lun);
|
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. "
|
printk("(%s:%c:%d:%d): refuses %s tagged commands. "
|
||||||
"Performing simple queue tagged I/O only\n",
|
"Performing simple queue tagged I/O only\n",
|
||||||
ahd_name(ahd), devinfo->channel, devinfo->target,
|
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");
|
? "ordered" : "head of queue");
|
||||||
ahd_set_tags(ahd, scb->io_ctx, devinfo, AHD_QUEUE_BASIC);
|
ahd_set_tags(ahd, scb->io_ctx, devinfo, AHD_QUEUE_BASIC);
|
||||||
mask = ~0x03;
|
mask = ~0x03;
|
||||||
@@ -5609,7 +5607,7 @@ ahd_handle_msg_reject(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
|
|||||||
ahd_inb_scbram(ahd, SCB_CONTROL) & mask);
|
ahd_inb_scbram(ahd, SCB_CONTROL) & mask);
|
||||||
scb->hscb->control &= mask;
|
scb->hscb->control &= mask;
|
||||||
ahd_set_transaction_tag(scb, /*enabled*/FALSE,
|
ahd_set_transaction_tag(scb, /*enabled*/FALSE,
|
||||||
/*type*/MSG_SIMPLE_TASK);
|
/*type*/SIMPLE_QUEUE_TAG);
|
||||||
ahd_outb(ahd, MSG_OUT, MSG_IDENTIFYFLAG);
|
ahd_outb(ahd, MSG_OUT, MSG_IDENTIFYFLAG);
|
||||||
ahd_assert_atn(ahd);
|
ahd_assert_atn(ahd);
|
||||||
ahd_busy_tcl(ahd, BUILD_TCL(scb->hscb->scsiid, devinfo->lun),
|
ahd_busy_tcl(ahd, BUILD_TCL(scb->hscb->scsiid, devinfo->lun),
|
||||||
@@ -5924,7 +5922,7 @@ ahd_handle_devreset(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
ahd_queue_lstate_event(ahd, lstate, devinfo->our_scsiid,
|
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);
|
ahd_send_lstate_events(ahd, lstate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -8913,7 +8911,7 @@ ahd_handle_scsi_status(struct ahd_softc *ahd, struct scb *scb)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (siu->status == SCSI_STATUS_OK)
|
if (siu->status == SAM_STAT_GOOD)
|
||||||
ahd_set_transaction_status(scb,
|
ahd_set_transaction_status(scb,
|
||||||
CAM_REQ_CMP_ERR);
|
CAM_REQ_CMP_ERR);
|
||||||
}
|
}
|
||||||
@@ -8927,8 +8925,8 @@ ahd_handle_scsi_status(struct ahd_softc *ahd, struct scb *scb)
|
|||||||
ahd_done(ahd, scb);
|
ahd_done(ahd, scb);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SCSI_STATUS_CMD_TERMINATED:
|
case SAM_STAT_COMMAND_TERMINATED:
|
||||||
case SCSI_STATUS_CHECK_COND:
|
case SAM_STAT_CHECK_CONDITION:
|
||||||
{
|
{
|
||||||
struct ahd_devinfo devinfo;
|
struct ahd_devinfo devinfo;
|
||||||
struct ahd_dma_seg *sg;
|
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);
|
ahd_queue_scb(ahd, scb);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SCSI_STATUS_OK:
|
case SAM_STAT_GOOD:
|
||||||
printk("%s: Interrupted for status of 0???\n",
|
printk("%s: Interrupted for status of 0???\n",
|
||||||
ahd_name(ahd));
|
ahd_name(ahd));
|
||||||
fallthrough;
|
fallthrough;
|
||||||
@@ -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);
|
- (lstate->event_r_idx - lstate->event_w_idx);
|
||||||
|
|
||||||
if (event_type == EVENT_TYPE_BUS_RESET
|
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.
|
* Any earlier events are irrelevant, so reset our buffer.
|
||||||
* This has the effect of allowing us to deal with reset
|
* This has the effect of allowing us to deal with reset
|
||||||
@@ -9768,7 +9766,6 @@ ahd_dump_card_state(struct ahd_softc *ahd)
|
|||||||
}
|
}
|
||||||
printk("\n");
|
printk("\n");
|
||||||
|
|
||||||
|
|
||||||
printk("Sequencer DMA-Up and Complete list: ");
|
printk("Sequencer DMA-Up and Complete list: ");
|
||||||
scb_index = ahd_inw(ahd, COMPLETE_DMA_SCB_HEAD);
|
scb_index = ahd_inw(ahd, COMPLETE_DMA_SCB_HEAD);
|
||||||
i = 0;
|
i = 0;
|
||||||
|
|||||||
@@ -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->flags & (AHD_DEV_Q_TAGGED|AHD_DEV_Q_BASIC)) != 0) {
|
||||||
if (dev->commands_since_idle_or_otag == AHD_OTAG_THRESH
|
if (dev->commands_since_idle_or_otag == AHD_OTAG_THRESH
|
||||||
&& (dev->flags & AHD_DEV_Q_TAGGED) != 0) {
|
&& (dev->flags & AHD_DEV_Q_TAGGED) != 0) {
|
||||||
hscb->control |= MSG_ORDERED_TASK;
|
hscb->control |= ORDERED_QUEUE_TAG;
|
||||||
dev->commands_since_idle_or_otag = 0;
|
dev->commands_since_idle_or_otag = 0;
|
||||||
} else {
|
} 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
|
if (dev->openings == 1
|
||||||
&& ahd_get_transaction_status(scb) == CAM_REQ_CMP
|
&& 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++;
|
dev->tag_success_count++;
|
||||||
/*
|
/*
|
||||||
* Some devices deal with temporary internal resource
|
* 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)) {
|
switch (ahd_get_scsi_status(scb)) {
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
case SCSI_STATUS_CHECK_COND:
|
case SAM_STAT_CHECK_CONDITION:
|
||||||
case SCSI_STATUS_CMD_TERMINATED:
|
case SAM_STAT_COMMAND_TERMINATED:
|
||||||
{
|
{
|
||||||
struct scsi_cmnd *cmd;
|
struct scsi_cmnd *cmd;
|
||||||
|
|
||||||
@@ -1947,7 +1947,7 @@ ahd_linux_handle_scsi_status(struct ahd_softc *ahd,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SCSI_STATUS_QUEUE_FULL:
|
case SAM_STAT_TASK_SET_FULL:
|
||||||
/*
|
/*
|
||||||
* By the time the core driver has returned this
|
* By the time the core driver has returned this
|
||||||
* command, all other commands that were queued
|
* 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;
|
dev->last_queuefull_same_count = 0;
|
||||||
}
|
}
|
||||||
ahd_set_transaction_status(scb, CAM_REQUEUE_REQ);
|
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,
|
ahd_platform_set_tags(ahd, sdev, &devinfo,
|
||||||
(dev->flags & AHD_DEV_Q_BASIC)
|
(dev->flags & AHD_DEV_Q_BASIC)
|
||||||
? AHD_QUEUE_BASIC : AHD_QUEUE_TAGGED);
|
? 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,
|
ahd_platform_set_tags(ahd, sdev, &devinfo,
|
||||||
(dev->flags & AHD_DEV_Q_BASIC)
|
(dev->flags & AHD_DEV_Q_BASIC)
|
||||||
? AHD_QUEUE_BASIC : AHD_QUEUE_TAGGED);
|
? 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);
|
scsi_status = ahd_cmd_get_scsi_status(cmd);
|
||||||
|
|
||||||
switch(scsi_status) {
|
switch(scsi_status) {
|
||||||
case SCSI_STATUS_CMD_TERMINATED:
|
case SAM_STAT_COMMAND_TERMINATED:
|
||||||
case SCSI_STATUS_CHECK_COND:
|
case SAM_STAT_CHECK_CONDITION:
|
||||||
if ((cmd->result >> 24) != DRIVER_SENSE) {
|
if ((cmd->result >> 24) != DRIVER_SENSE) {
|
||||||
do_fallback = 1;
|
do_fallback = 1;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -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 *);
|
int ahd_linux_show_info(struct seq_file *,struct Scsi_Host *);
|
||||||
|
|
||||||
/*********************** Transaction Access Wrappers **************************/
|
/*********************** 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
|
static inline
|
||||||
void ahd_cmd_set_transaction_status(struct scsi_cmnd *cmd, uint32_t status)
|
void ahd_cmd_set_transaction_status(struct scsi_cmnd *cmd, uint32_t status)
|
||||||
|
|||||||
@@ -242,7 +242,8 @@ ahd_proc_write_seeprom(struct Scsi_Host *shost, char *buffer, int length)
|
|||||||
u_int start_addr;
|
u_int start_addr;
|
||||||
|
|
||||||
if (ahd->seep_config == NULL) {
|
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) {
|
if (ahd->seep_config == NULL) {
|
||||||
printk("aic79xx: Unable to allocate serial "
|
printk("aic79xx: Unable to allocate serial "
|
||||||
"eeprom buffer. Write failing\n");
|
"eeprom buffer. Write failing\n");
|
||||||
|
|||||||
@@ -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[] =
|
static const struct ahc_phase_table_entry ahc_phase_table[] =
|
||||||
{
|
{
|
||||||
{ P_DATAOUT, MSG_NOOP, "in Data-out phase" },
|
{ P_DATAOUT, NOP, "in Data-out phase" },
|
||||||
{ P_DATAIN, MSG_INITIATOR_DET_ERR, "in Data-in phase" },
|
{ P_DATAIN, INITIATOR_ERROR, "in Data-in phase" },
|
||||||
{ P_DATAOUT_DT, MSG_NOOP, "in DT Data-out phase" },
|
{ P_DATAOUT_DT, NOP, "in DT Data-out phase" },
|
||||||
{ P_DATAIN_DT, MSG_INITIATOR_DET_ERR, "in DT Data-in phase" },
|
{ P_DATAIN_DT, INITIATOR_ERROR, "in DT Data-in phase" },
|
||||||
{ P_COMMAND, MSG_NOOP, "in Command phase" },
|
{ P_COMMAND, NOP, "in Command phase" },
|
||||||
{ P_MESGOUT, MSG_NOOP, "in Message-out phase" },
|
{ P_MESGOUT, NOP, "in Message-out phase" },
|
||||||
{ P_STATUS, MSG_INITIATOR_DET_ERR, "in Status phase" },
|
{ P_STATUS, INITIATOR_ERROR, "in Status phase" },
|
||||||
{ P_MESGIN, MSG_PARITY_ERROR, "in Message-in phase" },
|
{ P_MESGIN, MSG_PARITY_ERROR, "in Message-in phase" },
|
||||||
{ P_BUSFREE, MSG_NOOP, "while idle" },
|
{ P_BUSFREE, NOP, "while idle" },
|
||||||
{ 0, MSG_NOOP, "in unknown phase" }
|
{ 0, NOP, "in unknown phase" }
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -815,7 +815,7 @@ ahc_restart(struct ahc_softc *ahc)
|
|||||||
ahc_clear_msg_state(ahc);
|
ahc_clear_msg_state(ahc);
|
||||||
|
|
||||||
ahc_outb(ahc, SCSISIGO, 0); /* De-assert BSY */
|
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, SXFRCTL1, ahc_inb(ahc, SXFRCTL1) & ~BITBUCKET);
|
||||||
ahc_outb(ahc, LASTPHASE, P_BUSFREE);
|
ahc_outb(ahc, LASTPHASE, P_BUSFREE);
|
||||||
ahc_outb(ahc, SAVED_SCSIID, 0xFF);
|
ahc_outb(ahc, SAVED_SCSIID, 0xFF);
|
||||||
@@ -1041,12 +1041,12 @@ ahc_handle_seqint(struct ahc_softc *ahc, u_int intstat)
|
|||||||
ahc_freeze_scb(scb);
|
ahc_freeze_scb(scb);
|
||||||
ahc_set_scsi_status(scb, hscb->shared_data.status.scsi_status);
|
ahc_set_scsi_status(scb, hscb->shared_data.status.scsi_status);
|
||||||
switch (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",
|
printk("%s: Interrupted for status of 0???\n",
|
||||||
ahc_name(ahc));
|
ahc_name(ahc));
|
||||||
break;
|
break;
|
||||||
case SCSI_STATUS_CMD_TERMINATED:
|
case SAM_STAT_COMMAND_TERMINATED:
|
||||||
case SCSI_STATUS_CHECK_COND:
|
case SAM_STAT_CHECK_CONDITION:
|
||||||
{
|
{
|
||||||
struct ahc_dma_seg *sg;
|
struct ahc_dma_seg *sg;
|
||||||
struct scsi_sense *sc;
|
struct scsi_sense *sc;
|
||||||
@@ -1179,7 +1179,7 @@ ahc_handle_seqint(struct ahc_softc *ahc, u_int intstat)
|
|||||||
printk("SXFRCTL0 == 0x%x\n", ahc_inb(ahc, SXFRCTL0));
|
printk("SXFRCTL0 == 0x%x\n", ahc_inb(ahc, SXFRCTL0));
|
||||||
printk("SEQCTL == 0x%x\n", ahc_inb(ahc, SEQCTL));
|
printk("SEQCTL == 0x%x\n", ahc_inb(ahc, SEQCTL));
|
||||||
ahc_dump_card_state(ahc);
|
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_len = 1;
|
||||||
ahc->msgout_index = 0;
|
ahc->msgout_index = 0;
|
||||||
ahc->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
|
ahc->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
|
||||||
@@ -1286,8 +1286,7 @@ ahc_handle_seqint(struct ahc_softc *ahc, u_int intstat)
|
|||||||
ahc->msg_type =
|
ahc->msg_type =
|
||||||
MSG_TYPE_TARGET_MSGOUT;
|
MSG_TYPE_TARGET_MSGOUT;
|
||||||
ahc->msgin_index = 0;
|
ahc->msgin_index = 0;
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
ahc_setup_target_msgin(ahc,
|
ahc_setup_target_msgin(ahc,
|
||||||
&devinfo,
|
&devinfo,
|
||||||
scb);
|
scb);
|
||||||
@@ -1684,7 +1683,7 @@ ahc_handle_scsiint(struct ahc_softc *ahc, u_int intstat)
|
|||||||
* data direction, so ignore the value
|
* data direction, so ignore the value
|
||||||
* in the phase table.
|
* in the phase table.
|
||||||
*/
|
*/
|
||||||
mesg_out = MSG_INITIATOR_DET_ERR;
|
mesg_out = INITIATOR_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1694,7 +1693,7 @@ ahc_handle_scsiint(struct ahc_softc *ahc, u_int intstat)
|
|||||||
* the appropriate message. "In" phases have set
|
* the appropriate message. "In" phases have set
|
||||||
* mesg_out to something other than MSG_NOP.
|
* mesg_out to something other than MSG_NOP.
|
||||||
*/
|
*/
|
||||||
if (mesg_out != MSG_NOOP) {
|
if (mesg_out != NOP) {
|
||||||
if (ahc->msg_type != MSG_TYPE_NONE)
|
if (ahc->msg_type != MSG_TYPE_NONE)
|
||||||
ahc->send_msg_perror = TRUE;
|
ahc->send_msg_perror = TRUE;
|
||||||
else
|
else
|
||||||
@@ -1818,10 +1817,10 @@ ahc_handle_scsiint(struct ahc_softc *ahc, u_int intstat)
|
|||||||
u_int tag;
|
u_int tag;
|
||||||
|
|
||||||
tag = SCB_LIST_NULL;
|
tag = SCB_LIST_NULL;
|
||||||
if (ahc_sent_msg(ahc, AHCMSG_1B, MSG_ABORT_TAG, TRUE)
|
if (ahc_sent_msg(ahc, AHCMSG_1B, ABORT_TASK, TRUE)
|
||||||
|| ahc_sent_msg(ahc, AHCMSG_1B, MSG_ABORT, TRUE)) {
|
|| ahc_sent_msg(ahc, AHCMSG_1B, ABORT_TASK_SET, TRUE)) {
|
||||||
if (ahc->msgout_buf[ahc->msgout_index - 1]
|
if (ahc->msgout_buf[ahc->msgout_index - 1]
|
||||||
== MSG_ABORT_TAG)
|
== ABORT_TASK)
|
||||||
tag = scb->hscb->tag;
|
tag = scb->hscb->tag;
|
||||||
ahc_print_path(ahc, scb);
|
ahc_print_path(ahc, scb);
|
||||||
printk("SCB %d - Abort%s Completed.\n",
|
printk("SCB %d - Abort%s Completed.\n",
|
||||||
@@ -1833,7 +1832,7 @@ ahc_handle_scsiint(struct ahc_softc *ahc, u_int intstat)
|
|||||||
CAM_REQ_ABORTED);
|
CAM_REQ_ABORTED);
|
||||||
printerror = 0;
|
printerror = 0;
|
||||||
} else if (ahc_sent_msg(ahc, AHCMSG_1B,
|
} else if (ahc_sent_msg(ahc, AHCMSG_1B,
|
||||||
MSG_BUS_DEV_RESET, TRUE)) {
|
TARGET_RESET, TRUE)) {
|
||||||
ahc_compile_devinfo(&devinfo,
|
ahc_compile_devinfo(&devinfo,
|
||||||
initiator_role_id,
|
initiator_role_id,
|
||||||
target,
|
target,
|
||||||
@@ -1846,7 +1845,7 @@ ahc_handle_scsiint(struct ahc_softc *ahc, u_int intstat)
|
|||||||
/*verbose_level*/0);
|
/*verbose_level*/0);
|
||||||
printerror = 0;
|
printerror = 0;
|
||||||
} else if (ahc_sent_msg(ahc, AHCMSG_EXT,
|
} else if (ahc_sent_msg(ahc, AHCMSG_EXT,
|
||||||
MSG_EXT_PPR, FALSE)) {
|
EXTENDED_PPR, FALSE)) {
|
||||||
struct ahc_initiator_tinfo *tinfo;
|
struct ahc_initiator_tinfo *tinfo;
|
||||||
struct ahc_tmode_tstate *tstate;
|
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);
|
ahc_qinfifo_requeue_tail(ahc, scb);
|
||||||
printerror = 0;
|
printerror = 0;
|
||||||
} else if (ahc_sent_msg(ahc, AHCMSG_EXT,
|
} else if (ahc_sent_msg(ahc, AHCMSG_EXT,
|
||||||
MSG_EXT_WDTR, FALSE)) {
|
EXTENDED_WDTR, FALSE)) {
|
||||||
/*
|
/*
|
||||||
* Negotiation Rejected. Go-narrow and
|
* Negotiation Rejected. Go-narrow and
|
||||||
* retry command.
|
* retry command.
|
||||||
@@ -1877,7 +1876,7 @@ ahc_handle_scsiint(struct ahc_softc *ahc, u_int intstat)
|
|||||||
ahc_qinfifo_requeue_tail(ahc, scb);
|
ahc_qinfifo_requeue_tail(ahc, scb);
|
||||||
printerror = 0;
|
printerror = 0;
|
||||||
} else if (ahc_sent_msg(ahc, AHCMSG_EXT,
|
} else if (ahc_sent_msg(ahc, AHCMSG_EXT,
|
||||||
MSG_EXT_SDTR, FALSE)) {
|
EXTENDED_SDTR, FALSE)) {
|
||||||
/*
|
/*
|
||||||
* Negotiation Rejected. Go-async and
|
* Negotiation Rejected. Go-async and
|
||||||
* retry command.
|
* retry command.
|
||||||
@@ -1994,7 +1993,6 @@ ahc_clear_critical_section(struct ahc_softc *ahc)
|
|||||||
seqaddr -= 1;
|
seqaddr -= 1;
|
||||||
cs = ahc->critical_sections;
|
cs = ahc->critical_sections;
|
||||||
for (i = 0; i < ahc->num_critical_sections; i++, cs++) {
|
for (i = 0; i < ahc->num_critical_sections; i++, cs++) {
|
||||||
|
|
||||||
if (cs->begin < seqaddr && cs->end >= seqaddr)
|
if (cs->begin < seqaddr && cs->end >= seqaddr)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -2880,7 +2878,7 @@ ahc_setup_initiator_msgout(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (scb->flags & SCB_DEVICE_RESET) {
|
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->msgout_len++;
|
||||||
ahc_print_path(ahc, scb);
|
ahc_print_path(ahc, scb);
|
||||||
printk("Bus Device Reset Message Sent\n");
|
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));
|
ahc_outb(ahc, SCSISEQ, (ahc_inb(ahc, SCSISEQ) & ~ENSELO));
|
||||||
} else if ((scb->flags & SCB_ABORT) != 0) {
|
} else if ((scb->flags & SCB_ABORT) != 0) {
|
||||||
if ((scb->hscb->control & TAG_ENB) != 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
|
else
|
||||||
ahc->msgout_buf[ahc->msgout_index++] = MSG_ABORT;
|
ahc->msgout_buf[ahc->msgout_index++] = ABORT_TASK_SET;
|
||||||
ahc->msgout_len++;
|
ahc->msgout_len++;
|
||||||
ahc_print_path(ahc, scb);
|
ahc_print_path(ahc, scb);
|
||||||
printk("Abort%s Message Sent\n",
|
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, CLRSINT1, CLRATNO);
|
||||||
}
|
}
|
||||||
ahc_outb(ahc, MSG_OUT, MSG_NOOP);
|
ahc_outb(ahc, MSG_OUT, NOP);
|
||||||
ahc_outb(ahc, SEQ_FLAGS2,
|
ahc_outb(ahc, SEQ_FLAGS2,
|
||||||
ahc_inb(ahc, SEQ_FLAGS2) & ~TARGET_MSG_PENDING);
|
ahc_inb(ahc, SEQ_FLAGS2) & ~TARGET_MSG_PENDING);
|
||||||
}
|
}
|
||||||
@@ -3192,7 +3190,7 @@ proto_violation_reset:
|
|||||||
ahc_outb(ahc, MSG_OUT, HOST_MSG);
|
ahc_outb(ahc, MSG_OUT, HOST_MSG);
|
||||||
if (scb == NULL) {
|
if (scb == NULL) {
|
||||||
ahc_print_devinfo(ahc, &devinfo);
|
ahc_print_devinfo(ahc, &devinfo);
|
||||||
ahc->msgout_buf[0] = MSG_ABORT_TASK;
|
ahc->msgout_buf[0] = ABORT_TASK;
|
||||||
ahc->msgout_len = 1;
|
ahc->msgout_len = 1;
|
||||||
ahc->msgout_index = 0;
|
ahc->msgout_index = 0;
|
||||||
ahc->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
|
ahc->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
|
||||||
@@ -3520,7 +3518,7 @@ ahc_sent_msg(struct ahc_softc *ahc, ahc_msgtype type, u_int msgval, int full)
|
|||||||
index = 0;
|
index = 0;
|
||||||
|
|
||||||
while (index < ahc->msgout_len) {
|
while (index < ahc->msgout_len) {
|
||||||
if (ahc->msgout_buf[index] == MSG_EXTENDED) {
|
if (ahc->msgout_buf[index] == EXTENDED_MESSAGE) {
|
||||||
u_int end_index;
|
u_int end_index;
|
||||||
|
|
||||||
end_index = index + 1 + ahc->msgout_buf[index + 1];
|
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;
|
found = TRUE;
|
||||||
}
|
}
|
||||||
index = end_index;
|
index = end_index;
|
||||||
} else if (ahc->msgout_buf[index] >= MSG_SIMPLE_TASK
|
} else if (ahc->msgout_buf[index] >= SIMPLE_QUEUE_TAG
|
||||||
&& ahc->msgout_buf[index] <= MSG_IGN_WIDE_RESIDUE) {
|
&& ahc->msgout_buf[index] <= IGNORE_WIDE_RESIDUE) {
|
||||||
|
|
||||||
/* Skip tag type and tag id or residue param*/
|
/* Skip tag type and tag id or residue param*/
|
||||||
index += 2;
|
index += 2;
|
||||||
@@ -3586,30 +3584,30 @@ ahc_parse_msg(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
|
|||||||
* extended message type.
|
* extended message type.
|
||||||
*/
|
*/
|
||||||
switch (ahc->msgin_buf[0]) {
|
switch (ahc->msgin_buf[0]) {
|
||||||
case MSG_DISCONNECT:
|
case DISCONNECT:
|
||||||
case MSG_SAVEDATAPOINTER:
|
case SAVE_POINTERS:
|
||||||
case MSG_CMDCOMPLETE:
|
case COMMAND_COMPLETE:
|
||||||
case MSG_RESTOREPOINTERS:
|
case RESTORE_POINTERS:
|
||||||
case MSG_IGN_WIDE_RESIDUE:
|
case IGNORE_WIDE_RESIDUE:
|
||||||
/*
|
/*
|
||||||
* End our message loop as these are messages
|
* End our message loop as these are messages
|
||||||
* the sequencer handles on its own.
|
* the sequencer handles on its own.
|
||||||
*/
|
*/
|
||||||
done = MSGLOOP_TERMINATED;
|
done = MSGLOOP_TERMINATED;
|
||||||
break;
|
break;
|
||||||
case MSG_MESSAGE_REJECT:
|
case MESSAGE_REJECT:
|
||||||
response = ahc_handle_msg_reject(ahc, devinfo);
|
response = ahc_handle_msg_reject(ahc, devinfo);
|
||||||
fallthrough;
|
fallthrough;
|
||||||
case MSG_NOOP:
|
case NOP:
|
||||||
done = MSGLOOP_MSGCOMPLETE;
|
done = MSGLOOP_MSGCOMPLETE;
|
||||||
break;
|
break;
|
||||||
case MSG_EXTENDED:
|
case EXTENDED_MESSAGE:
|
||||||
{
|
{
|
||||||
/* Wait for enough of the message to begin validation */
|
/* Wait for enough of the message to begin validation */
|
||||||
if (ahc->msgin_index < 2)
|
if (ahc->msgin_index < 2)
|
||||||
break;
|
break;
|
||||||
switch (ahc->msgin_buf[2]) {
|
switch (ahc->msgin_buf[2]) {
|
||||||
case MSG_EXT_SDTR:
|
case EXTENDED_SDTR:
|
||||||
{
|
{
|
||||||
const struct ahc_syncrate *syncrate;
|
const struct ahc_syncrate *syncrate;
|
||||||
u_int period;
|
u_int period;
|
||||||
@@ -3661,7 +3659,7 @@ ahc_parse_msg(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
|
|||||||
* and didn't have to fall down to async
|
* and didn't have to fall down to async
|
||||||
* transfers.
|
* 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 */
|
/* We started it */
|
||||||
if (saved_offset != offset) {
|
if (saved_offset != offset) {
|
||||||
/* Went too low - force async */
|
/* Went too low - force async */
|
||||||
@@ -3688,7 +3686,7 @@ ahc_parse_msg(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
|
|||||||
done = MSGLOOP_MSGCOMPLETE;
|
done = MSGLOOP_MSGCOMPLETE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MSG_EXT_WDTR:
|
case EXTENDED_WDTR:
|
||||||
{
|
{
|
||||||
u_int bus_width;
|
u_int bus_width;
|
||||||
u_int saved_width;
|
u_int saved_width;
|
||||||
@@ -3722,7 +3720,7 @@ ahc_parse_msg(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
|
|||||||
saved_width, bus_width);
|
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
|
* Don't send a WDTR back to the
|
||||||
* target, since we asked first.
|
* target, since we asked first.
|
||||||
@@ -3784,7 +3782,7 @@ ahc_parse_msg(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
|
|||||||
done = MSGLOOP_MSGCOMPLETE;
|
done = MSGLOOP_MSGCOMPLETE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MSG_EXT_PPR:
|
case EXTENDED_PPR:
|
||||||
{
|
{
|
||||||
const struct ahc_syncrate *syncrate;
|
const struct ahc_syncrate *syncrate;
|
||||||
u_int period;
|
u_int period;
|
||||||
@@ -3844,7 +3842,7 @@ ahc_parse_msg(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
|
|||||||
&offset, bus_width,
|
&offset, bus_width,
|
||||||
devinfo->role);
|
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
|
* If we are unable to do any of the
|
||||||
* requested options (we went too low),
|
* requested options (we went too low),
|
||||||
@@ -3908,7 +3906,7 @@ ahc_parse_msg(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#ifdef AHC_TARGET_MODE
|
#ifdef AHC_TARGET_MODE
|
||||||
case MSG_BUS_DEV_RESET:
|
case TARGET_RESET:
|
||||||
ahc_handle_devreset(ahc, devinfo,
|
ahc_handle_devreset(ahc, devinfo,
|
||||||
CAM_BDR_SENT,
|
CAM_BDR_SENT,
|
||||||
"Bus Device Reset Received",
|
"Bus Device Reset Received",
|
||||||
@@ -3916,9 +3914,9 @@ ahc_parse_msg(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
|
|||||||
ahc_restart(ahc);
|
ahc_restart(ahc);
|
||||||
done = MSGLOOP_TERMINATED;
|
done = MSGLOOP_TERMINATED;
|
||||||
break;
|
break;
|
||||||
case MSG_ABORT_TAG:
|
case ABORT_TASK:
|
||||||
case MSG_ABORT:
|
case ABORT_TASK_SET:
|
||||||
case MSG_CLEAR_QUEUE:
|
case CLEAR_QUEUE_TASK_SET:
|
||||||
{
|
{
|
||||||
int tag;
|
int tag;
|
||||||
|
|
||||||
@@ -3928,7 +3926,7 @@ ahc_parse_msg(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
tag = SCB_LIST_NULL;
|
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);
|
tag = ahc_inb(ahc, INITIATOR_TAG);
|
||||||
ahc_abort_scbs(ahc, devinfo->target, devinfo->channel,
|
ahc_abort_scbs(ahc, devinfo->target, devinfo->channel,
|
||||||
devinfo->lun, tag, ROLE_TARGET,
|
devinfo->lun, tag, ROLE_TARGET,
|
||||||
@@ -3952,7 +3950,7 @@ ahc_parse_msg(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
case MSG_TERM_IO_PROC:
|
case TERMINATE_IO_PROC:
|
||||||
default:
|
default:
|
||||||
reject = TRUE;
|
reject = TRUE;
|
||||||
break;
|
break;
|
||||||
@@ -3964,7 +3962,7 @@ ahc_parse_msg(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
|
|||||||
*/
|
*/
|
||||||
ahc->msgout_index = 0;
|
ahc->msgout_index = 0;
|
||||||
ahc->msgout_len = 1;
|
ahc->msgout_len = 1;
|
||||||
ahc->msgout_buf[0] = MSG_MESSAGE_REJECT;
|
ahc->msgout_buf[0] = MESSAGE_REJECT;
|
||||||
done = MSGLOOP_MSGCOMPLETE;
|
done = MSGLOOP_MSGCOMPLETE;
|
||||||
response = TRUE;
|
response = TRUE;
|
||||||
}
|
}
|
||||||
@@ -4003,7 +4001,7 @@ ahc_handle_msg_reject(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
|
|||||||
/* Might be necessary */
|
/* Might be necessary */
|
||||||
last_msg = ahc_inb(ahc, LAST_MSG);
|
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.
|
* Target does not support the PPR message.
|
||||||
* Attempt to negotiate SPI-2 style.
|
* 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_build_transfer_msg(ahc, devinfo);
|
||||||
ahc->msgout_index = 0;
|
ahc->msgout_index = 0;
|
||||||
response = 1;
|
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 */
|
/* note 8bit xfers */
|
||||||
printk("(%s:%c:%d:%d): refuses WIDE negotiation. Using "
|
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;
|
ahc->msgout_index = 0;
|
||||||
response = 1;
|
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 */
|
/* note asynch xfers and clear flag */
|
||||||
ahc_set_syncrate(ahc, devinfo, /*syncrate*/NULL, /*period*/0,
|
ahc_set_syncrate(ahc, devinfo, /*syncrate*/NULL, /*period*/0,
|
||||||
/*offset*/0, /*ppr_options*/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",
|
"Using asynchronous transfers\n",
|
||||||
ahc_name(ahc), devinfo->channel,
|
ahc_name(ahc), devinfo->channel,
|
||||||
devinfo->target, devinfo->lun);
|
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 tag_type;
|
||||||
int mask;
|
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. "
|
printk("(%s:%c:%d:%d): refuses tagged commands. "
|
||||||
"Performing non-tagged I/O\n", ahc_name(ahc),
|
"Performing non-tagged I/O\n", ahc_name(ahc),
|
||||||
devinfo->channel, devinfo->target, devinfo->lun);
|
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. "
|
printk("(%s:%c:%d:%d): refuses %s tagged commands. "
|
||||||
"Performing simple queue tagged I/O only\n",
|
"Performing simple queue tagged I/O only\n",
|
||||||
ahc_name(ahc), devinfo->channel, devinfo->target,
|
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");
|
? "ordered" : "head of queue");
|
||||||
ahc_set_tags(ahc, scb->io_ctx, devinfo, AHC_QUEUE_BASIC);
|
ahc_set_tags(ahc, scb->io_ctx, devinfo, AHC_QUEUE_BASIC);
|
||||||
mask = ~0x03;
|
mask = ~0x03;
|
||||||
@@ -4087,7 +4085,7 @@ ahc_handle_msg_reject(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
|
|||||||
ahc_inb(ahc, SCB_CONTROL) & mask);
|
ahc_inb(ahc, SCB_CONTROL) & mask);
|
||||||
scb->hscb->control &= mask;
|
scb->hscb->control &= mask;
|
||||||
ahc_set_transaction_tag(scb, /*enabled*/FALSE,
|
ahc_set_transaction_tag(scb, /*enabled*/FALSE,
|
||||||
/*type*/MSG_SIMPLE_TASK);
|
/*type*/SIMPLE_QUEUE_TAG);
|
||||||
ahc_outb(ahc, MSG_OUT, MSG_IDENTIFYFLAG);
|
ahc_outb(ahc, MSG_OUT, MSG_IDENTIFYFLAG);
|
||||||
ahc_assert_atn(ahc);
|
ahc_assert_atn(ahc);
|
||||||
|
|
||||||
@@ -4324,7 +4322,7 @@ ahc_handle_devreset(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
ahc_queue_lstate_event(ahc, lstate, devinfo->our_scsiid,
|
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);
|
ahc_send_lstate_events(ahc, lstate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5170,7 +5168,7 @@ ahc_chip_init(struct ahc_softc *ahc)
|
|||||||
ahc_outb(ahc, DISCONNECTED_SCBH, SCB_LIST_NULL);
|
ahc_outb(ahc, DISCONNECTED_SCBH, SCB_LIST_NULL);
|
||||||
|
|
||||||
/* Message out buffer starts empty */
|
/* 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.
|
* Setup the allowed SCSI Sequences based on operational mode.
|
||||||
@@ -5989,7 +5987,6 @@ ahc_search_qinfifo(struct ahc_softc *ahc, int target, char channel,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
prev = next;
|
prev = next;
|
||||||
next = ahc_inb(ahc, SCB_NEXT);
|
next = ahc_inb(ahc, SCB_NEXT);
|
||||||
}
|
}
|
||||||
@@ -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);
|
- (lstate->event_r_idx - lstate->event_w_idx);
|
||||||
|
|
||||||
if (event_type == EVENT_TYPE_BUS_RESET
|
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.
|
* Any earlier events are irrelevant, so reset our buffer.
|
||||||
* This has the effect of allowing us to deal with reset
|
* This has the effect of allowing us to deal with reset
|
||||||
@@ -7085,7 +7082,6 @@ ahc_print_register(const ahc_reg_parse_entry_t *table, u_int num_entries,
|
|||||||
printed_mask == 0 ? ":(" : "|",
|
printed_mask == 0 ? ":(" : "|",
|
||||||
table[entry].name);
|
table[entry].name);
|
||||||
printed_mask |= table[entry].mask;
|
printed_mask |= table[entry].mask;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (entry >= num_entries)
|
if (entry >= num_entries)
|
||||||
@@ -7527,7 +7523,6 @@ ahc_handle_en_lun(struct ahc_softc *ahc, struct cam_sim *sim, union ccb *ccb)
|
|||||||
targid_mask |= target_mask;
|
targid_mask |= target_mask;
|
||||||
ahc_outb(ahc, TARGID, targid_mask);
|
ahc_outb(ahc, TARGID, targid_mask);
|
||||||
ahc_outb(ahc, TARGID+1, (targid_mask >> 8));
|
ahc_outb(ahc, TARGID+1, (targid_mask >> 8));
|
||||||
|
|
||||||
ahc_update_scsiid(ahc, targid_mask);
|
ahc_update_scsiid(ahc, targid_mask);
|
||||||
} else {
|
} else {
|
||||||
u_int our_id;
|
u_int our_id;
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Adaptec AIC7xxx device driver for Linux.
|
* Adaptec AIC7xxx device driver for Linux.
|
||||||
*
|
*
|
||||||
@@ -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->flags & (AHC_DEV_Q_TAGGED|AHC_DEV_Q_BASIC)) != 0) {
|
||||||
if (dev->commands_since_idle_or_otag == AHC_OTAG_THRESH
|
if (dev->commands_since_idle_or_otag == AHC_OTAG_THRESH
|
||||||
&& (dev->flags & AHC_DEV_Q_TAGGED) != 0) {
|
&& (dev->flags & AHC_DEV_Q_TAGGED) != 0) {
|
||||||
hscb->control |= MSG_ORDERED_TASK;
|
hscb->control |= ORDERED_QUEUE_TAG;
|
||||||
dev->commands_since_idle_or_otag = 0;
|
dev->commands_since_idle_or_otag = 0;
|
||||||
} else {
|
} else {
|
||||||
hscb->control |= MSG_SIMPLE_TASK;
|
hscb->control |= SIMPLE_QUEUE_TAG;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1759,7 +1760,7 @@ ahc_done(struct ahc_softc *ahc, struct scb *scb)
|
|||||||
|
|
||||||
if (dev->openings == 1
|
if (dev->openings == 1
|
||||||
&& ahc_get_transaction_status(scb) == CAM_REQ_CMP
|
&& 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++;
|
dev->tag_success_count++;
|
||||||
/*
|
/*
|
||||||
* Some devices deal with temporary internal resource
|
* Some devices deal with temporary internal resource
|
||||||
@@ -1816,8 +1817,8 @@ ahc_linux_handle_scsi_status(struct ahc_softc *ahc,
|
|||||||
switch (ahc_get_scsi_status(scb)) {
|
switch (ahc_get_scsi_status(scb)) {
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
case SCSI_STATUS_CHECK_COND:
|
case SAM_STAT_CHECK_CONDITION:
|
||||||
case SCSI_STATUS_CMD_TERMINATED:
|
case SAM_STAT_COMMAND_TERMINATED:
|
||||||
{
|
{
|
||||||
struct scsi_cmnd *cmd;
|
struct scsi_cmnd *cmd;
|
||||||
|
|
||||||
@@ -1855,7 +1856,7 @@ ahc_linux_handle_scsi_status(struct ahc_softc *ahc,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SCSI_STATUS_QUEUE_FULL:
|
case SAM_STAT_TASK_SET_FULL:
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* By the time the core driver has returned this
|
* 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;
|
dev->last_queuefull_same_count = 0;
|
||||||
}
|
}
|
||||||
ahc_set_transaction_status(scb, CAM_REQUEUE_REQ);
|
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,
|
ahc_platform_set_tags(ahc, sdev, &devinfo,
|
||||||
(dev->flags & AHC_DEV_Q_BASIC)
|
(dev->flags & AHC_DEV_Q_BASIC)
|
||||||
? AHC_QUEUE_BASIC : AHC_QUEUE_TAGGED);
|
? 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.
|
* as if the target returned BUSY SCSI status.
|
||||||
*/
|
*/
|
||||||
dev->openings = 1;
|
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,
|
ahc_platform_set_tags(ahc, sdev, &devinfo,
|
||||||
(dev->flags & AHC_DEV_Q_BASIC)
|
(dev->flags & AHC_DEV_Q_BASIC)
|
||||||
? AHC_QUEUE_BASIC : AHC_QUEUE_TAGGED);
|
? AHC_QUEUE_BASIC : AHC_QUEUE_TAGGED);
|
||||||
@@ -2361,7 +2362,8 @@ static void ahc_linux_set_period(struct scsi_target *starget, int period)
|
|||||||
ppr_options &= MSG_EXT_PPR_QAS_REQ;
|
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_lock(ahc, &flags);
|
||||||
ahc_set_syncrate(ahc, &devinfo, syncrate, period, offset,
|
ahc_set_syncrate(ahc, &devinfo, syncrate, period, offset,
|
||||||
ppr_options, AHC_TRANS_GOAL, FALSE);
|
ppr_options, AHC_TRANS_GOAL, FALSE);
|
||||||
@@ -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,
|
ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
|
||||||
starget->channel + 'A', ROLE_INITIATOR);
|
starget->channel + 'A', ROLE_INITIATOR);
|
||||||
if (offset != 0) {
|
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;
|
period = tinfo->goal.period;
|
||||||
ppr_options = tinfo->goal.ppr_options;
|
ppr_options = tinfo->goal.ppr_options;
|
||||||
}
|
}
|
||||||
@@ -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,
|
ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
|
||||||
starget->channel + 'A', ROLE_INITIATOR);
|
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_lock(ahc, &flags);
|
||||||
ahc_set_syncrate(ahc, &devinfo, syncrate, period, tinfo->goal.offset,
|
ahc_set_syncrate(ahc, &devinfo, syncrate, period, tinfo->goal.offset,
|
||||||
ppr_options, AHC_TRANS_GOAL, FALSE);
|
ppr_options, AHC_TRANS_GOAL, FALSE);
|
||||||
@@ -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,
|
ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
|
||||||
starget->channel + 'A', ROLE_INITIATOR);
|
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_lock(ahc, &flags);
|
||||||
ahc_set_syncrate(ahc, &devinfo, syncrate, period, tinfo->goal.offset,
|
ahc_set_syncrate(ahc, &devinfo, syncrate, period, tinfo->goal.offset,
|
||||||
ppr_options, AHC_TRANS_GOAL, FALSE);
|
ppr_options, AHC_TRANS_GOAL, FALSE);
|
||||||
@@ -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,
|
ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
|
||||||
starget->channel + 'A', ROLE_INITIATOR);
|
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_lock(ahc, &flags);
|
||||||
ahc_set_syncrate(ahc, &devinfo, syncrate, period, tinfo->goal.offset,
|
ahc_set_syncrate(ahc, &devinfo, syncrate, period, tinfo->goal.offset,
|
||||||
ppr_options, AHC_TRANS_GOAL, FALSE);
|
ppr_options, AHC_TRANS_GOAL, FALSE);
|
||||||
|
|||||||
@@ -515,29 +515,6 @@ int ahc_linux_show_info(struct seq_file *, struct Scsi_Host *);
|
|||||||
|
|
||||||
/*************************** Domain Validation ********************************/
|
/*************************** Domain Validation ********************************/
|
||||||
/*********************** Transaction Access Wrappers *************************/
|
/*********************** 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
|
static inline
|
||||||
void ahc_cmd_set_transaction_status(struct scsi_cmnd *cmd, uint32_t status)
|
void ahc_cmd_set_transaction_status(struct scsi_cmnd *cmd, uint32_t status)
|
||||||
|
|||||||
@@ -255,7 +255,8 @@ ahc_proc_write_seeprom(struct Scsi_Host *shost, char *buffer, int length)
|
|||||||
u_int start_addr;
|
u_int start_addr;
|
||||||
|
|
||||||
if (ahc->seep_config == NULL) {
|
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) {
|
if (ahc->seep_config == NULL) {
|
||||||
printk("aic7xxx: Unable to allocate serial "
|
printk("aic7xxx: Unable to allocate serial "
|
||||||
"eeprom buffer. Write failing\n");
|
"eeprom buffer. Write failing\n");
|
||||||
|
|||||||
@@ -117,21 +117,6 @@ struct scsi_sense_data
|
|||||||
#define SSD_FULL_SIZE sizeof(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 ********************************/
|
/************************* Large Disk Handling ********************************/
|
||||||
static inline int
|
static inline int
|
||||||
aic_sector_div(sector_t capacity, int heads, int sectors)
|
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 $
|
* $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 */
|
/* Identify message */ /* M/M */
|
||||||
#define MSG_IDENTIFYFLAG 0x80
|
#define MSG_IDENTIFYFLAG 0x80
|
||||||
#define MSG_IDENTIFY_DISCFLAG 0x40
|
#define MSG_IDENTIFY_DISCFLAG 0x40
|
||||||
@@ -49,16 +11,13 @@
|
|||||||
#define MSG_IDENTIFY_LUNMASK 0x3F
|
#define MSG_IDENTIFY_LUNMASK 0x3F
|
||||||
|
|
||||||
/* Extended messages (opcode and length) */
|
/* Extended messages (opcode and length) */
|
||||||
#define MSG_EXT_SDTR 0x01
|
|
||||||
#define MSG_EXT_SDTR_LEN 0x03
|
#define MSG_EXT_SDTR_LEN 0x03
|
||||||
|
|
||||||
#define MSG_EXT_WDTR 0x03
|
|
||||||
#define MSG_EXT_WDTR_LEN 0x02
|
#define MSG_EXT_WDTR_LEN 0x02
|
||||||
#define MSG_EXT_WDTR_BUS_8_BIT 0x00
|
#define MSG_EXT_WDTR_BUS_8_BIT 0x00
|
||||||
#define MSG_EXT_WDTR_BUS_16_BIT 0x01
|
#define MSG_EXT_WDTR_BUS_16_BIT 0x01
|
||||||
#define MSG_EXT_WDTR_BUS_32_BIT 0x02 /* Deprecated in SPI3 */
|
#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_LEN 0x06
|
||||||
#define MSG_EXT_PPR_PCOMP_EN 0x80
|
#define MSG_EXT_PPR_PCOMP_EN 0x80
|
||||||
#define MSG_EXT_PPR_RTI 0x40
|
#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 done_list_struct *dl)
|
||||||
{
|
{
|
||||||
struct asd_ha_struct *asd_ha = ascb->ha;
|
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;
|
int phy_id = dl->status_block[0] & DL_PHY_MASK;
|
||||||
struct asd_phy *phy = &asd_ha->phys[phy_id];
|
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_DPRINTK("phy%d: device unplugged\n", phy_id);
|
||||||
asd_turn_led(asd_ha, phy_id, 0);
|
asd_turn_led(asd_ha, phy_id, 0);
|
||||||
sas_phy_disconnected(&phy->sas_phy);
|
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;
|
break;
|
||||||
case CURRENT_OOB_DONE:
|
case CURRENT_OOB_DONE:
|
||||||
/* hot plugged device */
|
/* hot plugged device */
|
||||||
@@ -89,12 +89,13 @@ static void asd_phy_event_tasklet(struct asd_ascb *ascb,
|
|||||||
get_lrate_mode(phy, oob_mode);
|
get_lrate_mode(phy, oob_mode);
|
||||||
ASD_DPRINTK("phy%d device plugged: lrate:0x%x, proto:0x%x\n",
|
ASD_DPRINTK("phy%d device plugged: lrate:0x%x, proto:0x%x\n",
|
||||||
phy_id, phy->sas_phy.linkrate, phy->sas_phy.iproto);
|
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;
|
break;
|
||||||
case CURRENT_SPINUP_HOLD:
|
case CURRENT_SPINUP_HOLD:
|
||||||
/* hot plug SATA, no COMWAKE sent */
|
/* hot plug SATA, no COMWAKE sent */
|
||||||
asd_turn_led(asd_ha, phy_id, 1);
|
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;
|
break;
|
||||||
case CURRENT_GTO_TIMEOUT:
|
case CURRENT_GTO_TIMEOUT:
|
||||||
case CURRENT_OOB_ERROR:
|
case CURRENT_OOB_ERROR:
|
||||||
@@ -102,7 +103,7 @@ static void asd_phy_event_tasklet(struct asd_ascb *ascb,
|
|||||||
dl->status_block[1]);
|
dl->status_block[1]);
|
||||||
asd_turn_led(asd_ha, phy_id, 0);
|
asd_turn_led(asd_ha, phy_id, 0);
|
||||||
sas_phy_disconnected(&phy->sas_phy);
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -222,7 +223,6 @@ static void asd_bytes_dmaed_tasklet(struct asd_ascb *ascb,
|
|||||||
int edb_el = edb_id + ascb->edb_index;
|
int edb_el = edb_id + ascb->edb_index;
|
||||||
struct asd_dma_tok *edb = ascb->ha->seq.edb_arr[edb_el];
|
struct asd_dma_tok *edb = ascb->ha->seq.edb_arr[edb_el];
|
||||||
struct asd_phy *phy = &ascb->ha->phys[phy_id];
|
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];
|
u16 size = ((dl->status_block[3] & 7) << 8) | dl->status_block[2];
|
||||||
|
|
||||||
size = min(size, (u16) sizeof(phy->frame_rcvd));
|
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);
|
spin_unlock_irqrestore(&phy->sas_phy.frame_rcvd_lock, flags);
|
||||||
asd_dump_frame_rcvd(phy, dl);
|
asd_dump_frame_rcvd(phy, dl);
|
||||||
asd_form_port(ascb->ha, phy);
|
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,
|
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);
|
asd_turn_led(asd_ha, phy_id, 0);
|
||||||
sas_phy_disconnected(sas_phy);
|
sas_phy_disconnected(sas_phy);
|
||||||
asd_deform_port(asd_ha, 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) {
|
if (retries_left == 0) {
|
||||||
int num = 1;
|
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);
|
spin_lock_irqsave(&sas_phy->sas_prim_lock, flags);
|
||||||
sas_phy->sas_prim = ffs(cont);
|
sas_phy->sas_prim = ffs(cont);
|
||||||
spin_unlock_irqrestore(&sas_phy->sas_prim_lock, flags);
|
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;
|
break;
|
||||||
|
|
||||||
case LmUNKNOWNP:
|
case LmUNKNOWNP:
|
||||||
@@ -336,7 +337,8 @@ static void asd_primitive_rcvd_tasklet(struct asd_ascb *ascb,
|
|||||||
/* The sequencer disables all phys on that port.
|
/* The sequencer disables all phys on that port.
|
||||||
* We have to re-enable the phys ourselves. */
|
* We have to re-enable the phys ourselves. */
|
||||||
asd_deform_port(asd_ha, phy);
|
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;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -567,7 +569,7 @@ static void escb_tasklet_complete(struct asd_ascb *ascb,
|
|||||||
/* the device is gone */
|
/* the device is gone */
|
||||||
sas_phy_disconnected(sas_phy);
|
sas_phy_disconnected(sas_phy);
|
||||||
asd_deform_port(asd_ha, 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;
|
break;
|
||||||
default:
|
default:
|
||||||
ASD_DPRINTK("%s: phy%d: unknown event:0x%x\n", __func__,
|
ASD_DPRINTK("%s: phy%d: unknown event:0x%x\n", __func__,
|
||||||
|
|||||||
@@ -144,12 +144,6 @@
|
|||||||
#define VER_MINOR 0
|
#define VER_MINOR 0
|
||||||
#define VER_PATCH 6
|
#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
|
#ifdef USE_DMAC
|
||||||
/*
|
/*
|
||||||
* DMAC setup parameters
|
* DMAC setup parameters
|
||||||
@@ -1490,8 +1484,8 @@ void acornscsi_message(AS_Host *host)
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch (message[0]) {
|
switch (message[0]) {
|
||||||
case ABORT:
|
case ABORT_TASK_SET:
|
||||||
case ABORT_TAG:
|
case ABORT_TASK:
|
||||||
case COMMAND_COMPLETE:
|
case COMMAND_COMPLETE:
|
||||||
if (host->scsi.phase != PHASE_STATUSIN) {
|
if (host->scsi.phase != PHASE_STATUSIN) {
|
||||||
printk(KERN_ERR "scsi%d.%c: command complete following non-status in phase?\n",
|
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;
|
break;
|
||||||
|
|
||||||
case QUEUE_FULL:
|
|
||||||
/* TODO: target queue is full */
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SIMPLE_QUEUE_TAG:
|
case SIMPLE_QUEUE_TAG:
|
||||||
/* tag queue reconnect... message[1] = queue tag. Print something to indicate something happened! */
|
/* tag queue reconnect... message[1] = queue tag. Print something to indicate something happened! */
|
||||||
printk("scsi%d.%c: reconnect queue tag %02X\n",
|
printk("scsi%d.%c: reconnect queue tag %02X\n",
|
||||||
|
|||||||
@@ -42,7 +42,8 @@
|
|||||||
|
|
||||||
static struct scsi_host_template atp870u_template;
|
static struct scsi_host_template atp870u_template;
|
||||||
static void send_s870(struct atp_unit *dev,unsigned char c);
|
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)
|
static inline void atp_writeb_base(struct atp_unit *atp, u8 reg, u8 val)
|
||||||
{
|
{
|
||||||
@@ -145,7 +146,8 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id)
|
|||||||
if (dev->working[c] != 0) {
|
if (dev->working[c] != 0) {
|
||||||
if (is885(dev)) {
|
if (is885(dev)) {
|
||||||
if ((atp_readb_io(dev, c, 0x16) & 0x80) == 0)
|
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)
|
if ((atp_readb_pci(dev, c, 0x00) & 0x08) != 0)
|
||||||
{
|
{
|
||||||
@@ -192,9 +194,12 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id)
|
|||||||
}
|
}
|
||||||
if (is885(dev)) {
|
if (is885(dev)) {
|
||||||
adrcnt = 0;
|
adrcnt = 0;
|
||||||
((unsigned char *) &adrcnt)[2] = atp_readb_io(dev, c, 0x12);
|
((unsigned char *) &adrcnt)[2] =
|
||||||
((unsigned char *) &adrcnt)[1] = atp_readb_io(dev, c, 0x13);
|
atp_readb_io(dev, c, 0x12);
|
||||||
((unsigned char *) &adrcnt)[0] = atp_readb_io(dev, c, 0x14);
|
((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) {
|
if (dev->id[c][target_id].last_len != adrcnt) {
|
||||||
k = dev->id[c][target_id].last_len;
|
k = dev->id[c][target_id].last_len;
|
||||||
k -= adrcnt;
|
k -= adrcnt;
|
||||||
@@ -202,7 +207,10 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id)
|
|||||||
dev->id[c][target_id].last_len = adrcnt;
|
dev->id[c][target_id].last_len = adrcnt;
|
||||||
}
|
}
|
||||||
#ifdef ED_DBGP
|
#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);
|
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
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -218,7 +226,8 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id)
|
|||||||
* Issue more commands
|
* Issue more commands
|
||||||
*/
|
*/
|
||||||
spin_lock_irqsave(dev->host->host_lock, flags);
|
spin_lock_irqsave(dev->host->host_lock, flags);
|
||||||
if (((dev->quhd[c] != dev->quend[c]) || (dev->last_cmd[c] != 0xff)) &&
|
if (((dev->quhd[c] != dev->quend[c]) ||
|
||||||
|
(dev->last_cmd[c] != 0xff)) &&
|
||||||
(dev->in_snd[c] == 0)) {
|
(dev->in_snd[c] == 0)) {
|
||||||
#ifdef ED_DBGP
|
#ifdef ED_DBGP
|
||||||
printk("Call sent_s870\n");
|
printk("Call sent_s870\n");
|
||||||
@@ -247,9 +256,12 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id)
|
|||||||
dev->last_cmd[c] = 0xff;
|
dev->last_cmd[c] = 0xff;
|
||||||
}
|
}
|
||||||
adrcnt = 0;
|
adrcnt = 0;
|
||||||
((unsigned char *) &adrcnt)[2] = atp_readb_io(dev, c, 0x12);
|
((unsigned char *) &adrcnt)[2] =
|
||||||
((unsigned char *) &adrcnt)[1] = atp_readb_io(dev, c, 0x13);
|
atp_readb_io(dev, c, 0x12);
|
||||||
((unsigned char *) &adrcnt)[0] = atp_readb_io(dev, c, 0x14);
|
((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 = dev->id[c][target_id].last_len;
|
||||||
k -= adrcnt;
|
k -= adrcnt;
|
||||||
dev->id[c][target_id].tran_len = k;
|
dev->id[c][target_id].tran_len = k;
|
||||||
@@ -267,7 +279,6 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id)
|
|||||||
else
|
else
|
||||||
i=0x49;
|
i=0x49;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
if ((i == 0x80) || (i == 0x8f)) {
|
if ((i == 0x80) || (i == 0x8f)) {
|
||||||
#ifdef ED_DBGP
|
#ifdef ED_DBGP
|
||||||
@@ -285,9 +296,12 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id)
|
|||||||
printk("cmdp = 0x41\n");
|
printk("cmdp = 0x41\n");
|
||||||
#endif
|
#endif
|
||||||
adrcnt = 0;
|
adrcnt = 0;
|
||||||
((unsigned char *) &adrcnt)[2] = atp_readb_io(dev, c, 0x12);
|
((unsigned char *) &adrcnt)[2] =
|
||||||
((unsigned char *) &adrcnt)[1] = atp_readb_io(dev, c, 0x13);
|
atp_readb_io(dev, c, 0x12);
|
||||||
((unsigned char *) &adrcnt)[0] = atp_readb_io(dev, c, 0x14);
|
((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 = dev->id[c][target_id].last_len;
|
||||||
k -= adrcnt;
|
k -= adrcnt;
|
||||||
dev->id[c][target_id].tran_len = k;
|
dev->id[c][target_id].tran_len = k;
|
||||||
@@ -346,7 +360,10 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id)
|
|||||||
atp_writeb_io(dev, c, 0x13, ((unsigned char *) &k)[1]);
|
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, 0x14, ((unsigned char *) &k)[0]);
|
||||||
#ifdef ED_DBGP
|
#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));
|
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
|
#endif
|
||||||
/* Remap wide */
|
/* Remap wide */
|
||||||
j = target_id;
|
j = target_id;
|
||||||
@@ -362,20 +379,33 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id)
|
|||||||
if (is885(dev)) {
|
if (is885(dev)) {
|
||||||
i = atp_readb_pci(dev, c, 1) & 0xf3;
|
i = atp_readb_pci(dev, c, 1) & 0xf3;
|
||||||
//j=workreq->cmnd[0];
|
//j=workreq->cmnd[0];
|
||||||
if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) {
|
if ((workreq->cmnd[0] == READ_6) ||
|
||||||
|
(workreq->cmnd[0] == READ_10) ||
|
||||||
|
(workreq->cmnd[0] == WRITE_6) ||
|
||||||
|
(workreq->cmnd[0] == WRITE_10)) {
|
||||||
i |= 0x0c;
|
i |= 0x0c;
|
||||||
}
|
}
|
||||||
atp_writeb_pci(dev, c, 1, i);
|
atp_writeb_pci(dev, c, 1, i);
|
||||||
} else if (is880(dev)) {
|
} else if (is880(dev)) {
|
||||||
if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a))
|
if ((workreq->cmnd[0] == READ_6) ||
|
||||||
atp_writeb_base(dev, 0x3b, (atp_readb_base(dev, 0x3b) & 0x3f) | 0xc0);
|
(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
|
else
|
||||||
atp_writeb_base(dev, 0x3b, atp_readb_base(dev, 0x3b) & 0x3f);
|
atp_writeb_base(dev, 0x3b,
|
||||||
|
atp_readb_base(dev, 0x3b) & 0x3f);
|
||||||
} else {
|
} else {
|
||||||
if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a))
|
if ((workreq->cmnd[0] == READ_6) ||
|
||||||
atp_writeb_base(dev, 0x3a, (atp_readb_base(dev, 0x3a) & 0xf3) | 0x08);
|
(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
|
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;
|
j = 0;
|
||||||
id = 1;
|
id = 1;
|
||||||
@@ -409,8 +439,8 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id)
|
|||||||
k = id;
|
k = id;
|
||||||
}
|
}
|
||||||
if (k > adrcnt) {
|
if (k > adrcnt) {
|
||||||
((unsigned short int *)prd)[2] = (unsigned short int)
|
((unsigned short int *)prd)[2] =
|
||||||
(k - adrcnt);
|
(unsigned short int)(k - adrcnt);
|
||||||
((unsigned long *)prd)[0] += adrcnt;
|
((unsigned long *)prd)[0] += adrcnt;
|
||||||
adrcnt = 0;
|
adrcnt = 0;
|
||||||
dev->id[c][target_id].prd_pos = prd;
|
dev->id[c][target_id].prd_pos = prd;
|
||||||
@@ -425,7 +455,8 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id)
|
|||||||
}
|
}
|
||||||
atp_writel_pci(dev, c, 0x04, dev->id[c][target_id].prdaddr);
|
atp_writel_pci(dev, c, 0x04, dev->id[c][target_id].prdaddr);
|
||||||
#ifdef ED_DBGP
|
#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
|
#endif
|
||||||
if (!is885(dev)) {
|
if (!is885(dev)) {
|
||||||
atp_writeb_pci(dev, c, 2, 0x06);
|
atp_writeb_pci(dev, c, 2, 0x06);
|
||||||
@@ -466,10 +497,10 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id)
|
|||||||
workreq->result = atp_readb_io(dev, c, 0x0f);
|
workreq->result = atp_readb_io(dev, c, 0x0f);
|
||||||
if (((dev->r1f[c][target_id] & 0x10) != 0) && is885(dev)) {
|
if (((dev->r1f[c][target_id] & 0x10) != 0) && is885(dev)) {
|
||||||
printk(KERN_WARNING "AEC67162 CRC ERROR !\n");
|
printk(KERN_WARNING "AEC67162 CRC ERROR !\n");
|
||||||
workreq->result = 0x02;
|
workreq->result = SAM_STAT_CHECK_CONDITION;
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
workreq->result = 0x02;
|
workreq->result = SAM_STAT_CHECK_CONDITION;
|
||||||
|
|
||||||
if (is885(dev)) {
|
if (is885(dev)) {
|
||||||
j = atp_readb_base(dev, 0x29) | 0x01;
|
j = atp_readb_base(dev, 0x29) | 0x01;
|
||||||
@@ -503,7 +534,8 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id)
|
|||||||
* If there is stuff to send and nothing going then send it
|
* If there is stuff to send and nothing going then send it
|
||||||
*/
|
*/
|
||||||
spin_lock_irqsave(dev->host->host_lock, flags);
|
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)) {
|
(dev->in_snd[c] == 0)) {
|
||||||
#ifdef ED_DBGP
|
#ifdef ED_DBGP
|
||||||
printk("Call sent_s870(scsi_done)\n");
|
printk("Call sent_s870(scsi_done)\n");
|
||||||
@@ -528,9 +560,12 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id)
|
|||||||
atp_writeb_io(dev, c, 0x10, 0x41);
|
atp_writeb_io(dev, c, 0x10, 0x41);
|
||||||
if (is885(dev)) {
|
if (is885(dev)) {
|
||||||
k = dev->id[c][target_id].last_len;
|
k = dev->id[c][target_id].last_len;
|
||||||
atp_writeb_io(dev, c, 0x12, ((unsigned char *) (&k))[2]);
|
atp_writeb_io(dev, c, 0x12,
|
||||||
atp_writeb_io(dev, c, 0x13, ((unsigned char *) (&k))[1]);
|
((unsigned char *) (&k))[2]);
|
||||||
atp_writeb_io(dev, c, 0x14, ((unsigned char *) (&k))[0]);
|
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;
|
dev->id[c][target_id].dirct = 0x00;
|
||||||
} else {
|
} else {
|
||||||
dev->id[c][target_id].dirct = 0x00;
|
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);
|
atp_writeb_io(dev, c, 0x10, 0x41);
|
||||||
if (is885(dev)) {
|
if (is885(dev)) {
|
||||||
k = dev->id[c][target_id].last_len;
|
k = dev->id[c][target_id].last_len;
|
||||||
atp_writeb_io(dev, c, 0x12, ((unsigned char *) (&k))[2]);
|
atp_writeb_io(dev, c, 0x12,
|
||||||
atp_writeb_io(dev, c, 0x13, ((unsigned char *) (&k))[1]);
|
((unsigned char *) (&k))[2]);
|
||||||
atp_writeb_io(dev, c, 0x14, ((unsigned char *) (&k))[0]);
|
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;
|
dev->id[c][target_id].dirct = 0x20;
|
||||||
atp_writeb_io(dev, c, 0x18, 0x08);
|
atp_writeb_io(dev, c, 0x18, 0x08);
|
||||||
atp_writeb_pci(dev, c, 0, 0x01);
|
atp_writeb_pci(dev, c, 0, 0x01);
|
||||||
@@ -591,7 +630,7 @@ static int atp870u_queuecommand_lck(struct scsi_cmnd *req_p,
|
|||||||
req_p->sense_buffer[0]=0;
|
req_p->sense_buffer[0]=0;
|
||||||
scsi_set_resid(req_p, 0);
|
scsi_set_resid(req_p, 0);
|
||||||
if (scmd_channel(req_p) > 1) {
|
if (scmd_channel(req_p) > 1) {
|
||||||
req_p->result = 0x00040000;
|
req_p->result = DID_BAD_TARGET << 16;
|
||||||
done(req_p);
|
done(req_p);
|
||||||
#ifdef ED_DBGP
|
#ifdef ED_DBGP
|
||||||
printk("atp870u_queuecommand : req_p->device->channel > 1\n");
|
printk("atp870u_queuecommand : req_p->device->channel > 1\n");
|
||||||
@@ -602,8 +641,6 @@ static int atp870u_queuecommand_lck(struct scsi_cmnd *req_p,
|
|||||||
host = req_p->device->host;
|
host = req_p->device->host;
|
||||||
dev = (struct atp_unit *)&host->hostdata;
|
dev = (struct atp_unit *)&host->hostdata;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
m = 1;
|
m = 1;
|
||||||
m = m << scmd_id(req_p);
|
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) {
|
if ((m & dev->active_id[c]) == 0) {
|
||||||
req_p->result = 0x00040000;
|
req_p->result = DID_BAD_TARGET << 16;
|
||||||
done(req_p);
|
done(req_p);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -647,15 +684,20 @@ static int atp870u_queuecommand_lck(struct scsi_cmnd *req_p,
|
|||||||
printk("atp870u_queuecommand : dev->quhd[c] == dev->quend[c]\n");
|
printk("atp870u_queuecommand : dev->quhd[c] == dev->quend[c]\n");
|
||||||
#endif
|
#endif
|
||||||
dev->quend[c]--;
|
dev->quend[c]--;
|
||||||
req_p->result = 0x00020000;
|
req_p->result = DID_BUS_BUSY << 16;
|
||||||
done(req_p);
|
done(req_p);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
dev->quereq[c][dev->quend[c]] = req_p;
|
dev->quereq[c][dev->quend[c]] = req_p;
|
||||||
#ifdef ED_DBGP
|
#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]);
|
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
|
#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
|
#ifdef ED_DBGP
|
||||||
printk("Call sent_s870(atp870u_queuecommand)\n");
|
printk("Call sent_s870(atp870u_queuecommand)\n");
|
||||||
#endif
|
#endif
|
||||||
@@ -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->id[c][scmd_id(workreq)].curr_req = workreq;
|
||||||
dev->last_cmd[c] = scmd_id(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
|
#ifdef ED_DBGP
|
||||||
printk("Abort to Send\n");
|
printk("Abort to Send\n");
|
||||||
#endif
|
#endif
|
||||||
@@ -757,7 +800,7 @@ static void send_s870(struct atp_unit *dev,unsigned char c)
|
|||||||
if (l > 8)
|
if (l > 8)
|
||||||
l = 8;
|
l = 8;
|
||||||
}
|
}
|
||||||
if (workreq->cmnd[0] == 0x00) {
|
if (workreq->cmnd[0] == TEST_UNIT_READY) {
|
||||||
l = 0;
|
l = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -797,7 +840,8 @@ static void send_s870(struct atp_unit *dev,unsigned char c)
|
|||||||
*/
|
*/
|
||||||
atp_writeb_io(dev, c, 0x11, dev->id[c][target_id].devsp);
|
atp_writeb_io(dev, c, 0x11, dev->id[c][target_id].devsp);
|
||||||
#ifdef ED_DBGP
|
#ifdef ED_DBGP
|
||||||
printk("dev->id[%d][%d].devsp = %2x\n",c,target_id,dev->id[c][target_id].devsp);
|
printk("dev->id[%d][%d].devsp = %2x\n",c,target_id,
|
||||||
|
dev->id[c][target_id].devsp);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
sg_count = scsi_dma_map(workreq);
|
sg_count = scsi_dma_map(workreq);
|
||||||
@@ -872,12 +916,17 @@ static void send_s870(struct atp_unit *dev,unsigned char c)
|
|||||||
}
|
}
|
||||||
(((u16 *) (prd))[i - 1]) = cpu_to_le16(0x8000);
|
(((u16 *) (prd))[i - 1]) = cpu_to_le16(0x8000);
|
||||||
#ifdef ED_DBGP
|
#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("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);
|
printk("2. bttl %x, l %x\n",bttl, l);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#ifdef ED_DBGP
|
#ifdef ED_DBGP
|
||||||
printk("send_s870: prdaddr_2 0x%8x target_id %d\n", dev->id[c][target_id].prdaddr,target_id);
|
printk("send_s870: prdaddr_2 0x%8x target_id %d\n",
|
||||||
|
dev->id[c][target_id].prdaddr,target_id);
|
||||||
#endif
|
#endif
|
||||||
dev->id[c][target_id].prdaddr = dev->id[c][target_id].prd_bus;
|
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_writel_pci(dev, c, 4, dev->id[c][target_id].prdaddr);
|
||||||
@@ -885,21 +934,33 @@ static void send_s870(struct atp_unit *dev,unsigned char c)
|
|||||||
atp_writeb_pci(dev, c, 2, 0x00);
|
atp_writeb_pci(dev, c, 2, 0x00);
|
||||||
if (is885(dev)) {
|
if (is885(dev)) {
|
||||||
j = atp_readb_pci(dev, c, 1) & 0xf3;
|
j = atp_readb_pci(dev, c, 1) & 0xf3;
|
||||||
if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) ||
|
if ((workreq->cmnd[0] == READ_6) ||
|
||||||
(workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) {
|
(workreq->cmnd[0] == READ_10) ||
|
||||||
|
(workreq->cmnd[0] == WRITE_6) ||
|
||||||
|
(workreq->cmnd[0] == WRITE_10)) {
|
||||||
j |= 0x0c;
|
j |= 0x0c;
|
||||||
}
|
}
|
||||||
atp_writeb_pci(dev, c, 1, j);
|
atp_writeb_pci(dev, c, 1, j);
|
||||||
} else if (is880(dev)) {
|
} else if (is880(dev)) {
|
||||||
if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a))
|
if ((workreq->cmnd[0] == READ_6) ||
|
||||||
atp_writeb_base(dev, 0x3b, (atp_readb_base(dev, 0x3b) & 0x3f) | 0xc0);
|
(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
|
else
|
||||||
atp_writeb_base(dev, 0x3b, atp_readb_base(dev, 0x3b) & 0x3f);
|
atp_writeb_base(dev, 0x3b,
|
||||||
|
atp_readb_base(dev, 0x3b) & 0x3f);
|
||||||
} else {
|
} else {
|
||||||
if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a))
|
if ((workreq->cmnd[0] == READ_6) ||
|
||||||
atp_writeb_base(dev, 0x3a, (atp_readb_base(dev, 0x3a) & 0xf3) | 0x08);
|
(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
|
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) {
|
if(workreq->sc_data_direction == DMA_TO_DEVICE) {
|
||||||
@@ -1193,7 +1254,9 @@ static void atp870u_free_tables(struct Scsi_Host *host)
|
|||||||
for (k = 0; k < 16; k++) {
|
for (k = 0; k < 16; k++) {
|
||||||
if (!atp_dev->id[j][k].prd_table)
|
if (!atp_dev->id[j][k].prd_table)
|
||||||
continue;
|
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;
|
atp_dev->id[j][k].prd_table = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1205,7 +1268,10 @@ static int atp870u_init_tables(struct Scsi_Host *host)
|
|||||||
int c,k;
|
int c,k;
|
||||||
for(c=0;c < 2;c++) {
|
for(c=0;c < 2;c++) {
|
||||||
for(k=0;k<16;k++) {
|
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);
|
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) {
|
if (!atp_dev->id[c][k].prd_table) {
|
||||||
printk("atp870u_init_tables fail\n");
|
printk("atp870u_init_tables fail\n");
|
||||||
atp870u_free_tables(host);
|
atp870u_free_tables(host);
|
||||||
@@ -1263,7 +1329,8 @@ static void atp870_init(struct Scsi_Host *shpnt)
|
|||||||
|
|
||||||
pci_read_config_byte(pdev, 0x49, &host_id);
|
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);
|
shpnt->io_port, shpnt->irq);
|
||||||
|
|
||||||
atpdev->ioport[0] = shpnt->io_port;
|
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;
|
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);
|
shpnt->io_port, shpnt->irq);
|
||||||
atpdev->host_id[0] = host_id;
|
atpdev->host_id[0] = host_id;
|
||||||
|
|
||||||
@@ -1393,7 +1461,8 @@ static void atp885_init(struct Scsi_Host *shpnt)
|
|||||||
unsigned int n;
|
unsigned int n;
|
||||||
unsigned char setupdata[2][16];
|
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);
|
shpnt->io_port, shpnt->irq);
|
||||||
|
|
||||||
atpdev->ioport[0] = shpnt->io_port + 0x80;
|
atpdev->ioport[0] = shpnt->io_port + 0x80;
|
||||||
@@ -1413,11 +1482,13 @@ static void atp885_init(struct Scsi_Host *shpnt)
|
|||||||
atpdev->global_map[m] = 0;
|
atpdev->global_map[m] = 0;
|
||||||
for (k = 0; k < 4; k++) {
|
for (k = 0; k < 4; k++) {
|
||||||
atp_writew_base(atpdev, 0x3c, n++);
|
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++) {
|
for (k = 0; k < 4; k++) {
|
||||||
atp_writew_base(atpdev, 0x3c, n++);
|
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;
|
n += 8;
|
||||||
}
|
}
|
||||||
@@ -1659,7 +1730,6 @@ static void atp870u_remove (struct pci_dev *pdev)
|
|||||||
struct atp_unit *devext = pci_get_drvdata(pdev);
|
struct atp_unit *devext = pci_get_drvdata(pdev);
|
||||||
struct Scsi_Host *pshost = devext->host;
|
struct Scsi_Host *pshost = devext->host;
|
||||||
|
|
||||||
|
|
||||||
scsi_remove_host(pshost);
|
scsi_remove_host(pshost);
|
||||||
free_irq(pshost->irq, pshost);
|
free_irq(pshost->irq, pshost);
|
||||||
pci_release_regions(pdev);
|
pci_release_regions(pdev);
|
||||||
@@ -1709,7 +1779,8 @@ static struct pci_driver atp870u_driver = {
|
|||||||
|
|
||||||
module_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 char i, j, k, rmb, n;
|
||||||
unsigned short int m;
|
unsigned short int m;
|
||||||
@@ -1983,7 +2054,8 @@ u3p_cmd:
|
|||||||
dev->wide_id[c] |= m;
|
dev->wide_id[c] |= m;
|
||||||
dev->id[c][i].devsp = 0xce;
|
dev->id[c][i].devsp = 0xce;
|
||||||
#ifdef ED_DBGP
|
#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
|
#endif
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -2005,7 +2077,8 @@ chg_wide:
|
|||||||
while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00)
|
while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00)
|
||||||
cpu_relax();
|
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;
|
continue;
|
||||||
|
|
||||||
while (atp_readb_io(dev, c, 0x17) != 0x8e)
|
while (atp_readb_io(dev, c, 0x17) != 0x8e)
|
||||||
@@ -2109,7 +2182,9 @@ widep_cmd:
|
|||||||
m = m << i;
|
m = m << i;
|
||||||
dev->wide_id[c] |= m;
|
dev->wide_id[c] |= m;
|
||||||
not_wide:
|
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 = 1;
|
||||||
m = m << i;
|
m = m << i;
|
||||||
if ((dev->async[c] & m) != 0) {
|
if ((dev->async[c] & m) != 0) {
|
||||||
@@ -2148,7 +2223,8 @@ set_sync:
|
|||||||
while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00)
|
while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00)
|
||||||
cpu_relax();
|
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;
|
continue;
|
||||||
|
|
||||||
while (atp_readb_io(dev, c, 0x17) != 0x8e)
|
while (atp_readb_io(dev, c, 0x17) != 0x8e)
|
||||||
@@ -2310,7 +2386,8 @@ tar_dcons:
|
|||||||
set_syn_ok:
|
set_syn_ok:
|
||||||
dev->id[c][i].devsp = (dev->id[c][i].devsp & 0x0f) | j;
|
dev->id[c][i].devsp = (dev->id[c][i].devsp & 0x0f) | j;
|
||||||
#ifdef ED_DBGP
|
#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
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,21 +33,6 @@ struct scsi_cdb_s {
|
|||||||
u8 scsi_cdb[SCSI_MAX_CDBLEN];
|
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 */
|
#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
|
* setup sense information, if present
|
||||||
*/
|
*/
|
||||||
if ((m->scsi_status == SCSI_STATUS_CHECK_CONDITION) &&
|
if ((m->scsi_status == SAM_STAT_CHECK_CONDITION) &&
|
||||||
m->sns_len) {
|
m->sns_len) {
|
||||||
sns_len = m->sns_len;
|
sns_len = m->sns_len;
|
||||||
snsinfo = BFA_SNSINFO_FROM_TAG(ioim->fcpim->fcp,
|
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_data_s *itnim_data;
|
||||||
struct bfad_itnim_s *itnim;
|
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 */
|
/* Unmap DMA, if host is NULL, it means a scsi passthru cmd */
|
||||||
if (cmnd->device->host != NULL)
|
if (cmnd->device->host != NULL)
|
||||||
|
|||||||
@@ -64,6 +64,7 @@
|
|||||||
#include <scsi/scsi_cmnd.h>
|
#include <scsi/scsi_cmnd.h>
|
||||||
#include <scsi/scsi_device.h>
|
#include <scsi/scsi_device.h>
|
||||||
#include <scsi/scsi_host.h>
|
#include <scsi/scsi_host.h>
|
||||||
|
#include <scsi/scsi_transport_spi.h>
|
||||||
|
|
||||||
#include "dc395x.h"
|
#include "dc395x.h"
|
||||||
|
|
||||||
@@ -1281,12 +1282,8 @@ static void build_sdtr(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb,
|
|||||||
} else if (dcb->sync_offset == 0)
|
} else if (dcb->sync_offset == 0)
|
||||||
dcb->sync_offset = SYNC_NEGO_OFFSET;
|
dcb->sync_offset = SYNC_NEGO_OFFSET;
|
||||||
|
|
||||||
*ptr++ = MSG_EXTENDED; /* (01h) */
|
srb->msg_count += spi_populate_sync_msg(ptr, dcb->min_nego_period,
|
||||||
*ptr++ = 3; /* length */
|
dcb->sync_offset);
|
||||||
*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->state |= SRB_DO_SYNC_NEGO;
|
srb->state |= SRB_DO_SYNC_NEGO;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1305,11 +1302,7 @@ static void build_wdtr(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb,
|
|||||||
srb->msgout_buf[1]);
|
srb->msgout_buf[1]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
*ptr++ = MSG_EXTENDED; /* (01h) */
|
srb->msg_count += spi_populate_width_msg(ptr, wide);
|
||||||
*ptr++ = 2; /* length */
|
|
||||||
*ptr++ = EXTENDED_WDTR; /* (03h) */
|
|
||||||
*ptr++ = wide;
|
|
||||||
srb->msg_count += 4;
|
|
||||||
srb->state |= SRB_DO_WIDE_NEGO;
|
srb->state |= SRB_DO_WIDE_NEGO;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1476,7 +1469,7 @@ static u8 start_scsi(struct AdapterCtlBlk* acb, struct DeviceCtlBlk* dcb,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/* Send Tag id */
|
/* 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);
|
DC395x_write8(acb, TRM_S1040_SCSI_FIFO, tag_number);
|
||||||
dcb->tag_mask |= tag_mask;
|
dcb->tag_mask |= tag_mask;
|
||||||
srb->tag_number = tag_number;
|
srb->tag_number = tag_number;
|
||||||
@@ -1732,8 +1725,9 @@ static void msgout_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
|
|||||||
if (!srb->msg_count) {
|
if (!srb->msg_count) {
|
||||||
dprintkdbg(DBG_0, "msgout_phase1: (0x%p) NOP msg\n",
|
dprintkdbg(DBG_0, "msgout_phase1: (0x%p) NOP msg\n",
|
||||||
srb->cmd);
|
srb->cmd);
|
||||||
DC395x_write8(acb, TRM_S1040_SCSI_FIFO, MSG_NOP);
|
DC395x_write8(acb, TRM_S1040_SCSI_FIFO, NOP);
|
||||||
DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_DATALATCH); /* it's important for atn stop */
|
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);
|
DC395x_write8(acb, TRM_S1040_SCSI_COMMAND, SCMD_FIFO_OUT);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1741,7 +1735,7 @@ static void msgout_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
|
|||||||
for (i = 0; i < srb->msg_count; i++)
|
for (i = 0; i < srb->msg_count; i++)
|
||||||
DC395x_write8(acb, TRM_S1040_SCSI_FIFO, *ptr++);
|
DC395x_write8(acb, TRM_S1040_SCSI_FIFO, *ptr++);
|
||||||
srb->msg_count = 0;
|
srb->msg_count = 0;
|
||||||
if (srb->msgout_buf[0] == MSG_ABORT)
|
if (srb->msgout_buf[0] == ABORT_TASK_SET)
|
||||||
srb->state = SRB_ABORT_SENT;
|
srb->state = SRB_ABORT_SENT;
|
||||||
|
|
||||||
DC395x_write8(acb, TRM_S1040_SCSI_COMMAND, SCMD_FIFO_OUT);
|
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 = acb->tmp_srb;
|
||||||
srb->state = SRB_UNEXPECT_RESEL;
|
srb->state = SRB_UNEXPECT_RESEL;
|
||||||
dcb->active_srb = srb;
|
dcb->active_srb = srb;
|
||||||
srb->msgout_buf[0] = MSG_ABORT_TAG;
|
srb->msgout_buf[0] = ABORT_TASK;
|
||||||
srb->msg_count = 1;
|
srb->msg_count = 1;
|
||||||
DC395x_ENABLE_MSGOUT;
|
DC395x_ENABLE_MSGOUT;
|
||||||
dprintkl(KERN_DEBUG, "msgin_qtag: Unknown tag %i - abort\n", tag);
|
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);
|
msgin_reject(acb, srb);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MSG_IGNOREWIDE:
|
case IGNORE_WIDE_RESIDUE:
|
||||||
/* Discard wide residual */
|
/* Discard wide residual */
|
||||||
dprintkdbg(DBG_0, "msgin_phase0: Ignore Wide Residual!\n");
|
dprintkdbg(DBG_0, "msgin_phase0: Ignore Wide Residual!\n");
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -156,15 +156,6 @@
|
|||||||
#define H_ABORT 0x0FF
|
#define H_ABORT 0x0FF
|
||||||
|
|
||||||
/* SCSI BUS Status byte codes */
|
/* 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_UNEXP_BUS_F 0xFD /* Unexpect Bus Free */
|
||||||
#define SCSI_STAT_BUS_RST_DETECT 0xFE /* Scsi Bus Reset detected */
|
#define SCSI_STAT_BUS_RST_DETECT 0xFE /* Scsi Bus Reset detected */
|
||||||
#define SCSI_STAT_SEL_TIMEOUT 0xFF /* Selection Time out */
|
#define SCSI_STAT_SEL_TIMEOUT 0xFF /* Selection Time out */
|
||||||
@@ -181,35 +172,6 @@
|
|||||||
|
|
||||||
#define SYNC_NEGO_OFFSET 15
|
#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 */
|
/* cmd->result */
|
||||||
#define STATUS_MASK_ 0xFF
|
#define STATUS_MASK_ 0xFF
|
||||||
#define MSG_MASK 0xFF00
|
#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:
|
default:
|
||||||
printk(KERN_WARNING"%s: scsi opcode 0x%x not supported.\n",
|
printk(KERN_WARNING"%s: scsi opcode 0x%x not supported.\n",
|
||||||
pHba->name, cmd->cmnd[0]);
|
pHba->name, cmd->cmnd[0]);
|
||||||
cmd->result = (DID_OK <<16) | (INITIATOR_ERROR << 8);
|
cmd->result = (DID_ERROR <<16);
|
||||||
cmd->scsi_done(cmd);
|
cmd->scsi_done(cmd);
|
||||||
return 0;
|
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,
|
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;
|
struct scsi_device *dev = cmd->device;
|
||||||
int tgt = dev->id;
|
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->active_cmd = NULL;
|
||||||
esp_unmap_dma(esp, cmd);
|
esp_unmap_dma(esp, cmd);
|
||||||
esp_free_lun_tag(ent, dev->hostdata);
|
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) {
|
if (ent->eh_done) {
|
||||||
complete(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) |
|
cmd->result = ((DRIVER_SENSE << 24) |
|
||||||
(DID_OK << 16) |
|
(DID_OK << 16) |
|
||||||
(COMMAND_COMPLETE << 8) |
|
|
||||||
(SAM_STAT_CHECK_CONDITION << 0));
|
(SAM_STAT_CHECK_CONDITION << 0));
|
||||||
|
|
||||||
ent->flags &= ~ESP_CMD_FLAG_AUTOSENSE;
|
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);
|
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)
|
static void esp_event_queue_full(struct esp *esp, struct esp_cmd_entry *ent)
|
||||||
{
|
{
|
||||||
struct scsi_device *dev = ent->cmd->device;
|
struct scsi_device *dev = ent->cmd->device;
|
||||||
@@ -1244,7 +1240,7 @@ static int esp_finish_select(struct esp *esp)
|
|||||||
* all bets are off.
|
* all bets are off.
|
||||||
*/
|
*/
|
||||||
esp_schedule_reset(esp);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1289,7 +1285,7 @@ static int esp_finish_select(struct esp *esp)
|
|||||||
esp->target[dev->id].flags |= ESP_TGT_CHECK_NEGO;
|
esp->target[dev->id].flags |= ESP_TGT_CHECK_NEGO;
|
||||||
|
|
||||||
scsi_esp_cmd(esp, ESP_CMD_ESEL);
|
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;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1874,10 +1870,7 @@ again:
|
|||||||
ent->flags |= ESP_CMD_FLAG_AUTOSENSE;
|
ent->flags |= ESP_CMD_FLAG_AUTOSENSE;
|
||||||
esp_autosense(esp, ent);
|
esp_autosense(esp, ent);
|
||||||
} else {
|
} else {
|
||||||
esp_cmd_is_done(esp, ent, cmd,
|
esp_cmd_is_done(esp, ent, cmd, DID_OK);
|
||||||
compose_result(ent->status,
|
|
||||||
ent->message,
|
|
||||||
DID_OK));
|
|
||||||
}
|
}
|
||||||
} else if (ent->message == DISCONNECT) {
|
} else if (ent->message == DISCONNECT) {
|
||||||
esp_log_disconnect("Disconnecting tgt[%d] tag[%x:%x]\n",
|
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
|
depends on ACPI
|
||||||
help
|
help
|
||||||
This driver supports HiSilicon's SAS HBA based on PCI device
|
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_NUM 64
|
||||||
#define HISI_SAS_IOST_ITCT_CACHE_DW_SZ 10
|
#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_STATUS_BUF_SZ (sizeof(struct hisi_sas_status_buffer))
|
||||||
#define HISI_SAS_COMMAND_TABLE_SZ (sizeof(union hisi_sas_command_table))
|
#define HISI_SAS_COMMAND_TABLE_SZ (sizeof(union hisi_sas_command_table))
|
||||||
@@ -154,6 +155,16 @@ enum hisi_sas_phy_event {
|
|||||||
HISI_PHYES_NUM,
|
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 hisi_sas_phy {
|
||||||
struct work_struct works[HISI_PHYES_NUM];
|
struct work_struct works[HISI_PHYES_NUM];
|
||||||
struct hisi_hba *hisi_hba;
|
struct hisi_hba *hisi_hba;
|
||||||
@@ -175,6 +186,9 @@ struct hisi_sas_phy {
|
|||||||
enum sas_linkrate maximum_linkrate;
|
enum sas_linkrate maximum_linkrate;
|
||||||
int enable;
|
int enable;
|
||||||
atomic_t down_cnt;
|
atomic_t down_cnt;
|
||||||
|
|
||||||
|
/* Trace FIFO */
|
||||||
|
struct hisi_sas_debugfs_fifo fifo;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct hisi_sas_port {
|
struct hisi_sas_port {
|
||||||
@@ -474,6 +488,7 @@ struct hisi_hba {
|
|||||||
struct dentry *debugfs_dir;
|
struct dentry *debugfs_dir;
|
||||||
struct dentry *debugfs_dump_dentry;
|
struct dentry *debugfs_dump_dentry;
|
||||||
struct dentry *debugfs_bist_dentry;
|
struct dentry *debugfs_bist_dentry;
|
||||||
|
struct dentry *debugfs_fifo_dentry;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Generic HW DMA host memory structures */
|
/* 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 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,
|
extern void hisi_sas_phy_enable(struct hisi_hba *hisi_hba, int phy_no,
|
||||||
int enable);
|
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,
|
extern void hisi_sas_slot_task_free(struct hisi_hba *hisi_hba,
|
||||||
struct sas_task *task,
|
struct sas_task *task,
|
||||||
struct hisi_sas_slot *slot);
|
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;
|
unsigned int dq_index;
|
||||||
u32 blk_tag;
|
u32 blk_tag;
|
||||||
|
|
||||||
blk_tag = blk_mq_unique_tag(scmd->request);
|
blk_tag = blk_mq_unique_tag(scmd->request);
|
||||||
dq_index = blk_mq_unique_tag_to_hwq(blk_tag);
|
dq_index = blk_mq_unique_tag_to_hwq(blk_tag);
|
||||||
*dq_pointer = dq = &hisi_hba->dq[dq_index];
|
*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 Scsi_Host *shost = hisi_hba->shost;
|
||||||
struct blk_mq_queue_map *qmap = &shost->tag_set.map[HCTX_TYPE_DEFAULT];
|
struct blk_mq_queue_map *qmap = &shost->tag_set.map[HCTX_TYPE_DEFAULT];
|
||||||
int queue = qmap->mq_map[raw_smp_processor_id()];
|
int queue = qmap->mq_map[raw_smp_processor_id()];
|
||||||
|
|
||||||
*dq_pointer = dq = &hisi_hba->dq[queue];
|
*dq_pointer = dq = &hisi_hba->dq[queue];
|
||||||
} else {
|
|
||||||
*dq_pointer = dq = sas_dev->dq;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
port = to_hisi_sas_port(sas_port);
|
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;
|
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 hisi_sas_phy *phy = &hisi_hba->phy[phy_no];
|
||||||
struct asd_sas_phy *sas_phy = &phy->sas_phy;
|
struct asd_sas_phy *sas_phy = &phy->sas_phy;
|
||||||
struct sas_ha_struct *sas_ha;
|
|
||||||
|
|
||||||
if (!phy->phy_attached)
|
if (!phy->phy_attached)
|
||||||
return;
|
return;
|
||||||
@@ -627,8 +625,7 @@ static void hisi_sas_bytes_dmaed(struct hisi_hba *hisi_hba, int phy_no)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sas_ha = &hisi_hba->sha;
|
sas_notify_phy_event(sas_phy, PHYE_OOB_DONE, gfp_flags);
|
||||||
sas_ha->notify_phy_event(sas_phy, PHYE_OOB_DONE);
|
|
||||||
|
|
||||||
if (sas_phy->phy) {
|
if (sas_phy->phy) {
|
||||||
struct sas_phy *sphy = 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_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)
|
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)
|
if (phy->identify.target_port_protocols == SAS_PROTOCOL_SSP)
|
||||||
hisi_hba->hw->sl_notify_ssp(hisi_hba, phy_no);
|
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)
|
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)
|
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;
|
struct asd_sas_port *_sas_port = NULL;
|
||||||
int phy_no;
|
int phy_no;
|
||||||
|
|
||||||
@@ -1432,11 +1428,12 @@ static void hisi_sas_rescan_topology(struct hisi_hba *hisi_hba, u32 state)
|
|||||||
_sas_port = sas_port;
|
_sas_port = sas_port;
|
||||||
|
|
||||||
if (dev_is_expander(dev->dev_type))
|
if (dev_is_expander(dev->dev_type))
|
||||||
sas_ha->notify_port_event(sas_phy,
|
sas_notify_port_event(sas_phy,
|
||||||
PORTE_BROADCAST_RCVD);
|
PORTE_BROADCAST_RCVD,
|
||||||
|
GFP_KERNEL);
|
||||||
}
|
}
|
||||||
} else {
|
} 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 */
|
/* report PHY down if timed out */
|
||||||
if (!ret)
|
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) {
|
} else if (sas_dev->dev_status != HISI_SAS_DEV_INIT) {
|
||||||
/*
|
/*
|
||||||
* If in init state, we rely on caller to wait for link to be
|
* 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);
|
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 hisi_sas_phy *phy = &hisi_hba->phy[phy_no];
|
||||||
struct asd_sas_phy *sas_phy = &phy->sas_phy;
|
struct asd_sas_phy *sas_phy = &phy->sas_phy;
|
||||||
struct sas_ha_struct *sas_ha = &hisi_hba->sha;
|
|
||||||
struct device *dev = hisi_hba->dev;
|
struct device *dev = hisi_hba->dev;
|
||||||
|
|
||||||
if (rdy) {
|
if (rdy) {
|
||||||
/* Phy down but ready */
|
/* 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);
|
hisi_sas_port_notify_formed(sas_phy);
|
||||||
} else {
|
} else {
|
||||||
struct hisi_sas_port *port = phy->port;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
/* Phy down and not ready */
|
/* 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);
|
sas_phy_disconnected(sas_phy);
|
||||||
|
|
||||||
if (port) {
|
if (port) {
|
||||||
@@ -2725,12 +2722,21 @@ int hisi_sas_remove(struct platform_device *pdev)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(hisi_sas_remove);
|
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;
|
bool hisi_sas_debugfs_enable;
|
||||||
|
u32 hisi_sas_debugfs_dump_count = 1;
|
||||||
|
#endif
|
||||||
|
|
||||||
EXPORT_SYMBOL_GPL(hisi_sas_debugfs_enable);
|
EXPORT_SYMBOL_GPL(hisi_sas_debugfs_enable);
|
||||||
module_param_named(debugfs_enable, hisi_sas_debugfs_enable, bool, 0444);
|
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);
|
EXPORT_SYMBOL_GPL(hisi_sas_debugfs_dump_count);
|
||||||
module_param_named(debugfs_dump_count, hisi_sas_debugfs_dump_count, uint, 0444);
|
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");
|
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_sas_phy *phy = p;
|
||||||
struct hisi_hba *hisi_hba = phy->hisi_hba;
|
struct hisi_hba *hisi_hba = phy->hisi_hba;
|
||||||
struct asd_sas_phy *sas_phy = &phy->sas_phy;
|
struct asd_sas_phy *sas_phy = &phy->sas_phy;
|
||||||
struct sas_ha_struct *sha = &hisi_hba->sha;
|
|
||||||
struct device *dev = hisi_hba->dev;
|
struct device *dev = hisi_hba->dev;
|
||||||
int phy_no = sas_phy->id;
|
int phy_no = sas_phy->id;
|
||||||
u32 irq_value;
|
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))
|
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:
|
end:
|
||||||
hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT2,
|
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);
|
u32 phy_state = hisi_sas_read32(hisi_hba, PHY_STATE);
|
||||||
|
|
||||||
hisi_sas_phy_down(hisi_hba, phy_no,
|
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)
|
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);
|
phy_state = hisi_sas_read32(hisi_hba, PHY_STATE);
|
||||||
dev_info(dev, "phydown: phy%d phy_state=0x%x\n", phy_no, 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);
|
sl_ctrl = hisi_sas_phy_read32(hisi_hba, phy_no, SL_CONTROL);
|
||||||
hisi_sas_phy_write32(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 hisi_sas_phy *phy = &hisi_hba->phy[phy_no];
|
||||||
struct asd_sas_phy *sas_phy = &phy->sas_phy;
|
struct asd_sas_phy *sas_phy = &phy->sas_phy;
|
||||||
struct sas_ha_struct *sas_ha = &hisi_hba->sha;
|
|
||||||
u32 bcast_status;
|
u32 bcast_status;
|
||||||
|
|
||||||
hisi_sas_phy_write32(hisi_hba, phy_no, SL_RX_BCAST_CHK_MSK, 1);
|
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);
|
bcast_status = hisi_sas_phy_read32(hisi_hba, phy_no, RX_PRIMS_STATUS);
|
||||||
if ((bcast_status & RX_BCAST_CHG_MSK) &&
|
if ((bcast_status & RX_BCAST_CHG_MSK) &&
|
||||||
!test_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags))
|
!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,
|
hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT0,
|
||||||
CHL_INT0_SL_RX_BCST_ACK_MSK);
|
CHL_INT0_SL_RX_BCST_ACK_MSK);
|
||||||
hisi_sas_phy_write32(hisi_hba, phy_no, SL_RX_BCAST_CHK_MSK, 0);
|
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)
|
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);
|
return hisi_sas_probe(pdev, &hisi_sas_v2_hw);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -303,6 +303,19 @@
|
|||||||
#define ERR_CNT_INVLD_DW (PORT_BASE + 0x390)
|
#define ERR_CNT_INVLD_DW (PORT_BASE + 0x390)
|
||||||
#define ERR_CNT_CODE_ERR (PORT_BASE + 0x394)
|
#define ERR_CNT_CODE_ERR (PORT_BASE + 0x394)
|
||||||
#define ERR_CNT_DISP_ERR (PORT_BASE + 0x398)
|
#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 */
|
#define DEFAULT_ITCT_HW 2048 /* reset value, not reprogrammed */
|
||||||
#if (HISI_SAS_MAX_DEVICES > DEFAULT_ITCT_HW)
|
#if (HISI_SAS_MAX_DEVICES > DEFAULT_ITCT_HW)
|
||||||
@@ -517,11 +530,6 @@ static int prot_mask;
|
|||||||
module_param(prot_mask, int, 0);
|
module_param(prot_mask, int, 0);
|
||||||
MODULE_PARM_DESC(prot_mask, " host protection capabilities mask, def=0x0 ");
|
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 void debugfs_work_handler_v3_hw(struct work_struct *work);
|
||||||
|
|
||||||
static u32 hisi_sas_read32(struct hisi_hba *hisi_hba, u32 off)
|
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);
|
phy_state = hisi_sas_read32(hisi_hba, PHY_STATE);
|
||||||
dev_info(dev, "phydown: phy%d phy_state=0x%x\n", phy_no, 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);
|
sl_ctrl = hisi_sas_phy_read32(hisi_hba, phy_no, SL_CONTROL);
|
||||||
hisi_sas_phy_write32(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 hisi_sas_phy *phy = &hisi_hba->phy[phy_no];
|
||||||
struct asd_sas_phy *sas_phy = &phy->sas_phy;
|
struct asd_sas_phy *sas_phy = &phy->sas_phy;
|
||||||
struct sas_ha_struct *sas_ha = &hisi_hba->sha;
|
|
||||||
u32 bcast_status;
|
u32 bcast_status;
|
||||||
|
|
||||||
hisi_sas_phy_write32(hisi_hba, phy_no, SL_RX_BCAST_CHK_MSK, 1);
|
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);
|
bcast_status = hisi_sas_phy_read32(hisi_hba, phy_no, RX_PRIMS_STATUS);
|
||||||
if ((bcast_status & RX_BCAST_CHG_MSK) &&
|
if ((bcast_status & RX_BCAST_CHG_MSK) &&
|
||||||
!test_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags))
|
!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,
|
hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT0,
|
||||||
CHL_INT0_SL_RX_BCST_ACK_MSK);
|
CHL_INT0_SL_RX_BCST_ACK_MSK);
|
||||||
hisi_sas_phy_write32(hisi_hba, phy_no, SL_RX_BCAST_CHK_MSK, 0);
|
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,
|
.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)
|
static void debugfs_work_handler_v3_hw(struct work_struct *work)
|
||||||
{
|
{
|
||||||
struct hisi_hba *hisi_hba =
|
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_create_dir("dump", hisi_hba->debugfs_dir);
|
||||||
|
|
||||||
debugfs_phy_down_cnt_init_v3_hw(hisi_hba);
|
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++) {
|
for (i = 0; i < hisi_sas_debugfs_dump_count; i++) {
|
||||||
if (debugfs_alloc_v3_hw(hisi_hba, 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);
|
del_timer(&hisi_hba->timer);
|
||||||
|
|
||||||
sas_unregister_ha(sha);
|
sas_unregister_ha(sha);
|
||||||
|
flush_workqueue(hisi_hba->wq);
|
||||||
sas_remove_host(sha->core.shost);
|
sas_remove_host(sha->core.shost);
|
||||||
|
|
||||||
hisi_sas_v3_destroy_irqs(pdev, hisi_hba);
|
hisi_sas_v3_destroy_irqs(pdev, hisi_hba);
|
||||||
|
|||||||
@@ -2396,7 +2396,6 @@ static int handle_ioaccel_mode2_error(struct ctlr_info *h,
|
|||||||
break;
|
break;
|
||||||
case IOACCEL2_STATUS_SR_UNDERRUN:
|
case IOACCEL2_STATUS_SR_UNDERRUN:
|
||||||
cmd->result = (DID_OK << 16); /* host byte */
|
cmd->result = (DID_OK << 16); /* host byte */
|
||||||
cmd->result |= (COMMAND_COMPLETE << 8); /* msg byte */
|
|
||||||
ioaccel2_resid = get_unaligned_le32(
|
ioaccel2_resid = get_unaligned_le32(
|
||||||
&c2->error_data.resid_cnt[0]);
|
&c2->error_data.resid_cnt[0]);
|
||||||
scsi_set_resid(cmd, ioaccel2_resid);
|
scsi_set_resid(cmd, ioaccel2_resid);
|
||||||
@@ -2598,7 +2597,6 @@ static void complete_scsi_command(struct CommandList *cp)
|
|||||||
hpsa_unmap_ioaccel2_sg_chain_block(h, c2);
|
hpsa_unmap_ioaccel2_sg_chain_block(h, c2);
|
||||||
|
|
||||||
cmd->result = (DID_OK << 16); /* host byte */
|
cmd->result = (DID_OK << 16); /* host byte */
|
||||||
cmd->result |= (COMMAND_COMPLETE << 8); /* msg byte */
|
|
||||||
|
|
||||||
/* SCSI command has already been cleaned up in SML */
|
/* SCSI command has already been cleaned up in SML */
|
||||||
if (dev->was_removed) {
|
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_DEFAULT_LOG_LEVEL 2
|
||||||
#define IBMVFC_MAX_CDB_LEN 16
|
#define IBMVFC_MAX_CDB_LEN 16
|
||||||
#define IBMVFC_CLS3_ERROR 0
|
#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:
|
* Ensure we have resources for ERP and initialization:
|
||||||
@@ -645,11 +651,10 @@ struct ibmvfc_crq {
|
|||||||
volatile __be64 ioba;
|
volatile __be64 ioba;
|
||||||
} __packed __aligned(8);
|
} __packed __aligned(8);
|
||||||
|
|
||||||
struct ibmvfc_crq_queue {
|
struct ibmvfc_sub_crq {
|
||||||
struct ibmvfc_crq *msgs;
|
struct ibmvfc_crq crq;
|
||||||
int size, cur;
|
__be64 reserved[2];
|
||||||
dma_addr_t msg_token;
|
} __packed __aligned(8);
|
||||||
};
|
|
||||||
|
|
||||||
enum ibmvfc_ae_link_state {
|
enum ibmvfc_ae_link_state {
|
||||||
IBMVFC_AE_LS_LINK_UP = 0x01,
|
IBMVFC_AE_LS_LINK_UP = 0x01,
|
||||||
@@ -678,12 +683,6 @@ struct ibmvfc_async_crq {
|
|||||||
__be64 reserved;
|
__be64 reserved;
|
||||||
} __packed __aligned(8);
|
} __packed __aligned(8);
|
||||||
|
|
||||||
struct ibmvfc_async_crq_queue {
|
|
||||||
struct ibmvfc_async_crq *msgs;
|
|
||||||
int size, cur;
|
|
||||||
dma_addr_t msg_token;
|
|
||||||
};
|
|
||||||
|
|
||||||
union ibmvfc_iu {
|
union ibmvfc_iu {
|
||||||
struct ibmvfc_mad_common mad_common;
|
struct ibmvfc_mad_common mad_common;
|
||||||
struct ibmvfc_npiv_login_mad npiv_login;
|
struct ibmvfc_npiv_login_mad npiv_login;
|
||||||
@@ -738,13 +737,16 @@ struct ibmvfc_target {
|
|||||||
|
|
||||||
/* a unit of work for the hosting partition */
|
/* a unit of work for the hosting partition */
|
||||||
struct ibmvfc_event {
|
struct ibmvfc_event {
|
||||||
struct list_head queue;
|
struct list_head queue_list;
|
||||||
|
struct list_head cancel;
|
||||||
struct ibmvfc_host *vhost;
|
struct ibmvfc_host *vhost;
|
||||||
|
struct ibmvfc_queue *queue;
|
||||||
struct ibmvfc_target *tgt;
|
struct ibmvfc_target *tgt;
|
||||||
struct scsi_cmnd *cmnd;
|
struct scsi_cmnd *cmnd;
|
||||||
atomic_t free;
|
atomic_t free;
|
||||||
union ibmvfc_iu *xfer_iu;
|
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;
|
struct ibmvfc_crq crq;
|
||||||
union ibmvfc_iu iu;
|
union ibmvfc_iu iu;
|
||||||
union ibmvfc_iu *sync_iu;
|
union ibmvfc_iu *sync_iu;
|
||||||
@@ -753,6 +755,7 @@ struct ibmvfc_event {
|
|||||||
struct completion comp;
|
struct completion comp;
|
||||||
struct completion *eh_comp;
|
struct completion *eh_comp;
|
||||||
struct timer_list timer;
|
struct timer_list timer;
|
||||||
|
u16 hwq;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* a pool of event structs for use */
|
/* a pool of event structs for use */
|
||||||
@@ -763,6 +766,49 @@ struct ibmvfc_event_pool {
|
|||||||
dma_addr_t iu_token;
|
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 {
|
enum ibmvfc_host_action {
|
||||||
IBMVFC_HOST_ACTION_NONE = 0,
|
IBMVFC_HOST_ACTION_NONE = 0,
|
||||||
IBMVFC_HOST_ACTION_RESET,
|
IBMVFC_HOST_ACTION_RESET,
|
||||||
@@ -797,26 +843,29 @@ struct ibmvfc_host {
|
|||||||
enum ibmvfc_host_action action;
|
enum ibmvfc_host_action action;
|
||||||
#define IBMVFC_NUM_TRACE_INDEX_BITS 8
|
#define IBMVFC_NUM_TRACE_INDEX_BITS 8
|
||||||
#define IBMVFC_NUM_TRACE_ENTRIES (1 << IBMVFC_NUM_TRACE_INDEX_BITS)
|
#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)
|
#define IBMVFC_TRACE_SIZE (sizeof(struct ibmvfc_trace_entry) * IBMVFC_NUM_TRACE_ENTRIES)
|
||||||
struct ibmvfc_trace_entry *trace;
|
struct ibmvfc_trace_entry *trace;
|
||||||
u32 trace_index:IBMVFC_NUM_TRACE_INDEX_BITS;
|
atomic_t trace_index;
|
||||||
int num_targets;
|
int num_targets;
|
||||||
struct list_head targets;
|
struct list_head targets;
|
||||||
struct list_head sent;
|
struct list_head purge;
|
||||||
struct list_head free;
|
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
struct ibmvfc_event_pool pool;
|
|
||||||
struct dma_pool *sg_pool;
|
struct dma_pool *sg_pool;
|
||||||
mempool_t *tgt_pool;
|
mempool_t *tgt_pool;
|
||||||
struct ibmvfc_crq_queue crq;
|
struct ibmvfc_queue crq;
|
||||||
struct ibmvfc_async_crq_queue async_crq;
|
struct ibmvfc_queue async_crq;
|
||||||
|
struct ibmvfc_scsi_channels scsi_scrqs;
|
||||||
struct ibmvfc_npiv_login login_info;
|
struct ibmvfc_npiv_login login_info;
|
||||||
union ibmvfc_npiv_login_data *login_buf;
|
union ibmvfc_npiv_login_data *login_buf;
|
||||||
dma_addr_t login_buf_dma;
|
dma_addr_t login_buf_dma;
|
||||||
|
struct ibmvfc_channel_setup *channel_setup_buf;
|
||||||
|
dma_addr_t channel_setup_dma;
|
||||||
int disc_buf_sz;
|
int disc_buf_sz;
|
||||||
int log_level;
|
int log_level;
|
||||||
struct ibmvfc_discover_targets_entry *disc_buf;
|
struct ibmvfc_discover_targets_entry *disc_buf;
|
||||||
struct mutex passthru_mutex;
|
struct mutex passthru_mutex;
|
||||||
|
int max_vios_scsi_channels;
|
||||||
int task_set;
|
int task_set;
|
||||||
int init_retries;
|
int init_retries;
|
||||||
int discovery_threads;
|
int discovery_threads;
|
||||||
@@ -826,6 +875,10 @@ struct ibmvfc_host {
|
|||||||
int delay_init;
|
int delay_init;
|
||||||
int scan_complete;
|
int scan_complete;
|
||||||
int logged_in;
|
int logged_in;
|
||||||
|
int mq_enabled;
|
||||||
|
int using_channels;
|
||||||
|
int do_enquiry;
|
||||||
|
int client_scsi_channels;
|
||||||
int aborting_passthru;
|
int aborting_passthru;
|
||||||
int events_to_log;
|
int events_to_log;
|
||||||
#define IBMVFC_AE_LINKUP 0x0001
|
#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) {
|
if ((active_tc->flags & (TCF_WDTR_DONE | TCF_NO_WDTR)) == 0) {
|
||||||
active_tc->flags |= TCF_WDTR_DONE;
|
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(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 */
|
outb(1, host->addr + TUL_SFifo); /* Start from 16 bits */
|
||||||
} else if ((active_tc->flags & (TCF_SYNC_DONE | TCF_NO_SYNC_NEGO)) == 0) {
|
} else if ((active_tc->flags & (TCF_SYNC_DONE | TCF_NO_SYNC_NEGO)) == 0) {
|
||||||
active_tc->flags |= TCF_SYNC_DONE;
|
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(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(initio_rate_tbl[active_tc->flags & TCF_SCSI_RATE], host->addr + TUL_SFifo);
|
||||||
outb(MAX_OFFSET, host->addr + TUL_SFifo); /* REQ/ACK offset */
|
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 */
|
case MSG_OUT: /* Message out phase */
|
||||||
if (active_tc->flags & (TCF_SYNC_DONE | TCF_NO_SYNC_NEGO)) {
|
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);
|
outb(TSC_XF_FIFO_OUT, host->addr + TUL_SCmd);
|
||||||
if (wait_tulip(host) == -1)
|
if (wait_tulip(host) == -1)
|
||||||
return -1;
|
return -1;
|
||||||
} else {
|
} else {
|
||||||
active_tc->flags |= TCF_SYNC_DONE;
|
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(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(initio_rate_tbl[active_tc->flags & TCF_SCSI_RATE], host->addr + TUL_SFifo);
|
||||||
outb(MAX_OFFSET, host->addr + TUL_SFifo); /* REQ/ACK offset */
|
outb(MAX_OFFSET, host->addr + TUL_SFifo); /* REQ/ACK offset */
|
||||||
outb(TSC_XF_FIFO_OUT, host->addr + TUL_SCmd);
|
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 -1;
|
||||||
return 6;
|
return 6;
|
||||||
} else {
|
} 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);
|
outb(TSC_XF_FIFO_OUT, host->addr + TUL_SCmd);
|
||||||
if (wait_tulip(host) == -1)
|
if (wait_tulip(host) == -1)
|
||||||
return -1;
|
return -1;
|
||||||
@@ -1616,7 +1616,7 @@ static int initio_state_6(struct initio_host * host)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case MSG_OUT: /* Message out phase */
|
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);
|
outb(TSC_XF_FIFO_OUT, host->addr + TUL_SCmd);
|
||||||
if (wait_tulip(host) == -1)
|
if (wait_tulip(host) == -1)
|
||||||
return -1;
|
return -1;
|
||||||
@@ -1789,9 +1789,9 @@ int initio_status_msg(struct initio_host * host)
|
|||||||
|
|
||||||
if (host->phase == MSG_OUT) {
|
if (host->phase == MSG_OUT) {
|
||||||
if (host->jsstatus0 & TSS_PAR_ERROR)
|
if (host->jsstatus0 & TSS_PAR_ERROR)
|
||||||
outb(MSG_PARITY, host->addr + TUL_SFifo);
|
outb(MSG_PARITY_ERROR, host->addr + TUL_SFifo);
|
||||||
else
|
else
|
||||||
outb(MSG_NOP, host->addr + TUL_SFifo);
|
outb(NOP, host->addr + TUL_SFifo);
|
||||||
outb(TSC_XF_FIFO_OUT, host->addr + TUL_SCmd);
|
outb(TSC_XF_FIFO_OUT, host->addr + TUL_SCmd);
|
||||||
return wait_tulip(host);
|
return wait_tulip(host);
|
||||||
}
|
}
|
||||||
@@ -1802,7 +1802,7 @@ int initio_status_msg(struct initio_host * host)
|
|||||||
return -1;
|
return -1;
|
||||||
if (host->phase != MSG_OUT)
|
if (host->phase != MSG_OUT)
|
||||||
return initio_bad_seq(host);
|
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);
|
outb(TSC_XF_FIFO_OUT, host->addr + TUL_SCmd);
|
||||||
return wait_tulip(host);
|
return wait_tulip(host);
|
||||||
}
|
}
|
||||||
@@ -1815,7 +1815,8 @@ int initio_status_msg(struct initio_host * host)
|
|||||||
return initio_wait_done_disc(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)
|
if ((scb->tastat & 0x18) == 0x10)
|
||||||
return initio_msgin_accept(host);
|
return initio_msgin_accept(host);
|
||||||
}
|
}
|
||||||
@@ -1930,7 +1931,8 @@ int int_initio_resel(struct initio_host * host)
|
|||||||
return -1;
|
return -1;
|
||||||
msg = inb(host->addr + TUL_SFifo); /* Read Tag Message */
|
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;
|
goto no_tag;
|
||||||
|
|
||||||
if (initio_msgin_accept(host) == -1)
|
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)
|
if (host->phase != MSG_OUT)
|
||||||
return initio_bad_seq(host);
|
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);
|
outb(TSC_XF_FIFO_OUT, host->addr + TUL_SCmd);
|
||||||
|
|
||||||
return initio_wait_disc(host);
|
return initio_wait_disc(host);
|
||||||
@@ -2033,7 +2035,7 @@ static int initio_msgout_abort_tag(struct initio_host * host)
|
|||||||
if (host->phase != MSG_OUT)
|
if (host->phase != MSG_OUT)
|
||||||
return initio_bad_seq(host);
|
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);
|
outb(TSC_XF_FIFO_OUT, host->addr + TUL_SCmd);
|
||||||
|
|
||||||
return initio_wait_disc(host);
|
return initio_wait_disc(host);
|
||||||
@@ -2059,15 +2061,15 @@ static int initio_msgin(struct initio_host * host)
|
|||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
switch (inb(host->addr + TUL_SFifo)) {
|
switch (inb(host->addr + TUL_SFifo)) {
|
||||||
case MSG_DISC: /* Disconnect msg */
|
case DISCONNECT: /* Disconnect msg */
|
||||||
outb(TSC_MSG_ACCEPT, host->addr + TUL_SCmd);
|
outb(TSC_MSG_ACCEPT, host->addr + TUL_SCmd);
|
||||||
return initio_wait_disc(host);
|
return initio_wait_disc(host);
|
||||||
case MSG_SDP:
|
case SAVE_POINTERS:
|
||||||
case MSG_RESTORE:
|
case RESTORE_POINTERS:
|
||||||
case MSG_NOP:
|
case NOP:
|
||||||
initio_msgin_accept(host);
|
initio_msgin_accept(host);
|
||||||
break;
|
break;
|
||||||
case MSG_REJ: /* Clear ATN first */
|
case MESSAGE_REJECT: /* Clear ATN first */
|
||||||
outb((inb(host->addr + TUL_SSignal) & (TSC_SET_ACK | 7)),
|
outb((inb(host->addr + TUL_SSignal) & (TSC_SET_ACK | 7)),
|
||||||
host->addr + TUL_SSignal);
|
host->addr + TUL_SSignal);
|
||||||
active_tc = host->active_tc;
|
active_tc = host->active_tc;
|
||||||
@@ -2076,13 +2078,13 @@ static int initio_msgin(struct initio_host * host)
|
|||||||
host->addr + TUL_SSignal);
|
host->addr + TUL_SSignal);
|
||||||
initio_msgin_accept(host);
|
initio_msgin_accept(host);
|
||||||
break;
|
break;
|
||||||
case MSG_EXTEND: /* extended msg */
|
case EXTENDED_MESSAGE: /* extended msg */
|
||||||
initio_msgin_extend(host);
|
initio_msgin_extend(host);
|
||||||
break;
|
break;
|
||||||
case MSG_IGNOREWIDE:
|
case IGNORE_WIDE_RESIDUE:
|
||||||
initio_msgin_accept(host);
|
initio_msgin_accept(host);
|
||||||
break;
|
break;
|
||||||
case MSG_COMP:
|
case COMMAND_COMPLETE:
|
||||||
outb(TSC_FLUSH_FIFO, host->addr + TUL_SCtrl0);
|
outb(TSC_FLUSH_FIFO, host->addr + TUL_SCtrl0);
|
||||||
outb(TSC_MSG_ACCEPT, host->addr + TUL_SCmd);
|
outb(TSC_MSG_ACCEPT, host->addr + TUL_SCmd);
|
||||||
return initio_wait_done_disc(host);
|
return initio_wait_done_disc(host);
|
||||||
@@ -2104,7 +2106,7 @@ static int initio_msgout_reject(struct initio_host * host)
|
|||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (host->phase == MSG_OUT) {
|
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);
|
outb(TSC_XF_FIFO_OUT, host->addr + TUL_SCmd);
|
||||||
return wait_tulip(host);
|
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)
|
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);
|
outb(TSC_XF_FIFO_OUT, host->addr + TUL_SCmd);
|
||||||
return wait_tulip(host);
|
return wait_tulip(host);
|
||||||
}
|
}
|
||||||
@@ -2167,9 +2169,9 @@ static int initio_msgin_extend(struct initio_host * host)
|
|||||||
|
|
||||||
initio_sync_done(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(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[2], host->addr + TUL_SFifo);
|
||||||
outb(host->msg[3], host->addr + TUL_SFifo);
|
outb(host->msg[3], host->addr + TUL_SFifo);
|
||||||
outb(TSC_XF_FIFO_OUT, host->addr + TUL_SCmd);
|
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)
|
if (initio_msgin_accept(host) != MSG_OUT)
|
||||||
return host->phase;
|
return host->phase;
|
||||||
/* WDTR msg out */
|
/* WDTR msg out */
|
||||||
outb(MSG_EXTEND, host->addr + TUL_SFifo);
|
outb(EXTENDED_MESSAGE, host->addr + TUL_SFifo);
|
||||||
outb(2, 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(host->msg[2], host->addr + TUL_SFifo);
|
||||||
outb(TSC_XF_FIFO_OUT, host->addr + TUL_SCmd);
|
outb(TSC_XF_FIFO_OUT, host->addr + TUL_SCmd);
|
||||||
return wait_tulip(host);
|
return wait_tulip(host);
|
||||||
@@ -2391,7 +2393,7 @@ int initio_bus_device_reset(struct initio_host * host)
|
|||||||
}
|
}
|
||||||
tmp = tmp->next;
|
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);
|
outb(TSC_XF_FIFO_OUT, host->addr + TUL_SCmd);
|
||||||
return initio_wait_disc(host);
|
return initio_wait_disc(host);
|
||||||
|
|
||||||
|
|||||||
@@ -433,31 +433,6 @@ struct scsi_ctrl_blk {
|
|||||||
#define TARGET_BUSY 0x08
|
#define TARGET_BUSY 0x08
|
||||||
#define INI_QUEUE_FULL 0x28
|
#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
|
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;
|
ha = (ips_ha_t *) SC->device->host->hostdata;
|
||||||
|
|
||||||
if (!ha)
|
if (!ha)
|
||||||
return (1);
|
goto out_error;
|
||||||
|
|
||||||
if (!ha->active)
|
if (!ha->active)
|
||||||
return (DID_ERROR);
|
goto out_error;
|
||||||
|
|
||||||
if (ips_is_passthru(SC)) {
|
if (ips_is_passthru(SC)) {
|
||||||
if (ha->copp_waitlist.count == IPS_MAX_IOCTL_QUEUE) {
|
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);
|
ips_next(ha, IPS_INTR_IORL);
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
out_error:
|
||||||
|
SC->result = DID_ERROR << 16;
|
||||||
|
done(SC);
|
||||||
|
|
||||||
return (0);
|
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",
|
"%s: isci_phy = %p, sas_phy = %p\n",
|
||||||
__func__, iphy, &iphy->sas_phy);
|
__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);
|
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
|
/* Notify libsas that we have an address frame, if indeed
|
||||||
* we've found an SSP, SMP, or STP target */
|
* we've found an SSP, SMP, or STP target */
|
||||||
if (success)
|
if (success)
|
||||||
isci_host->sas_ha.notify_port_event(&iphy->sas_phy,
|
sas_notify_port_event(&iphy->sas_phy,
|
||||||
PORTE_BYTES_DMAED);
|
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.
|
* isci_port_deformed and isci_dev_gone functions.
|
||||||
*/
|
*/
|
||||||
sas_phy_disconnected(&isci_phy->sas_phy);
|
sas_phy_disconnected(&isci_phy->sas_phy);
|
||||||
isci_host->sas_ha.notify_phy_event(&isci_phy->sas_phy,
|
sas_notify_phy_event(&isci_phy->sas_phy,
|
||||||
PHYE_LOSS_OF_SIGNAL);
|
PHYE_LOSS_OF_SIGNAL, GFP_ATOMIC);
|
||||||
|
|
||||||
dev_dbg(&isci_host->pdev->dev,
|
dev_dbg(&isci_host->pdev->dev,
|
||||||
"%s: isci_port = %p - Done\n", __func__, isci_port);
|
"%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,
|
static enum sci_status stp_request_udma_await_tc_event(struct isci_request *ireq,
|
||||||
u32 completion_code)
|
u32 completion_code)
|
||||||
{
|
{
|
||||||
enum sci_status status = SCI_SUCCESS;
|
|
||||||
|
|
||||||
switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
|
switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
|
||||||
case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
|
case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
|
||||||
ireq->scu_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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return status;
|
return SCI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum sci_status atapi_raw_completion(struct isci_request *ireq, u32 completion_code,
|
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,
|
sas_phy = container_of(port->phy_list.next, struct asd_sas_phy,
|
||||||
port_phy_el);
|
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);
|
mutex_unlock(&ha->disco_mutex);
|
||||||
}
|
}
|
||||||
@@ -131,15 +132,16 @@ static void sas_phy_event_worker(struct work_struct *work)
|
|||||||
sas_free_event(ev);
|
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 sas_ha_struct *ha = phy->ha;
|
||||||
|
struct asd_sas_event *ev;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
BUG_ON(event >= PORT_NUM_EVENTS);
|
BUG_ON(event >= PORT_NUM_EVENTS);
|
||||||
|
|
||||||
ev = sas_alloc_event(phy);
|
ev = sas_alloc_event(phy, gfp_flags);
|
||||||
if (!ev)
|
if (!ev)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
@@ -151,16 +153,18 @@ static int sas_notify_port_event(struct asd_sas_phy *phy, enum port_event event)
|
|||||||
|
|
||||||
return ret;
|
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 sas_ha_struct *ha = phy->ha;
|
||||||
|
struct asd_sas_event *ev;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
BUG_ON(event >= PHY_NUM_EVENTS);
|
BUG_ON(event >= PHY_NUM_EVENTS);
|
||||||
|
|
||||||
ev = sas_alloc_event(phy);
|
ev = sas_alloc_event(phy, gfp_flags);
|
||||||
if (!ev)
|
if (!ev)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
@@ -172,11 +176,4 @@ int sas_notify_phy_event(struct asd_sas_phy *phy, enum phy_event event)
|
|||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(sas_notify_phy_event);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -123,12 +123,6 @@ int sas_register_ha(struct sas_ha_struct *sas_ha)
|
|||||||
goto Undo_phys;
|
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;
|
error = -ENOMEM;
|
||||||
snprintf(name, sizeof(name), "%s_event_q", dev_name(sas_ha->dev));
|
snprintf(name, sizeof(name), "%s_event_q", dev_name(sas_ha->dev));
|
||||||
sas_ha->event_q = create_singlethread_workqueue(name);
|
sas_ha->event_q = create_singlethread_workqueue(name);
|
||||||
@@ -410,7 +404,8 @@ void sas_resume_ha(struct sas_ha_struct *ha)
|
|||||||
|
|
||||||
if (phy->suspended) {
|
if (phy->suspended) {
|
||||||
dev_warn(&phy->phy->dev, "resume timeout\n");
|
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);
|
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;
|
struct asd_sas_event *event;
|
||||||
gfp_t flags = in_interrupt() ? GFP_ATOMIC : GFP_KERNEL;
|
|
||||||
struct sas_ha_struct *sas_ha = phy->ha;
|
struct sas_ha_struct *sas_ha = phy->ha;
|
||||||
struct sas_internal *i =
|
struct sas_internal *i =
|
||||||
to_sas_internal(sas_ha->core.shost->transportt);
|
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)
|
if (!event)
|
||||||
return NULL;
|
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) {
|
if (cmpxchg(&phy->in_shutdown, 0, 1) == 0) {
|
||||||
pr_notice("The phy%d bursting events, shut it down.\n",
|
pr_notice("The phy%d bursting events, shut it down.\n",
|
||||||
phy->id);
|
phy->id);
|
||||||
sas_notify_phy_event(phy, PHYE_SHUTDOWN);
|
sas_notify_phy_event(phy, PHYE_SHUTDOWN,
|
||||||
|
gfp_flags);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Do not support PHY control, stop allocating events */
|
/* 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);
|
int sas_register_phys(struct sas_ha_struct *sas_ha);
|
||||||
void sas_unregister_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);
|
void sas_free_event(struct asd_sas_event *event);
|
||||||
|
|
||||||
int sas_register_ports(struct sas_ha_struct *sas_ha);
|
int sas_register_ports(struct sas_ha_struct *sas_ha);
|
||||||
void sas_unregister_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_disable_revalidation(struct sas_ha_struct *ha);
|
||||||
void sas_enable_revalidation(struct sas_ha_struct *ha);
|
void sas_enable_revalidation(struct sas_ha_struct *ha);
|
||||||
void __sas_drain_work(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 *);
|
enum phy_func phy_func, struct sas_phy_linkrates *);
|
||||||
int sas_smp_get_phy_events(struct sas_phy *phy);
|
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);
|
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_find_dev_by_rphy(struct sas_rphy *rphy);
|
||||||
struct domain_device *sas_ex_to_ata(struct domain_device *ex_dev, int phy_id);
|
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_FLOGI_ISSUED 0x100000 /* FLOGI was issued */
|
||||||
#define HBA_DEFER_FLOGI 0x800000 /* Defer FLOGI till read_sparm cmpl */
|
#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*/
|
uint32_t fcp_ring_in_use; /* When polling test if intr-hndlr active*/
|
||||||
struct lpfc_dmabuf slim2p;
|
struct lpfc_dmabuf slim2p;
|
||||||
@@ -1135,7 +1138,6 @@ struct lpfc_hba {
|
|||||||
unsigned long last_completion_time;
|
unsigned long last_completion_time;
|
||||||
unsigned long skipped_hb;
|
unsigned long skipped_hb;
|
||||||
struct timer_list hb_tmofunc;
|
struct timer_list hb_tmofunc;
|
||||||
uint8_t hb_outstanding;
|
|
||||||
struct timer_list rrq_tmr;
|
struct timer_list rrq_tmr;
|
||||||
enum hba_temp_state over_temp_state;
|
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)
|
else if (strncmp(buf, "pci_bus_reset", sizeof("pci_bus_reset") - 1)
|
||||||
== 0)
|
== 0)
|
||||||
status = lpfc_reset_pci_bus(phba);
|
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)
|
else if (strncmp(buf, "trunk", sizeof("trunk") - 1) == 0)
|
||||||
status = lpfc_set_trunking(phba, (char *)buf + sizeof("trunk"));
|
status = lpfc_set_trunking(phba, (char *)buf + sizeof("trunk"));
|
||||||
else
|
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_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");
|
MODULE_PARM_DESC(lpfc_no_hba_reset, "WWPN of HBAs that should not be reset");
|
||||||
|
|
||||||
LPFC_ATTR(sli_mode, 0, 0, 3,
|
LPFC_ATTR(sli_mode, 3, 3, 3,
|
||||||
"SLI mode selector:"
|
"SLI mode selector: 3 - select SLI-3");
|
||||||
" 0 - auto (SLI-3 if supported),"
|
|
||||||
" 2 - select SLI-2 even on SLI-3 capable HBAs,"
|
|
||||||
" 3 - select SLI-3");
|
|
||||||
|
|
||||||
LPFC_ATTR_R(enable_npiv, 1, 0, 1,
|
LPFC_ATTR_R(enable_npiv, 1, 0, 1,
|
||||||
"Enable NPIV functionality");
|
"Enable NPIV functionality");
|
||||||
|
|||||||
@@ -5376,9 +5376,9 @@ lpfc_check_fwlog_support(struct lpfc_hba *phba)
|
|||||||
|
|
||||||
ras_fwlog = &phba->ras_fwlog;
|
ras_fwlog = &phba->ras_fwlog;
|
||||||
|
|
||||||
if (ras_fwlog->ras_hwsupport == false)
|
if (!ras_fwlog->ras_hwsupport)
|
||||||
return -EACCES;
|
return -EACCES;
|
||||||
else if (ras_fwlog->ras_enabled == false)
|
else if (!ras_fwlog->ras_enabled)
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
else
|
else
|
||||||
return 0;
|
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,
|
int lpfc_nvmet_rcv_unsol_abort(struct lpfc_vport *vport,
|
||||||
struct fc_frame_header *fc_hdr);
|
struct fc_frame_header *fc_hdr);
|
||||||
void lpfc_nvmet_wqfull_process(struct lpfc_hba *phba, struct lpfc_queue *wq);
|
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_nvme_wait_for_io_drain(struct lpfc_hba *phba);
|
||||||
void lpfc_sli4_build_dflt_fcf_record(struct lpfc_hba *, struct fcf_record *,
|
void lpfc_sli4_build_dflt_fcf_record(struct lpfc_hba *, struct fcf_record *,
|
||||||
uint16_t);
|
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(struct timer_list *t);
|
||||||
void lpfc_mbox_timeout_handler(struct lpfc_hba *);
|
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_did(struct lpfc_vport *, uint32_t);
|
||||||
struct lpfc_nodelist *lpfc_findnode_wwpn(struct lpfc_vport *,
|
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_io_ktime(struct lpfc_hba *phba, struct lpfc_io_buf *ncmd);
|
||||||
void lpfc_wqe_cmd_template(void);
|
void lpfc_wqe_cmd_template(void);
|
||||||
void lpfc_nvmet_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 int lpfc_enable_nvmet_cnt;
|
||||||
extern unsigned long long lpfc_enable_nvmet[];
|
extern unsigned long long lpfc_enable_nvmet[];
|
||||||
extern int lpfc_no_hba_reset_cnt;
|
extern int lpfc_no_hba_reset_cnt;
|
||||||
|
|||||||
@@ -77,6 +77,13 @@ struct lpfc_node_rrqs {
|
|||||||
unsigned long xri_bitmap[XRI_BITMAP_ULONGS];
|
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 lpfc_nodelist {
|
||||||
struct list_head nlp_listp;
|
struct list_head nlp_listp;
|
||||||
struct lpfc_name nlp_portname;
|
struct lpfc_name nlp_portname;
|
||||||
@@ -134,15 +141,15 @@ struct lpfc_nodelist {
|
|||||||
unsigned long *active_rrqs_xri_bitmap;
|
unsigned long *active_rrqs_xri_bitmap;
|
||||||
struct lpfc_scsicmd_bkt *lat_data; /* Latency data */
|
struct lpfc_scsicmd_bkt *lat_data; /* Latency data */
|
||||||
uint32_t fc4_prli_sent;
|
uint32_t fc4_prli_sent;
|
||||||
uint32_t fc4_xpt_flags;
|
u32 upcall_flags;
|
||||||
#define NLP_WAIT_FOR_UNREG 0x1
|
#define NLP_WAIT_FOR_LOGO 0x2
|
||||||
#define SCSI_XPT_REGD 0x2
|
|
||||||
#define NVME_XPT_REGD 0x4
|
|
||||||
|
|
||||||
|
enum lpfc_fc4_xpt_flags fc4_xpt_flags;
|
||||||
|
|
||||||
uint32_t nvme_fb_size; /* NVME target's supported byte cnt */
|
uint32_t nvme_fb_size; /* NVME target's supported byte cnt */
|
||||||
#define NVME_FB_BIT_SHIFT 9 /* PRLI Rsp first burst in 512B units. */
|
#define NVME_FB_BIT_SHIFT 9 /* PRLI Rsp first burst in 512B units. */
|
||||||
uint32_t nlp_defer_did;
|
uint32_t nlp_defer_did;
|
||||||
|
wait_queue_head_t *logo_waitq;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct lpfc_node_rrq {
|
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);
|
spin_unlock_irq(&phba->hbalock);
|
||||||
} else {
|
} else {
|
||||||
/* Because we asked f/w for NPIV it still expects us
|
/* 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,
|
lpfc_printf_vlog(vport, KERN_WARNING,
|
||||||
LOG_ELS | LOG_VPORT,
|
LOG_ELS | LOG_VPORT,
|
||||||
"1817 Fabric does not support NPIV "
|
"1817 Fabric does not support NPIV "
|
||||||
@@ -1428,6 +1428,9 @@ lpfc_els_abort_flogi(struct lpfc_hba *phba)
|
|||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* Make sure HBA is alive */
|
||||||
|
lpfc_issue_hb_tmo(phba);
|
||||||
|
|
||||||
spin_unlock_irq(&phba->hbalock);
|
spin_unlock_irq(&phba->hbalock);
|
||||||
|
|
||||||
return 0;
|
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_nodelist *ndlp = (struct lpfc_nodelist *) cmdiocb->context1;
|
||||||
struct lpfc_vport *vport = ndlp->vport;
|
struct lpfc_vport *vport = ndlp->vport;
|
||||||
IOCB_t *irsp;
|
IOCB_t *irsp;
|
||||||
struct lpfcMboxq *mbox;
|
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
uint32_t skip_recovery = 0;
|
uint32_t skip_recovery = 0;
|
||||||
|
int wake_up_waiter = 0;
|
||||||
|
|
||||||
/* we pass cmdiocb to state machine which needs rspiocb as well */
|
/* we pass cmdiocb to state machine which needs rspiocb as well */
|
||||||
cmdiocb->context_un.rsp_iocb = rspiocb;
|
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);
|
irsp = &(rspiocb->iocb);
|
||||||
spin_lock_irq(&ndlp->lock);
|
spin_lock_irq(&ndlp->lock);
|
||||||
ndlp->nlp_flag &= ~NLP_LOGO_SND;
|
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);
|
spin_unlock_irq(&ndlp->lock);
|
||||||
|
|
||||||
lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
|
lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
|
||||||
@@ -2884,32 +2891,14 @@ out:
|
|||||||
lpfc_els_free_iocb(phba, cmdiocb);
|
lpfc_els_free_iocb(phba, cmdiocb);
|
||||||
lpfc_nlp_put(ndlp);
|
lpfc_nlp_put(ndlp);
|
||||||
|
|
||||||
/* If we are in pt2pt mode, we could rcv new S_ID on PLOGI */
|
/* At this point, the LOGO processing is complete. NOTE: For a
|
||||||
if ((vport->fc_flag & FC_PT2PT) &&
|
* pt2pt topology, we are assuming the NPortID will only change
|
||||||
!(vport->fc_flag & FC_PT2PT_PLOGI)) {
|
* on link up processing. For a LOGO / PLOGI initiated by the
|
||||||
phba->pport->fc_myDID = 0;
|
* Initiator, we are assuming the NPortID is not going to change.
|
||||||
|
*/
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
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.
|
* 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
|
* 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);
|
spin_unlock_irq(&phba->hbalock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Make sure HBA is alive */
|
||||||
|
lpfc_issue_hb_tmo(phba);
|
||||||
|
|
||||||
if (!list_empty(&pring->txcmplq))
|
if (!list_empty(&pring->txcmplq))
|
||||||
if (!(phba->pport->load_flag & FC_UNLOADING))
|
if (!(phba->pport->load_flag & FC_UNLOADING))
|
||||||
mod_timer(&vport->els_tmofunc,
|
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);
|
lpfc_sli_issue_abort_iotag(phba, pring, piocb, NULL);
|
||||||
spin_unlock_irqrestore(&phba->hbalock, iflags);
|
spin_unlock_irqrestore(&phba->hbalock, iflags);
|
||||||
}
|
}
|
||||||
|
/* Make sure HBA is alive */
|
||||||
|
lpfc_issue_hb_tmo(phba);
|
||||||
|
|
||||||
if (!list_empty(&abort_list))
|
if (!list_empty(&abort_list))
|
||||||
lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
|
lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
|
||||||
"3387 abort list for txq not empty\n");
|
"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 int lpfc_fcf_inuse(struct lpfc_hba *);
|
||||||
static void lpfc_mbx_cmpl_read_sparam(struct lpfc_hba *, LPFC_MBOXQ_t *);
|
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
|
/* 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
|
* event or a call to fc_remove_host. While the rport should be
|
||||||
* valid during these downcalls, the transport can call twice
|
* 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;
|
struct lpfc_vport *vport = pmb->vport;
|
||||||
LPFC_MBOXQ_t *sparam_mb;
|
LPFC_MBOXQ_t *sparam_mb;
|
||||||
struct lpfc_dmabuf *sparam_mp;
|
struct lpfc_dmabuf *sparam_mp;
|
||||||
|
u16 status = pmb->u.mb.mbxStatus;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if (pmb->u.mb.mbxStatus)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
mempool_free(pmb, phba->mbox_mem_pool);
|
mempool_free(pmb, phba->mbox_mem_pool);
|
||||||
|
|
||||||
|
if (status)
|
||||||
|
goto out;
|
||||||
|
|
||||||
/* don't perform discovery for SLI4 loopback diagnostic test */
|
/* don't perform discovery for SLI4 loopback diagnostic test */
|
||||||
if ((phba->sli_rev == LPFC_SLI_REV4) &&
|
if ((phba->sli_rev == LPFC_SLI_REV4) &&
|
||||||
!(phba->hba_flag & HBA_FCOE_MODE) &&
|
!(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:
|
out:
|
||||||
lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
|
lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
|
||||||
"0306 CONFIG_LINK mbxStatus error x%x "
|
"0306 CONFIG_LINK mbxStatus error x%x HBA state x%x\n",
|
||||||
"HBA state x%x\n",
|
status, vport->port_state);
|
||||||
pmb->u.mb.mbxStatus, vport->port_state);
|
|
||||||
sparam_out:
|
|
||||||
mempool_free(pmb, phba->mbox_mem_pool);
|
|
||||||
|
|
||||||
|
sparam_out:
|
||||||
lpfc_linkdown(phba);
|
lpfc_linkdown(phba);
|
||||||
|
|
||||||
lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
|
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 */
|
/* FCP and NVME Transport interface */
|
||||||
if ((old_state == NLP_STE_MAPPED_NODE ||
|
if ((old_state == NLP_STE_MAPPED_NODE ||
|
||||||
old_state == NLP_STE_UNMAPPED_NODE)) {
|
old_state == NLP_STE_UNMAPPED_NODE)) {
|
||||||
if (ndlp->rport) {
|
if (ndlp->rport &&
|
||||||
|
lpfc_valid_xpt_node(ndlp)) {
|
||||||
vport->phba->nport_event_cnt++;
|
vport->phba->nport_event_cnt++;
|
||||||
lpfc_unregister_remote_port(ndlp);
|
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 ||
|
if (new_state == NLP_STE_MAPPED_NODE ||
|
||||||
new_state == NLP_STE_UNMAPPED_NODE) {
|
new_state == NLP_STE_UNMAPPED_NODE) {
|
||||||
if (ndlp->nlp_fc4_type ||
|
if (lpfc_valid_xpt_node(ndlp)) {
|
||||||
ndlp->nlp_DID == Fabric_DID ||
|
|
||||||
ndlp->nlp_DID == NameServer_DID ||
|
|
||||||
ndlp->nlp_DID == FDMI_DID) {
|
|
||||||
vport->phba->nport_event_cnt++;
|
vport->phba->nport_event_cnt++;
|
||||||
/*
|
/*
|
||||||
* Tell the fc transport about the port, if we haven't
|
* 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);
|
spin_unlock_irq(&phba->hbalock);
|
||||||
|
|
||||||
|
/* Make sure HBA is alive */
|
||||||
|
lpfc_issue_hb_tmo(phba);
|
||||||
|
|
||||||
/* Cancel all the IOCBs from the completions list */
|
/* Cancel all the IOCBs from the completions list */
|
||||||
lpfc_sli_cancel_iocbs(phba, &completions, IOSTAT_LOCAL_REJECT,
|
lpfc_sli_cancel_iocbs(phba, &completions, IOSTAT_LOCAL_REJECT,
|
||||||
IOERR_SLI_ABORTED);
|
IOERR_SLI_ABORTED);
|
||||||
|
|||||||
@@ -591,7 +591,7 @@ lpfc_config_port_post(struct lpfc_hba *phba)
|
|||||||
/* Set up heart beat (HB) timer */
|
/* Set up heart beat (HB) timer */
|
||||||
mod_timer(&phba->hb_tmofunc,
|
mod_timer(&phba->hb_tmofunc,
|
||||||
jiffies + msecs_to_jiffies(1000 * LPFC_HB_MBOX_INTERVAL));
|
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;
|
phba->last_completion_time = jiffies;
|
||||||
/* Set up error attention (ERATT) polling timer */
|
/* Set up error attention (ERATT) polling timer */
|
||||||
mod_timer(&phba->eratt_poll,
|
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;
|
unsigned long drvr_flag;
|
||||||
|
|
||||||
spin_lock_irqsave(&phba->hbalock, 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);
|
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);
|
mempool_free(pmboxq, phba->mbox_mem_pool);
|
||||||
if (!(phba->pport->fc_flag & FC_OFFLINE_MODE) &&
|
if (!(phba->pport->fc_flag & FC_OFFLINE_MODE) &&
|
||||||
!(phba->link_state == LPFC_HBA_ERROR) &&
|
!(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
|
* lpfc_hb_timeout_handler - The HBA-timer timeout handler
|
||||||
* @phba: pointer to lpfc hba data structure.
|
* @phba: pointer to lpfc hba data structure.
|
||||||
@@ -1400,9 +1454,9 @@ void
|
|||||||
lpfc_hb_timeout_handler(struct lpfc_hba *phba)
|
lpfc_hb_timeout_handler(struct lpfc_hba *phba)
|
||||||
{
|
{
|
||||||
struct lpfc_vport **vports;
|
struct lpfc_vport **vports;
|
||||||
LPFC_MBOXQ_t *pmboxq;
|
|
||||||
struct lpfc_dmabuf *buf_ptr;
|
struct lpfc_dmabuf *buf_ptr;
|
||||||
int retval, i;
|
int retval = 0;
|
||||||
|
int i, tmo;
|
||||||
struct lpfc_sli *psli = &phba->sli;
|
struct lpfc_sli *psli = &phba->sli;
|
||||||
LIST_HEAD(completions);
|
LIST_HEAD(completions);
|
||||||
|
|
||||||
@@ -1424,24 +1478,6 @@ lpfc_hb_timeout_handler(struct lpfc_hba *phba)
|
|||||||
(phba->pport->fc_flag & FC_OFFLINE_MODE))
|
(phba->pport->fc_flag & FC_OFFLINE_MODE))
|
||||||
return;
|
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 &&
|
if (phba->elsbuf_cnt &&
|
||||||
(phba->elsbuf_cnt == phba->elsbuf_prev_cnt)) {
|
(phba->elsbuf_cnt == phba->elsbuf_prev_cnt)) {
|
||||||
spin_lock_irq(&phba->hbalock);
|
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 there is no heart beat outstanding, issue a heartbeat command */
|
||||||
if (phba->cfg_enable_hba_heartbeat) {
|
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)) &&
|
if ((!(psli->sli_flag & LPFC_SLI_MBOX_ACTIVE)) &&
|
||||||
(list_empty(&psli->mboxq))) {
|
(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);
|
retval = lpfc_issue_hb_mbox(phba);
|
||||||
pmboxq->mbox_cmpl = lpfc_hb_mbox_cmpl;
|
if (retval) {
|
||||||
pmboxq->vport = phba->pport;
|
tmo = (1000 * LPFC_HB_MBOX_INTERVAL);
|
||||||
retval = lpfc_sli_issue_mbox(phba, pmboxq,
|
goto out;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
phba->skipped_hb = 0;
|
phba->skipped_hb = 0;
|
||||||
phba->hb_outstanding = 1;
|
|
||||||
} else if (time_before_eq(phba->last_completion_time,
|
} else if (time_before_eq(phba->last_completion_time,
|
||||||
phba->skipped_hb)) {
|
phba->skipped_hb)) {
|
||||||
lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
|
lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
|
||||||
@@ -1502,30 +1544,23 @@ lpfc_hb_timeout_handler(struct lpfc_hba *phba)
|
|||||||
} else
|
} else
|
||||||
phba->skipped_hb = jiffies;
|
phba->skipped_hb = jiffies;
|
||||||
|
|
||||||
mod_timer(&phba->hb_tmofunc,
|
tmo = (1000 * LPFC_HB_MBOX_TIMEOUT);
|
||||||
jiffies +
|
goto out;
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
mod_timer(&phba->hb_tmofunc,
|
/* Check to see if we want to force a MBX_HEARTBEAT */
|
||||||
jiffies +
|
if (phba->hba_flag & HBA_HBEAT_TMO) {
|
||||||
msecs_to_jiffies(1000 * LPFC_HB_MBOX_INTERVAL));
|
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 */
|
/* need reset: attempt for port recovery */
|
||||||
if (en_rn_msg)
|
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 "
|
"2887 Reset Needed: Attempting Port "
|
||||||
"Recovery...\n");
|
"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_offline_prep(phba, mbx_action);
|
||||||
lpfc_sli_flush_io_rings(phba);
|
lpfc_sli_flush_io_rings(phba);
|
||||||
lpfc_offline(phba);
|
lpfc_offline(phba);
|
||||||
@@ -2979,7 +3024,7 @@ lpfc_stop_hba_timers(struct lpfc_hba *phba)
|
|||||||
del_timer_sync(&phba->rrq_tmr);
|
del_timer_sync(&phba->rrq_tmr);
|
||||||
phba->hba_flag &= ~HBA_RRQ_ACTIVE;
|
phba->hba_flag &= ~HBA_RRQ_ACTIVE;
|
||||||
}
|
}
|
||||||
phba->hb_outstanding = 0;
|
phba->hba_flag &= ~(HBA_HBEAT_INP | HBA_HBEAT_TMO);
|
||||||
|
|
||||||
switch (phba->pci_dev_grp) {
|
switch (phba->pci_dev_grp) {
|
||||||
case LPFC_PCI_DEV_LP:
|
case LPFC_PCI_DEV_LP:
|
||||||
@@ -3592,6 +3637,10 @@ lpfc_offline(struct lpfc_hba *phba)
|
|||||||
spin_unlock_irq(shost->host_lock);
|
spin_unlock_irq(shost->host_lock);
|
||||||
}
|
}
|
||||||
lpfc_destroy_vport_work_array(phba, vports);
|
lpfc_destroy_vport_work_array(phba, vports);
|
||||||
|
/* 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);
|
__lpfc_cpuhp_remove(phba);
|
||||||
|
|
||||||
if (phba->cfg_xri_rebalancing)
|
if (phba->cfg_xri_rebalancing)
|
||||||
@@ -6177,10 +6226,14 @@ lpfc_reset_hba(struct lpfc_hba *phba)
|
|||||||
phba->link_state = LPFC_HBA_ERROR;
|
phba->link_state = LPFC_HBA_ERROR;
|
||||||
return;
|
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);
|
lpfc_offline_prep(phba, LPFC_MBX_WAIT);
|
||||||
else
|
} else {
|
||||||
lpfc_offline_prep(phba, LPFC_MBX_NO_WAIT);
|
lpfc_offline_prep(phba, LPFC_MBX_NO_WAIT);
|
||||||
|
lpfc_sli_flush_io_rings(phba);
|
||||||
|
}
|
||||||
lpfc_offline(phba);
|
lpfc_offline(phba);
|
||||||
lpfc_sli_brdrestart(phba);
|
lpfc_sli_brdrestart(phba);
|
||||||
lpfc_online(phba);
|
lpfc_online(phba);
|
||||||
@@ -10728,10 +10781,13 @@ lpfc_sli_enable_intr(struct lpfc_hba *phba, uint32_t cfg_mode)
|
|||||||
uint32_t intr_mode = LPFC_INTR_ERROR;
|
uint32_t intr_mode = LPFC_INTR_ERROR;
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
if (cfg_mode == 2) {
|
|
||||||
/* Need to issue conf_port mbox cmd before conf_msi mbox cmd */
|
/* Need to issue conf_port mbox cmd before conf_msi mbox cmd */
|
||||||
retval = lpfc_sli_config_port(phba, LPFC_SLI_REV3);
|
retval = lpfc_sli_config_port(phba, LPFC_SLI_REV3);
|
||||||
if (!retval) {
|
if (retval)
|
||||||
|
return intr_mode;
|
||||||
|
phba->hba_flag &= ~HBA_NEEDS_CFG_PORT;
|
||||||
|
|
||||||
|
if (cfg_mode == 2) {
|
||||||
/* Now, try to enable MSI-X interrupt mode */
|
/* Now, try to enable MSI-X interrupt mode */
|
||||||
retval = lpfc_sli_enable_msix(phba);
|
retval = lpfc_sli_enable_msix(phba);
|
||||||
if (!retval) {
|
if (!retval) {
|
||||||
@@ -10740,7 +10796,6 @@ lpfc_sli_enable_intr(struct lpfc_hba *phba, uint32_t cfg_mode)
|
|||||||
intr_mode = 2;
|
intr_mode = 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* Fallback to MSI if MSI-X initialization failed */
|
/* Fallback to MSI if MSI-X initialization failed */
|
||||||
if (cfg_mode >= 1 && phba->intr_type == NONE) {
|
if (cfg_mode >= 1 && phba->intr_type == NONE) {
|
||||||
@@ -14122,15 +14177,32 @@ void lpfc_dmp_dbg(struct lpfc_hba *phba)
|
|||||||
int i;
|
int i;
|
||||||
int j = 0;
|
int j = 0;
|
||||||
unsigned long rem_nsec;
|
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)
|
if (phba->cfg_log_verbose)
|
||||||
return;
|
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)
|
if (atomic_cmpxchg(&phba->dbg_log_dmping, 0, 1) != 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
start_idx = (unsigned int)atomic_read(&phba->dbg_log_idx) % DBG_LOG_SZ;
|
start_idx = (unsigned int)atomic_read(&phba->dbg_log_idx) % DBG_LOG_SZ;
|
||||||
dbg_cnt = (unsigned int)atomic_read(&phba->dbg_log_cnt);
|
dbg_cnt = (unsigned int)atomic_read(&phba->dbg_log_cnt);
|
||||||
|
if (!dbg_cnt)
|
||||||
|
goto out;
|
||||||
temp_idx = start_idx;
|
temp_idx = start_idx;
|
||||||
if (dbg_cnt >= DBG_LOG_SZ) {
|
if (dbg_cnt >= DBG_LOG_SZ) {
|
||||||
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,
|
rem_nsec / 1000,
|
||||||
phba->dbg_log[temp_idx].log);
|
phba->dbg_log[temp_idx].log);
|
||||||
}
|
}
|
||||||
|
out:
|
||||||
atomic_set(&phba->dbg_log_cnt, 0);
|
atomic_set(&phba->dbg_log_cnt, 0);
|
||||||
atomic_set(&phba->dbg_log_dmping, 0);
|
atomic_set(&phba->dbg_log_dmping, 0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2409,7 +2409,7 @@ error:
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 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.
|
* @phba: pointer to the hba structure containing.
|
||||||
* @mbox: pointer to lpfc mbox command to initialize.
|
* @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);
|
lpfc_sli_issue_abort_iotag(phba, pring, iocb, NULL);
|
||||||
spin_unlock_irq(&phba->hbalock);
|
spin_unlock_irq(&phba->hbalock);
|
||||||
}
|
}
|
||||||
|
/* Make sure HBA is alive */
|
||||||
|
lpfc_issue_hb_tmo(phba);
|
||||||
|
|
||||||
INIT_LIST_HEAD(&abort_list);
|
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) &&
|
if (!(ndlp->nlp_type & NLP_FABRIC) &&
|
||||||
!(phba->nvmet_support)) {
|
!(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,
|
lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb,
|
||||||
ndlp, NULL);
|
ndlp, NULL);
|
||||||
return 1;
|
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_FCP_TARGET | NLP_FCP_INITIATOR);
|
||||||
ndlp->nlp_type &= ~(NLP_NVME_TARGET | NLP_NVME_INITIATOR);
|
ndlp->nlp_type &= ~(NLP_NVME_TARGET | NLP_NVME_INITIATOR);
|
||||||
ndlp->nlp_fcp_info &= ~NLP_FCP_2_DEVICE;
|
ndlp->nlp_fcp_info &= ~NLP_FCP_2_DEVICE;
|
||||||
|
ndlp->nlp_nvme_info &= ~NLP_NVME_NSLER;
|
||||||
ndlp->nlp_flag &= ~NLP_FIRSTBURST;
|
ndlp->nlp_flag &= ~NLP_FIRSTBURST;
|
||||||
|
|
||||||
login_mbox = NULL;
|
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;
|
ndlp->nlp_fc4_type |= NLP_FC4_NVME;
|
||||||
lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
|
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;
|
ndlp->nlp_fc4_type |= NLP_FC4_FCP;
|
||||||
}
|
}
|
||||||
if (rport) {
|
if (rport) {
|
||||||
@@ -2034,6 +2051,7 @@ lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_vport *vport,
|
|||||||
* must complete PRLI.
|
* must complete PRLI.
|
||||||
*/
|
*/
|
||||||
if (ndlp->nlp_type & NLP_FABRIC) {
|
if (ndlp->nlp_type & NLP_FABRIC) {
|
||||||
|
ndlp->nlp_fc4_type &= ~NLP_FC4_FCP;
|
||||||
ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE;
|
ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE;
|
||||||
lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
|
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))
|
if (!lpfc_rcv_prli_support_check(vport, ndlp, cmdiocb))
|
||||||
return ndlp->nlp_state;
|
return ndlp->nlp_state;
|
||||||
|
lpfc_rcv_prli(vport, ndlp, cmdiocb);
|
||||||
lpfc_els_rsp_prli_acc(vport, cmdiocb, ndlp);
|
lpfc_els_rsp_prli_acc(vport, cmdiocb, ndlp);
|
||||||
return ndlp->nlp_state;
|
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);
|
bf_set(wqe_xri_tag, &wqe->gen_req.wqe_com, genwqe->sli4_xritag);
|
||||||
|
|
||||||
/* Word 7 */
|
/* 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_class, &wqe->gen_req.wqe_com, CLASS3);
|
||||||
bf_set(wqe_cmnd, &wqe->gen_req.wqe_com, CMD_GEN_REQUEST64_WQE);
|
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);
|
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,
|
ret = lpfc_nvme_gen_req(vport, bmp, pnvme_lsreq->rqstaddr,
|
||||||
pnvme_lsreq, gen_req_cmp, ndlp, 2,
|
pnvme_lsreq, gen_req_cmp, ndlp, 2,
|
||||||
LPFC_NVME_LS_TIMEOUT, 0);
|
pnvme_lsreq->timeout, 0);
|
||||||
if (ret != WQE_SUCCESS) {
|
if (ret != WQE_SUCCESS) {
|
||||||
lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
|
lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
|
||||||
"6052 NVMEx REQ: EXIT. issue ls wqe failed "
|
"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(&lpfc_nbuf->buf_lock);
|
||||||
spin_unlock_irqrestore(&phba->hbalock, flags);
|
spin_unlock_irqrestore(&phba->hbalock, flags);
|
||||||
|
|
||||||
|
/* Make sure HBA is alive */
|
||||||
|
lpfc_issue_hb_tmo(phba);
|
||||||
|
|
||||||
if (ret_val != WQE_SUCCESS) {
|
if (ret_val != WQE_SUCCESS) {
|
||||||
lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
|
lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
|
||||||
"6137 Failed abts issue_wqe with status x%x "
|
"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
|
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))
|
#if (IS_ENABLED(CONFIG_NVME_FC))
|
||||||
struct lpfc_io_buf *lpfc_ncmd;
|
struct lpfc_io_buf *lpfc_ncmd;
|
||||||
struct nvmefc_fcp_req *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);
|
lpfc_sli_release_iocbq(phba, pwqeIn);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -2616,31 +2627,29 @@ lpfc_nvme_cancel_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *pwqeIn)
|
|||||||
lpfc_sli_release_iocbq(phba, pwqeIn);
|
lpfc_sli_release_iocbq(phba, pwqeIn);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
lpfc_ncmd = (struct lpfc_io_buf *)pwqeIn->context1;
|
|
||||||
|
|
||||||
spin_lock(&lpfc_ncmd->buf_lock);
|
spin_lock(&lpfc_ncmd->buf_lock);
|
||||||
if (!lpfc_ncmd->nvmeCmd) {
|
nCmd = lpfc_ncmd->nvmeCmd;
|
||||||
|
if (!nCmd) {
|
||||||
spin_unlock(&lpfc_ncmd->buf_lock);
|
spin_unlock(&lpfc_ncmd->buf_lock);
|
||||||
lpfc_release_nvme_buf(phba, lpfc_ncmd);
|
lpfc_release_nvme_buf(phba, lpfc_ncmd);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
spin_unlock(&lpfc_ncmd->buf_lock);
|
||||||
|
|
||||||
nCmd = lpfc_ncmd->nvmeCmd;
|
|
||||||
lpfc_printf_log(phba, KERN_INFO, LOG_NVME_IOERR,
|
lpfc_printf_log(phba, KERN_INFO, LOG_NVME_IOERR,
|
||||||
"6194 NVME Cancel xri %x\n",
|
"6194 NVME Cancel xri %x\n",
|
||||||
lpfc_ncmd->cur_iocbq.sli4_xritag);
|
lpfc_ncmd->cur_iocbq.sli4_xritag);
|
||||||
|
|
||||||
nCmd->transferred_length = 0;
|
wcqep->word0 = 0;
|
||||||
nCmd->rcv_rsplen = 0;
|
bf_set(lpfc_wcqe_c_status, wcqep, stat);
|
||||||
nCmd->status = NVME_SC_INTERNAL;
|
wcqep->parameter = param;
|
||||||
freqpriv = nCmd->private;
|
wcqep->word3 = 0; /* xb is 0 */
|
||||||
freqpriv->nvme_buf = NULL;
|
|
||||||
lpfc_ncmd->nvmeCmd = NULL;
|
|
||||||
|
|
||||||
spin_unlock(&lpfc_ncmd->buf_lock);
|
|
||||||
nCmd->done(nCmd);
|
|
||||||
|
|
||||||
/* Call release with XB=1 to queue the IO into the abort list. */
|
/* 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
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1367,17 +1367,22 @@ static void
|
|||||||
lpfc_nvmet_host_release(void *hosthandle)
|
lpfc_nvmet_host_release(void *hosthandle)
|
||||||
{
|
{
|
||||||
struct lpfc_nodelist *ndlp = hosthandle;
|
struct lpfc_nodelist *ndlp = hosthandle;
|
||||||
struct lpfc_hba *phba = NULL;
|
struct lpfc_hba *phba = ndlp->phba;
|
||||||
struct lpfc_nvmet_tgtport *tgtp;
|
struct lpfc_nvmet_tgtport *tgtp;
|
||||||
|
|
||||||
phba = ndlp->phba;
|
|
||||||
if (!phba->targetport || !phba->targetport->private)
|
if (!phba->targetport || !phba->targetport->private)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
lpfc_printf_log(phba, KERN_ERR, LOG_NVME,
|
lpfc_printf_log(phba, KERN_ERR, LOG_NVME,
|
||||||
"6202 NVMET XPT releasing hosthandle x%px\n",
|
"6202 NVMET XPT releasing hosthandle x%px "
|
||||||
hosthandle);
|
"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;
|
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);
|
atomic_set(&tgtp->state, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3644,15 +3649,33 @@ out:
|
|||||||
void
|
void
|
||||||
lpfc_nvmet_invalidate_host(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
|
lpfc_nvmet_invalidate_host(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
|
||||||
{
|
{
|
||||||
|
u32 ndlp_has_hh;
|
||||||
struct lpfc_nvmet_tgtport *tgtp;
|
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",
|
"6203 Invalidating hosthandle x%px\n",
|
||||||
ndlp);
|
ndlp);
|
||||||
|
|
||||||
tgtp = (struct lpfc_nvmet_tgtport *)phba->targetport->private;
|
tgtp = (struct lpfc_nvmet_tgtport *)phba->targetport->private;
|
||||||
atomic_set(&tgtp->state, LPFC_NVMET_INV_HOST_ACTIVE);
|
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))
|
#if (IS_ENABLED(CONFIG_NVME_TARGET_FC))
|
||||||
/* Need to get the nvmet_fc_target_port pointer here.*/
|
/* Need to get the nvmet_fc_target_port pointer here.*/
|
||||||
nvmet_fc_invalidate_host(phba->targetport, ndlp);
|
nvmet_fc_invalidate_host(phba->targetport, ndlp);
|
||||||
|
|||||||
@@ -5479,6 +5479,9 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd)
|
|||||||
lpfc_sli_abort_fcp_cmpl);
|
lpfc_sli_abort_fcp_cmpl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Make sure HBA is alive */
|
||||||
|
lpfc_issue_hb_tmo(phba);
|
||||||
|
|
||||||
if (ret_val != IOCB_SUCCESS) {
|
if (ret_val != IOCB_SUCCESS) {
|
||||||
/* Indicate the IO is not being aborted by the driver. */
|
/* Indicate the IO is not being aborted by the driver. */
|
||||||
lpfc_cmd->waitq = NULL;
|
lpfc_cmd->waitq = NULL;
|
||||||
@@ -5849,6 +5852,7 @@ lpfc_device_reset_handler(struct scsi_cmnd *cmnd)
|
|||||||
uint64_t lun_id = cmnd->device->lun;
|
uint64_t lun_id = cmnd->device->lun;
|
||||||
struct lpfc_scsi_event_header scsi_event;
|
struct lpfc_scsi_event_header scsi_event;
|
||||||
int status;
|
int status;
|
||||||
|
u32 logit = LOG_FCP;
|
||||||
|
|
||||||
rdata = lpfc_rport_data_from_scsi_device(cmnd->device);
|
rdata = lpfc_rport_data_from_scsi_device(cmnd->device);
|
||||||
if (!rdata || !rdata->pnode) {
|
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,
|
status = lpfc_send_taskmgmt(vport, cmnd, tgt_id, lun_id,
|
||||||
FCP_LUN_RESET);
|
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) "
|
"0713 SCSI layer issued Device Reset (%d, %llu) "
|
||||||
"return x%x\n", tgt_id, lun_id, status);
|
"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;
|
uint64_t lun_id = cmnd->device->lun;
|
||||||
struct lpfc_scsi_event_header scsi_event;
|
struct lpfc_scsi_event_header scsi_event;
|
||||||
int status;
|
int status;
|
||||||
|
u32 logit = LOG_FCP;
|
||||||
|
unsigned long flags;
|
||||||
|
DECLARE_WAIT_QUEUE_HEAD_ONSTACK(waitq);
|
||||||
|
|
||||||
rdata = lpfc_rport_data_from_scsi_device(cmnd->device);
|
rdata = lpfc_rport_data_from_scsi_device(cmnd->device);
|
||||||
if (!rdata || !rdata->pnode) {
|
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,
|
lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
|
||||||
"0722 Target Reset rport failure: rdata x%px\n", rdata);
|
"0722 Target Reset rport failure: rdata x%px\n", rdata);
|
||||||
if (pnode) {
|
if (pnode) {
|
||||||
spin_lock_irq(&pnode->lock);
|
spin_lock_irqsave(&pnode->lock, flags);
|
||||||
pnode->nlp_flag &= ~NLP_NPR_ADISC;
|
pnode->nlp_flag &= ~NLP_NPR_ADISC;
|
||||||
pnode->nlp_fcp_info &= ~NLP_FCP_2_DEVICE;
|
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_reset_flush_io_context(vport, tgt_id, lun_id,
|
||||||
LPFC_CTX_TGT);
|
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,
|
status = lpfc_send_taskmgmt(vport, cmnd, tgt_id, lun_id,
|
||||||
FCP_TARGET_RESET);
|
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));
|
||||||
|
|
||||||
|
if (pnode->upcall_flags & NLP_WAIT_FOR_LOGO) {
|
||||||
lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
|
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) "
|
"0723 SCSI layer issued Target Reset (%d, %llu) "
|
||||||
"return x%x\n", tgt_id, lun_id, status);
|
"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;
|
struct lpfc_scsi_event_header scsi_event;
|
||||||
int match;
|
int match;
|
||||||
int ret = SUCCESS, status, i;
|
int ret = SUCCESS, status, i;
|
||||||
|
u32 logit = LOG_FCP;
|
||||||
|
|
||||||
scsi_event.event_type = FC_REG_SCSI_EVENT;
|
scsi_event.event_type = FC_REG_SCSI_EVENT;
|
||||||
scsi_event.subcategory = LPFC_EVENT_BUSRESET;
|
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);
|
status = lpfc_reset_flush_io_context(vport, 0, 0, LPFC_CTX_HOST);
|
||||||
if (status != SUCCESS)
|
if (status != SUCCESS)
|
||||||
ret = FAILED;
|
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);
|
"0714 SCSI layer issued Bus Reset Data: x%x\n", ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -6086,7 +6132,7 @@ lpfc_host_reset_handler(struct scsi_cmnd *cmnd)
|
|||||||
struct lpfc_hba *phba = vport->phba;
|
struct lpfc_hba *phba = vport->phba;
|
||||||
int rc, ret = SUCCESS;
|
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");
|
"3172 SCSI layer issued Host Reset Data:\n");
|
||||||
|
|
||||||
lpfc_offline_prep(phba, LPFC_MBX_WAIT);
|
lpfc_offline_prep(phba, LPFC_MBX_WAIT);
|
||||||
@@ -6662,6 +6708,7 @@ struct scsi_host_template lpfc_template = {
|
|||||||
.info = lpfc_info,
|
.info = lpfc_info,
|
||||||
.queuecommand = lpfc_queuecommand,
|
.queuecommand = lpfc_queuecommand,
|
||||||
.eh_timed_out = fc_eh_timed_out,
|
.eh_timed_out = fc_eh_timed_out,
|
||||||
|
.eh_should_retry_cmd = fc_eh_should_retry_cmd,
|
||||||
.eh_abort_handler = lpfc_abort_handler,
|
.eh_abort_handler = lpfc_abort_handler,
|
||||||
.eh_device_reset_handler = lpfc_device_reset_handler,
|
.eh_device_reset_handler = lpfc_device_reset_handler,
|
||||||
.eh_target_reset_handler = lpfc_target_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)) {
|
while (!list_empty(iocblist)) {
|
||||||
list_remove_head(iocblist, piocb, struct lpfc_iocbq, list);
|
list_remove_head(iocblist, piocb, struct lpfc_iocbq, list);
|
||||||
if (!piocb->iocb_cmpl) {
|
if (piocb->wqe_cmpl) {
|
||||||
if (piocb->iocb_flag & LPFC_IO_NVME)
|
if (piocb->iocb_flag & LPFC_IO_NVME)
|
||||||
lpfc_nvme_cancel_iocb(phba, piocb);
|
lpfc_nvme_cancel_iocb(phba, piocb,
|
||||||
|
ulpstatus, ulpWord4);
|
||||||
else
|
else
|
||||||
lpfc_sli_release_iocbq(phba, piocb);
|
lpfc_sli_release_iocbq(phba, piocb);
|
||||||
} else {
|
|
||||||
|
} else if (piocb->iocb_cmpl) {
|
||||||
piocb->iocb.ulpStatus = ulpstatus;
|
piocb->iocb.ulpStatus = ulpstatus;
|
||||||
piocb->iocb.un.ulpWord[4] = ulpWord4;
|
piocb->iocb.un.ulpWord[4] = ulpWord4;
|
||||||
(piocb->iocb_cmpl) (phba, piocb, piocb);
|
(piocb->iocb_cmpl) (phba, piocb, piocb);
|
||||||
|
} else {
|
||||||
|
lpfc_sli_release_iocbq(phba, piocb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@@ -3007,23 +3011,44 @@ lpfc_nvme_unsol_ls_handler(struct lpfc_hba *phba, struct lpfc_iocbq *piocb)
|
|||||||
axchg->payload = nvmebuf->dbuf.virt;
|
axchg->payload = nvmebuf->dbuf.virt;
|
||||||
INIT_LIST_HEAD(&axchg->list);
|
INIT_LIST_HEAD(&axchg->list);
|
||||||
|
|
||||||
if (phba->nvmet_support)
|
if (phba->nvmet_support) {
|
||||||
ret = lpfc_nvmet_handle_lsreq(phba, axchg);
|
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);
|
ret = lpfc_nvme_handle_lsreq(phba, axchg);
|
||||||
|
}
|
||||||
|
|
||||||
/* if zero, LS was successfully handled. If non-zero, LS not handled */
|
/* if zero, LS was successfully handled. If non-zero, LS not handled */
|
||||||
if (!ret)
|
if (!ret)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
out_fail:
|
||||||
lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
|
lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
|
||||||
"6155 Drop NVME LS from DID %06X: SID %06X OXID x%X "
|
"6155 Drop NVME LS from DID %06X: SID %06X OXID x%X "
|
||||||
"NVMe%s handler failed %d\n",
|
"NVMe%s handler failed %d\n",
|
||||||
did, sid, oxid,
|
did, sid, oxid,
|
||||||
(phba->nvmet_support) ? "T" : "I", ret);
|
(phba->nvmet_support) ? "T" : "I", ret);
|
||||||
|
|
||||||
out_fail:
|
|
||||||
|
|
||||||
/* recycle receive buffer */
|
/* recycle receive buffer */
|
||||||
lpfc_in_buf_free(phba, &nvmebuf->dbuf);
|
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);
|
lpfc_sli_issue_abort_iotag(phba, pring, iocb, NULL);
|
||||||
spin_unlock_irq(&phba->hbalock);
|
spin_unlock_irq(&phba->hbalock);
|
||||||
}
|
}
|
||||||
|
/* Make sure HBA is alive */
|
||||||
|
lpfc_issue_hb_tmo(phba);
|
||||||
|
|
||||||
/* Cancel all the IOCBs from the completions list */
|
/* Cancel all the IOCBs from the completions list */
|
||||||
lpfc_sli_cancel_iocbs(phba, &completions, IOSTAT_LOCAL_REJECT,
|
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))
|
if (lpfc_readl(phba->HSregaddr, &status))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
phba->hba_flag |= HBA_NEEDS_CFG_PORT;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check status register every 100ms for 5 retries, then every
|
* Check status register every 100ms for 5 retries, then every
|
||||||
* 500ms for 5, then every 2.5 sec for 5, then reset board and
|
* 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 */
|
/* perform board reset */
|
||||||
phba->fc_eventTag = 0;
|
phba->fc_eventTag = 0;
|
||||||
phba->link_events = 0;
|
phba->link_events = 0;
|
||||||
|
phba->hba_flag |= HBA_NEEDS_CFG_PORT;
|
||||||
if (phba->pport) {
|
if (phba->pport) {
|
||||||
phba->pport->fc_myDID = 0;
|
phba->pport->fc_myDID = 0;
|
||||||
phba->pport->fc_prevDID = 0;
|
phba->pport->fc_prevDID = 0;
|
||||||
@@ -5020,6 +5050,8 @@ lpfc_sli_chipset_init(struct lpfc_hba *phba)
|
|||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
phba->hba_flag |= HBA_NEEDS_CFG_PORT;
|
||||||
|
|
||||||
/* Clear all interrupt enable conditions */
|
/* Clear all interrupt enable conditions */
|
||||||
writel(0, phba->HCregaddr);
|
writel(0, phba->HCregaddr);
|
||||||
readl(phba->HCregaddr); /* flush */
|
readl(phba->HCregaddr); /* flush */
|
||||||
@@ -5316,45 +5348,18 @@ int
|
|||||||
lpfc_sli_hba_setup(struct lpfc_hba *phba)
|
lpfc_sli_hba_setup(struct lpfc_hba *phba)
|
||||||
{
|
{
|
||||||
uint32_t rc;
|
uint32_t rc;
|
||||||
int mode = 3, i;
|
int i;
|
||||||
int longs;
|
int longs;
|
||||||
|
|
||||||
switch (phba->cfg_sli_mode) {
|
/* Enable ISR already does config_port because of config_msi mbx */
|
||||||
case 2:
|
if (phba->hba_flag & HBA_NEEDS_CFG_PORT) {
|
||||||
if (phba->cfg_enable_npiv) {
|
rc = lpfc_sli_config_port(phba, LPFC_SLI_REV3);
|
||||||
lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
|
if (rc)
|
||||||
"1824 NPIV enabled: Override sli_mode "
|
return -EIO;
|
||||||
"parameter (%d) to auto (0).\n",
|
phba->hba_flag &= ~HBA_NEEDS_CFG_PORT;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
phba->fcp_embed_io = 0; /* SLI4 FC support only */
|
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 */
|
/* Enable PCIe device Advanced Error Reporting (AER) if configured */
|
||||||
if (phba->cfg_aer_support == 1 && !(phba->hba_flag & HBA_AER_ENABLED)) {
|
if (phba->cfg_aer_support == 1 && !(phba->hba_flag & HBA_AER_ENABLED)) {
|
||||||
rc = pci_enable_pcie_error_reporting(phba->pcidev);
|
rc = pci_enable_pcie_error_reporting(phba->pcidev);
|
||||||
@@ -7486,7 +7491,7 @@ static void lpfc_sli4_dip(struct lpfc_hba *phba)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (bf_get(lpfc_sliport_status_dip, ®_data))
|
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"
|
"2904 Firmware Dump Image Present"
|
||||||
" on Adapter");
|
" on Adapter");
|
||||||
}
|
}
|
||||||
@@ -8041,7 +8046,7 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba)
|
|||||||
/* Start heart beat timer */
|
/* Start heart beat timer */
|
||||||
mod_timer(&phba->hb_tmofunc,
|
mod_timer(&phba->hb_tmofunc,
|
||||||
jiffies + msecs_to_jiffies(1000 * LPFC_HB_MBOX_INTERVAL));
|
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;
|
phba->last_completion_time = jiffies;
|
||||||
|
|
||||||
/* start eq_delay heartbeat */
|
/* start eq_delay heartbeat */
|
||||||
@@ -8291,8 +8296,10 @@ lpfc_mbox_timeout_handler(struct lpfc_hba *phba)
|
|||||||
|
|
||||||
struct lpfc_sli *psli = &phba->sli;
|
struct lpfc_sli *psli = &phba->sli;
|
||||||
|
|
||||||
/* If the mailbox completed, process the completion and return */
|
/* If the mailbox completed, process the completion */
|
||||||
if (lpfc_sli4_process_missed_mbox_completions(phba))
|
lpfc_sli4_process_missed_mbox_completions(phba);
|
||||||
|
|
||||||
|
if (!(psli->sli_flag & LPFC_SLI_ACTIVE))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (pmbox != NULL)
|
if (pmbox != NULL)
|
||||||
@@ -8333,8 +8340,6 @@ lpfc_mbox_timeout_handler(struct lpfc_hba *phba)
|
|||||||
psli->sli_flag &= ~LPFC_SLI_ACTIVE;
|
psli->sli_flag &= ~LPFC_SLI_ACTIVE;
|
||||||
spin_unlock_irq(&phba->hbalock);
|
spin_unlock_irq(&phba->hbalock);
|
||||||
|
|
||||||
lpfc_sli_abort_fcp_rings(phba);
|
|
||||||
|
|
||||||
lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
|
lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
|
||||||
"0345 Resetting board due to mailbox timeout\n");
|
"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);
|
spin_unlock_irqrestore(&phba->hbalock, flags);
|
||||||
|
|
||||||
|
/* Make sure HBA is alive */
|
||||||
|
lpfc_issue_hb_tmo(phba);
|
||||||
|
|
||||||
/* Cancel all the IOCBs from the completions list */
|
/* Cancel all the IOCBs from the completions list */
|
||||||
lpfc_sli_cancel_iocbs(phba, &completions, IOSTAT_LOCAL_REJECT,
|
lpfc_sli_cancel_iocbs(phba, &completions, IOSTAT_LOCAL_REJECT,
|
||||||
IOERR_SLI_DOWN);
|
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;
|
struct lpfc_io_buf *lpfc_cmd;
|
||||||
int rc = 1;
|
int rc = 1;
|
||||||
|
|
||||||
if (iocbq->vport != vport)
|
if (!iocbq || iocbq->vport != vport)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
if (!(iocbq->iocb_flag & LPFC_IO_FCP) ||
|
if (!(iocbq->iocb_flag & LPFC_IO_FCP) ||
|
||||||
@@ -13026,8 +13034,22 @@ lpfc_sli_sp_intr_handler(int irq, void *dev_id)
|
|||||||
spin_unlock_irqrestore(
|
spin_unlock_irqrestore(
|
||||||
&phba->pport->work_port_lock,
|
&phba->pport->work_port_lock,
|
||||||
iflag);
|
iflag);
|
||||||
|
|
||||||
|
/* 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);
|
lpfc_mbox_cmpl_put(phba, pmb);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else
|
} else
|
||||||
spin_unlock_irqrestore(&phba->hbalock, iflag);
|
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;
|
phba->pport->work_port_events &= ~WORKER_MBOX_TMO;
|
||||||
spin_unlock_irqrestore(&phba->pport->work_port_lock, iflags);
|
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);
|
spin_lock_irqsave(&phba->hbalock, iflags);
|
||||||
__lpfc_mbox_cmpl_put(phba, pmb);
|
__lpfc_mbox_cmpl_put(phba, pmb);
|
||||||
phba->work_ha |= HA_MBATT;
|
phba->work_ha |= HA_MBATT;
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
* included with this package. *
|
* 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"
|
#define LPFC_DRIVER_NAME "lpfc"
|
||||||
|
|
||||||
/* Used for SLI 2/3 */
|
/* Used for SLI 2/3 */
|
||||||
|
|||||||
@@ -478,7 +478,7 @@ lpfc_vport_create(struct fc_vport *fc_vport, bool disable)
|
|||||||
rc = VPORT_OK;
|
rc = VPORT_OK;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
|
lpfc_printf_vlog(vport, KERN_ERR, LOG_VPORT,
|
||||||
"1825 Vport Created.\n");
|
"1825 Vport Created.\n");
|
||||||
lpfc_host_attrib_init(lpfc_shost_from_vport(vport));
|
lpfc_host_attrib_init(lpfc_shost_from_vport(vport));
|
||||||
error_out:
|
error_out:
|
||||||
|
|||||||
@@ -326,7 +326,6 @@ static void mac53c94_interrupt(int irq, void *dev_id)
|
|||||||
}
|
}
|
||||||
cmd->SCp.Status = readb(®s->fifo);
|
cmd->SCp.Status = readb(®s->fifo);
|
||||||
cmd->SCp.Message = readb(®s->fifo);
|
cmd->SCp.Message = readb(®s->fifo);
|
||||||
cmd->result = CMD_ACCEPT_MSG;
|
|
||||||
writeb(CMD_ACCEPT_MSG, ®s->command);
|
writeb(CMD_ACCEPT_MSG, ®s->command);
|
||||||
state->phase = busfreeing;
|
state->phase = busfreeing;
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -1165,7 +1165,7 @@ megaraid_mbox_setup_dma_pools(adapter_t *adapter)
|
|||||||
* structure
|
* structure
|
||||||
* Since passthru and extended passthru commands are exclusive, they
|
* Since passthru and extended passthru commands are exclusive, they
|
||||||
* share common memory pool. Passthru structures piggyback on memory
|
* 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",
|
raid_dev->epthru_pool_handle = dma_pool_create("megaraid mbox pthru",
|
||||||
&adapter->pdev->dev, sizeof(mraid_epassthru_t), 128, 0);
|
&adapter->pdev->dev, sizeof(mraid_epassthru_t), 128, 0);
|
||||||
|
|||||||
@@ -3920,7 +3920,6 @@ megasas_free_host_crash_buffer(struct megasas_instance *instance)
|
|||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
for (i = 0; i < instance->drv_buf_alloc; 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_index = 0;
|
||||||
|
|||||||
@@ -2505,8 +2505,8 @@ _base_check_pcie_native_sgl(struct MPT3SAS_ADAPTER *ioc,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Check if we need to build a native SG list. */
|
/* Check if we need to build a native SG list. */
|
||||||
if (base_is_prp_possible(ioc, pcie_device,
|
if (!base_is_prp_possible(ioc, pcie_device,
|
||||||
scmd, sges_left) == 0) {
|
scmd, sges_left)) {
|
||||||
/* We built a native SG list, just return. */
|
/* We built a native SG list, just return. */
|
||||||
goto out;
|
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);
|
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 mvs_phy *phy = &mvi->phy[i];
|
||||||
struct asd_sas_phy *sas_phy = &phy->sas_phy;
|
struct asd_sas_phy *sas_phy = &phy->sas_phy;
|
||||||
struct sas_ha_struct *sas_ha;
|
|
||||||
if (!phy->phy_attached)
|
if (!phy->phy_attached)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -229,8 +229,7 @@ static void mvs_bytes_dmaed(struct mvs_info *mvi, int i)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sas_ha = mvi->sas;
|
sas_notify_phy_event(sas_phy, PHYE_OOB_DONE, gfp_flags);
|
||||||
sas_ha->notify_phy_event(sas_phy, PHYE_OOB_DONE);
|
|
||||||
|
|
||||||
if (sas_phy->phy) {
|
if (sas_phy->phy) {
|
||||||
struct sas_phy *sphy = 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;
|
sas_phy->frame_rcvd_size = phy->frame_rcvd_size;
|
||||||
|
|
||||||
mvi->sas->notify_port_event(sas_phy,
|
sas_notify_port_event(sas_phy, PORTE_BYTES_DMAED, gfp_flags);
|
||||||
PORTE_BYTES_DMAED);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void mvs_scan_start(struct Scsi_Host *shost)
|
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++) {
|
for (j = 0; j < core_nr; j++) {
|
||||||
mvi = ((struct mvs_prv_info *)sha->lldd_ha)->mvi[j];
|
mvi = ((struct mvs_prv_info *)sha->lldd_ha)->mvi[j];
|
||||||
for (i = 0; i < mvi->chip->n_phy; ++i)
|
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;
|
mvs_prv->scan_finished = 1;
|
||||||
}
|
}
|
||||||
@@ -1880,7 +1878,6 @@ static void mvs_work_queue(struct work_struct *work)
|
|||||||
struct mvs_info *mvi = mwq->mvi;
|
struct mvs_info *mvi = mwq->mvi;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
u32 phy_no = (unsigned long) mwq->data;
|
u32 phy_no = (unsigned long) mwq->data;
|
||||||
struct sas_ha_struct *sas_ha = mvi->sas;
|
|
||||||
struct mvs_phy *phy = &mvi->phy[phy_no];
|
struct mvs_phy *phy = &mvi->phy[phy_no];
|
||||||
struct asd_sas_phy *sas_phy = &phy->sas_phy;
|
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)) {
|
if (!(tmp & PHY_READY_MASK)) {
|
||||||
sas_phy_disconnected(sas_phy);
|
sas_phy_disconnected(sas_phy);
|
||||||
mvs_phy_disconnected(phy);
|
mvs_phy_disconnected(phy);
|
||||||
sas_ha->notify_phy_event(sas_phy,
|
sas_notify_phy_event(sas_phy,
|
||||||
PHYE_LOSS_OF_SIGNAL);
|
PHYE_LOSS_OF_SIGNAL, GFP_ATOMIC);
|
||||||
mv_dprintk("phy%d Removed Device\n", phy_no);
|
mv_dprintk("phy%d Removed Device\n", phy_no);
|
||||||
} else {
|
} else {
|
||||||
MVS_CHIP_DISP->detect_porttype(mvi, phy_no);
|
MVS_CHIP_DISP->detect_porttype(mvi, phy_no);
|
||||||
mvs_update_phyinfo(mvi, phy_no, 1);
|
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);
|
mvs_port_notify_formed(sas_phy, 0);
|
||||||
mv_dprintk("phy%d Attached Device\n", phy_no);
|
mv_dprintk("phy%d Attached Device\n", phy_no);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (mwq->handler & EXP_BRCT_CHG) {
|
} else if (mwq->handler & EXP_BRCT_CHG) {
|
||||||
phy->phy_event &= ~EXP_BRCT_CHG;
|
phy->phy_event &= ~EXP_BRCT_CHG;
|
||||||
sas_ha->notify_port_event(sas_phy,
|
sas_notify_port_event(sas_phy,
|
||||||
PORTE_BROADCAST_RCVD);
|
PORTE_BROADCAST_RCVD, GFP_ATOMIC);
|
||||||
mv_dprintk("phy%d Got Broadcast Change\n", phy_no);
|
mv_dprintk("phy%d Got Broadcast Change\n", phy_no);
|
||||||
}
|
}
|
||||||
list_del(&mwq->entry);
|
list_del(&mwq->entry);
|
||||||
@@ -2026,7 +2023,7 @@ void mvs_int_port(struct mvs_info *mvi, int phy_no, u32 events)
|
|||||||
mdelay(10);
|
mdelay(10);
|
||||||
}
|
}
|
||||||
|
|
||||||
mvs_bytes_dmaed(mvi, phy_no);
|
mvs_bytes_dmaed(mvi, phy_no, GFP_ATOMIC);
|
||||||
/* whether driver is going to handle hot plug */
|
/* whether driver is going to handle hot plug */
|
||||||
if (phy->phy_event & PHY_PLUG_OUT) {
|
if (phy->phy_event & PHY_PLUG_OUT) {
|
||||||
mvs_port_notify_formed(&phy->sas_phy, 0);
|
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
|
#define DEBUG_FLAGS SCSI_NCR_DEBUG_FLAGS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Locally used status flag
|
||||||
|
*/
|
||||||
|
#define SAM_STAT_ILLEGAL 0xff
|
||||||
|
|
||||||
static inline struct list_head *ncr_list_pop(struct list_head *head)
|
static inline struct list_head *ncr_list_pop(struct list_head *head)
|
||||||
{
|
{
|
||||||
if (!list_empty(head)) {
|
if (!list_empty(head)) {
|
||||||
@@ -998,8 +1003,6 @@ typedef u32 tagmap_t;
|
|||||||
** Other definitions
|
** Other definitions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define ScsiResult(host_code, scsi_code) (((host_code) << 16) + ((scsi_code) & 0x7f))
|
|
||||||
|
|
||||||
#define initverbose (driver_setup.verbose)
|
#define initverbose (driver_setup.verbose)
|
||||||
#define bootverbose (np->verbose)
|
#define bootverbose (np->verbose)
|
||||||
|
|
||||||
@@ -2430,7 +2433,7 @@ static struct script script0 __initdata = {
|
|||||||
*/
|
*/
|
||||||
SCR_FROM_REG (SS_REG),
|
SCR_FROM_REG (SS_REG),
|
||||||
0,
|
0,
|
||||||
SCR_CALL ^ IFFALSE (DATA (S_GOOD)),
|
SCR_CALL ^ IFFALSE (DATA (SAM_STAT_GOOD)),
|
||||||
PADDRH (bad_status),
|
PADDRH (bad_status),
|
||||||
|
|
||||||
#ifndef SCSI_NCR_CCB_DONE_SUPPORT
|
#ifndef SCSI_NCR_CCB_DONE_SUPPORT
|
||||||
@@ -2879,7 +2882,7 @@ static struct scripth scripth0 __initdata = {
|
|||||||
8,
|
8,
|
||||||
SCR_TO_REG (HS_REG),
|
SCR_TO_REG (HS_REG),
|
||||||
0,
|
0,
|
||||||
SCR_LOAD_REG (SS_REG, S_GOOD),
|
SCR_LOAD_REG (SS_REG, SAM_STAT_GOOD),
|
||||||
0,
|
0,
|
||||||
SCR_JUMP,
|
SCR_JUMP,
|
||||||
PADDR (cleanup_ok),
|
PADDR (cleanup_ok),
|
||||||
@@ -3341,15 +3344,15 @@ static struct scripth scripth0 __initdata = {
|
|||||||
PADDRH (reset),
|
PADDRH (reset),
|
||||||
}/*-------------------------< BAD_STATUS >-----------------*/,{
|
}/*-------------------------< BAD_STATUS >-----------------*/,{
|
||||||
/*
|
/*
|
||||||
** If command resulted in either QUEUE FULL,
|
** If command resulted in either TASK_SET FULL,
|
||||||
** CHECK CONDITION or COMMAND TERMINATED,
|
** CHECK CONDITION or COMMAND TERMINATED,
|
||||||
** call the C code.
|
** call the C code.
|
||||||
*/
|
*/
|
||||||
SCR_INT ^ IFTRUE (DATA (S_QUEUE_FULL)),
|
SCR_INT ^ IFTRUE (DATA (SAM_STAT_TASK_SET_FULL)),
|
||||||
SIR_BAD_STATUS,
|
SIR_BAD_STATUS,
|
||||||
SCR_INT ^ IFTRUE (DATA (S_CHECK_COND)),
|
SCR_INT ^ IFTRUE (DATA (SAM_STAT_CHECK_CONDITION)),
|
||||||
SIR_BAD_STATUS,
|
SIR_BAD_STATUS,
|
||||||
SCR_INT ^ IFTRUE (DATA (S_TERMINATED)),
|
SCR_INT ^ IFTRUE (DATA (SAM_STAT_COMMAND_TERMINATED)),
|
||||||
SIR_BAD_STATUS,
|
SIR_BAD_STATUS,
|
||||||
SCR_RETURN,
|
SCR_RETURN,
|
||||||
0,
|
0,
|
||||||
@@ -4371,7 +4374,7 @@ static int ncr_queue_command (struct ncb *np, struct scsi_cmnd *cmd)
|
|||||||
*/
|
*/
|
||||||
cp->actualquirks = 0;
|
cp->actualquirks = 0;
|
||||||
cp->host_status = cp->nego_status ? HS_NEGOTIATE : HS_BUSY;
|
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->parity_status = 0;
|
||||||
|
|
||||||
cp->xerr_status = XE_OK;
|
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.
|
* in order to keep it alive.
|
||||||
*/
|
*/
|
||||||
if (!found && sync_reset && !retrieve_from_waiting_list(0, np, cmd)) {
|
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);
|
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
|
* First, look for the scsi command in the waiting list
|
||||||
*/
|
*/
|
||||||
if (remove_from_waiting_list(np, cmd)) {
|
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);
|
ncr_queue_done_cmd(np, cmd);
|
||||||
return SCSI_ABORT_SUCCESS;
|
return SCSI_ABORT_SUCCESS;
|
||||||
}
|
}
|
||||||
@@ -4895,7 +4898,8 @@ void ncr_complete (struct ncb *np, struct ccb *cp)
|
|||||||
** Print out any error for debugging purpose.
|
** Print out any error for debugging purpose.
|
||||||
*/
|
*/
|
||||||
if (DEBUG_FLAGS & (DEBUG_RESULT|DEBUG_TINY)) {
|
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 "
|
PRINT_ADDR(cmd, "ERROR: cmd=%x host_status=%x "
|
||||||
"scsi_status=%x\n", cmd->cmnd[0],
|
"scsi_status=%x\n", cmd->cmnd[0],
|
||||||
cp->host_status, cp->scsi_status);
|
cp->host_status, cp->scsi_status);
|
||||||
@@ -4905,15 +4909,16 @@ void ncr_complete (struct ncb *np, struct ccb *cp)
|
|||||||
/*
|
/*
|
||||||
** Check the status.
|
** Check the status.
|
||||||
*/
|
*/
|
||||||
|
cmd->result = 0;
|
||||||
if ( (cp->host_status == HS_COMPLETE)
|
if ( (cp->host_status == HS_COMPLETE)
|
||||||
&& (cp->scsi_status == S_GOOD ||
|
&& (cp->scsi_status == SAM_STAT_GOOD ||
|
||||||
cp->scsi_status == S_COND_MET)) {
|
cp->scsi_status == SAM_STAT_CONDITION_MET)) {
|
||||||
/*
|
/*
|
||||||
* All went well (GOOD status).
|
* All went well (GOOD status).
|
||||||
* CONDITION MET status is returned on
|
* CONDITION MET status is returned on
|
||||||
* `Pre-Fetch' or `Search data' success.
|
* `Pre-Fetch' or `Search data' success.
|
||||||
*/
|
*/
|
||||||
cmd->result = ScsiResult(DID_OK, cp->scsi_status);
|
set_status_byte(cmd, cp->scsi_status);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** @RESID@
|
** @RESID@
|
||||||
@@ -4944,11 +4949,11 @@ void ncr_complete (struct ncb *np, struct ccb *cp)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if ((cp->host_status == HS_COMPLETE)
|
} else if ((cp->host_status == HS_COMPLETE)
|
||||||
&& (cp->scsi_status == S_CHECK_COND)) {
|
&& (cp->scsi_status == SAM_STAT_CHECK_CONDITION)) {
|
||||||
/*
|
/*
|
||||||
** Check condition code
|
** 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.
|
** Copy back sense data to caller's buffer.
|
||||||
@@ -4965,20 +4970,20 @@ void ncr_complete (struct ncb *np, struct ccb *cp)
|
|||||||
printk (".\n");
|
printk (".\n");
|
||||||
}
|
}
|
||||||
} else if ((cp->host_status == HS_COMPLETE)
|
} else if ((cp->host_status == HS_COMPLETE)
|
||||||
&& (cp->scsi_status == S_CONFLICT)) {
|
&& (cp->scsi_status == SAM_STAT_RESERVATION_CONFLICT)) {
|
||||||
/*
|
/*
|
||||||
** Reservation Conflict condition code
|
** 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)
|
} else if ((cp->host_status == HS_COMPLETE)
|
||||||
&& (cp->scsi_status == S_BUSY ||
|
&& (cp->scsi_status == SAM_STAT_BUSY ||
|
||||||
cp->scsi_status == S_QUEUE_FULL)) {
|
cp->scsi_status == SAM_STAT_TASK_SET_FULL)) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Target is busy.
|
** 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)
|
} else if ((cp->host_status == HS_SEL_TIMEOUT)
|
||||||
|| (cp->host_status == HS_TIMEOUT)) {
|
|| (cp->host_status == HS_TIMEOUT)) {
|
||||||
@@ -4986,21 +4991,24 @@ void ncr_complete (struct ncb *np, struct ccb *cp)
|
|||||||
/*
|
/*
|
||||||
** No response
|
** 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) {
|
} else if (cp->host_status == HS_RESET) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** SCSI bus 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) {
|
} else if (cp->host_status == HS_ABORTED) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Transfer 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 {
|
} else {
|
||||||
|
|
||||||
@@ -5010,7 +5018,8 @@ void ncr_complete (struct ncb *np, struct ccb *cp)
|
|||||||
PRINT_ADDR(cmd, "COMMAND FAILED (%x %x) @%p.\n",
|
PRINT_ADDR(cmd, "COMMAND FAILED (%x %x) @%p.\n",
|
||||||
cp->host_status, cp->scsi_status, cp);
|
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) {
|
if (cp->host_status==HS_COMPLETE) {
|
||||||
switch (cp->scsi_status) {
|
switch (cp->scsi_status) {
|
||||||
case S_GOOD:
|
case SAM_STAT_GOOD:
|
||||||
printk (" GOOD");
|
printk (" GOOD");
|
||||||
break;
|
break;
|
||||||
case S_CHECK_COND:
|
case SAM_STAT_CHECK_CONDITION:
|
||||||
printk (" SENSE:");
|
printk (" SENSE:");
|
||||||
p = (u_char*) &cmd->sense_buffer;
|
p = (u_char*) &cmd->sense_buffer;
|
||||||
for (i=0; i<14; i++)
|
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) {
|
switch(s_status) {
|
||||||
default: /* Just for safety, should never happen */
|
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
|
** Decrease number of tags to the number of
|
||||||
** disconnected commands.
|
** 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->phys.header.savep = cp->startp;
|
||||||
cp->host_status = HS_BUSY;
|
cp->host_status = HS_BUSY;
|
||||||
cp->scsi_status = S_ILLEGAL;
|
cp->scsi_status = SAM_STAT_ILLEGAL;
|
||||||
|
|
||||||
ncr_put_start_queue(np, cp);
|
ncr_put_start_queue(np, cp);
|
||||||
if (disc_cnt)
|
if (disc_cnt)
|
||||||
INB (nc_ctest2); /* Clear SIGP */
|
INB (nc_ctest2); /* Clear SIGP */
|
||||||
OUTL_DSP (NCB_SCRIPT_PHYS (np, reselect));
|
OUTL_DSP (NCB_SCRIPT_PHYS (np, reselect));
|
||||||
return;
|
return;
|
||||||
case S_TERMINATED:
|
case SAM_STAT_COMMAND_TERMINATED:
|
||||||
case S_CHECK_COND:
|
case SAM_STAT_CHECK_CONDITION:
|
||||||
/*
|
/*
|
||||||
** If we were requesting sense, give up.
|
** 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->phys.header.wlastp = startp;
|
||||||
|
|
||||||
cp->host_status = HS_BUSY;
|
cp->host_status = HS_BUSY;
|
||||||
cp->scsi_status = S_ILLEGAL;
|
cp->scsi_status = SAM_STAT_ILLEGAL;
|
||||||
cp->auto_sense = s_status;
|
cp->auto_sense = s_status;
|
||||||
|
|
||||||
cp->start.schedule.l_paddr =
|
cp->start.schedule.l_paddr =
|
||||||
@@ -8035,7 +8044,7 @@ printk("ncr53c8xx_queue_command\n");
|
|||||||
spin_lock_irqsave(&np->smp_lock, flags);
|
spin_lock_irqsave(&np->smp_lock, flags);
|
||||||
|
|
||||||
if ((sts = ncr_queue_command(np, cmd)) != DID_OK) {
|
if ((sts = ncr_queue_command(np, cmd)) != DID_OK) {
|
||||||
cmd->result = sts << 16;
|
set_host_byte(cmd, sts);
|
||||||
#ifdef DEBUG_NCR53C8XX
|
#ifdef DEBUG_NCR53C8XX
|
||||||
printk("ncr53c8xx : command not queued - result=%d\n", sts);
|
printk("ncr53c8xx : command not queued - result=%d\n", sts);
|
||||||
#endif
|
#endif
|
||||||
@@ -8226,7 +8235,7 @@ static void process_waiting_list(struct ncb *np, int sts)
|
|||||||
#ifdef DEBUG_WAITING_LIST
|
#ifdef DEBUG_WAITING_LIST
|
||||||
printk("%s: cmd %lx done forced sts=%d\n", ncr_name(np), (u_long) wcmd, sts);
|
printk("%s: cmd %lx done forced sts=%d\n", ncr_name(np), (u_long) wcmd, sts);
|
||||||
#endif
|
#endif
|
||||||
wcmd->result = sts << 16;
|
set_host_byte(wcmd, sts);
|
||||||
ncr_queue_done_cmd(np, wcmd);
|
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
|
* 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;
|
SCpnt->scsi_done = done;
|
||||||
data->CurrentSC = SCpnt;
|
data->CurrentSC = SCpnt;
|
||||||
SCpnt->SCp.Status = CHECK_CONDITION;
|
SCpnt->SCp.Status = SAM_STAT_CHECK_CONDITION;
|
||||||
SCpnt->SCp.Message = 0;
|
SCpnt->SCp.Message = 0;
|
||||||
scsi_set_resid(SCpnt, scsi_bufflen(SCpnt));
|
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;
|
//*sync_neg = SYNC_NOT_YET;
|
||||||
|
|
||||||
/* all command complete and return status */
|
/* 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->result = (DID_OK << 16) |
|
||||||
((tmpSC->SCp.Message & 0xff) << 8) |
|
((tmpSC->SCp.Message & 0xff) << 8) |
|
||||||
((tmpSC->SCp.Status & 0xff) << 0);
|
((tmpSC->SCp.Status & 0xff) << 0);
|
||||||
@@ -1226,9 +1226,9 @@ static irqreturn_t nspintr(int irq, void *dev_id)
|
|||||||
data->Sync[target].SyncOffset = 0;
|
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] = 3; i++;
|
||||||
data->MsgBuffer[i] = MSG_EXT_SDTR; i++;
|
data->MsgBuffer[i] = EXTENDED_SDTR; i++;
|
||||||
data->MsgBuffer[i] = 0x0c; i++;
|
data->MsgBuffer[i] = 0x0c; i++;
|
||||||
data->MsgBuffer[i] = 15; 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);
|
//nsp_dbg(NSP_DEBUG_INTR, "sync target=%d,lun=%d",target,lun);
|
||||||
|
|
||||||
if (data->MsgLen >= 5 &&
|
if (data->MsgLen >= 5 &&
|
||||||
data->MsgBuffer[0] == MSG_EXTENDED &&
|
data->MsgBuffer[0] == EXTENDED_MESSAGE &&
|
||||||
data->MsgBuffer[1] == 3 &&
|
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].SyncPeriod = data->MsgBuffer[3];
|
||||||
data->Sync[target].SyncOffset = data->MsgBuffer[4];
|
data->Sync[target].SyncOffset = data->MsgBuffer[4];
|
||||||
//nsp_dbg(NSP_DEBUG_INTR, "sync ok, %d %d", data->MsgBuffer[3], 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;
|
tmp = -1;
|
||||||
for (i = 0; i < data->MsgLen; i++) {
|
for (i = 0; i < data->MsgLen; i++) {
|
||||||
tmp = data->MsgBuffer[i];
|
tmp = data->MsgBuffer[i];
|
||||||
if (data->MsgBuffer[i] == MSG_EXTENDED) {
|
if (data->MsgBuffer[i] == EXTENDED_MESSAGE) {
|
||||||
i += (1 + data->MsgBuffer[i+1]);
|
i += (1 + data->MsgBuffer[i+1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -370,17 +370,6 @@ enum _burst_mode {
|
|||||||
BURST_MEM32 = 2,
|
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 */
|
/* scatter-gather table */
|
||||||
# define BUFFER_ADDR ((char *)((sg_virt(SCpnt->SCp.buffer))))
|
# 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);
|
complete(pm8001_ha->nvmd_completion);
|
||||||
pm8001_dbg(pm8001_ha, MSG, "Set nvm data complete!\n");
|
pm8001_dbg(pm8001_ha, MSG, "Set nvm data complete!\n");
|
||||||
if ((dlen_status & NVMD_STAT) != 0) {
|
if ((dlen_status & NVMD_STAT) != 0) {
|
||||||
pm8001_dbg(pm8001_ha, FAIL, "Set nvm data error!\n");
|
pm8001_dbg(pm8001_ha, FAIL, "Set nvm data error %x\n",
|
||||||
return;
|
dlen_status);
|
||||||
}
|
}
|
||||||
ccb->task = NULL;
|
ccb->task = NULL;
|
||||||
ccb->ccb_tag = 0xFFFFFFFF;
|
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");
|
pm8001_dbg(pm8001_ha, MSG, "Get nvm data complete!\n");
|
||||||
if ((dlen_status & NVMD_STAT) != 0) {
|
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);
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ir_tds_bn_dps_das_nvm & IPMode) {
|
if (ir_tds_bn_dps_das_nvm & IPMode) {
|
||||||
/* indirect mode - IR bit set */
|
/* indirect mode - IR bit set */
|
||||||
pm8001_dbg(pm8001_ha, MSG, "Get NVMD success, IR=1\n");
|
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);
|
pm8001_dbg(pm8001_ha, MSG, "phy %d byte dmaded.\n", i);
|
||||||
|
|
||||||
sas_phy->frame_rcvd_size = phy->frame_rcvd_size;
|
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 */
|
/* 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);
|
u32 npip_portstate = le32_to_cpu(pPayload->npip_portstate);
|
||||||
u8 portstate = (u8)(npip_portstate & 0x0000000F);
|
u8 portstate = (u8)(npip_portstate & 0x0000000F);
|
||||||
struct pm8001_port *port = &pm8001_ha->port[port_id];
|
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];
|
struct pm8001_phy *phy = &pm8001_ha->phy[phy_id];
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
u8 deviceType = pPayload->sas_identify.dev_type;
|
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)
|
else if (phy->identify.device_type != SAS_PHY_UNUSED)
|
||||||
phy->identify.target_port_protocols = SAS_PROTOCOL_SMP;
|
phy->identify.target_port_protocols = SAS_PROTOCOL_SMP;
|
||||||
phy->sas_phy.oob_mode = SAS_OOB_MODE;
|
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);
|
spin_lock_irqsave(&phy->sas_phy.frame_rcvd_lock, flags);
|
||||||
memcpy(phy->frame_rcvd, &pPayload->sas_identify,
|
memcpy(phy->frame_rcvd, &pPayload->sas_identify,
|
||||||
sizeof(struct sas_identify_frame)-4);
|
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);
|
u32 npip_portstate = le32_to_cpu(pPayload->npip_portstate);
|
||||||
u8 portstate = (u8)(npip_portstate & 0x0000000F);
|
u8 portstate = (u8)(npip_portstate & 0x0000000F);
|
||||||
struct pm8001_port *port = &pm8001_ha->port[port_id];
|
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];
|
struct pm8001_phy *phy = &pm8001_ha->phy[phy_id];
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
pm8001_dbg(pm8001_ha, DEVIO, "HW_EVENT_SATA_PHY_UP port id = %d, phy id = %d\n",
|
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_type |= PORT_TYPE_SATA;
|
||||||
phy->phy_attached = 1;
|
phy->phy_attached = 1;
|
||||||
phy->sas_phy.oob_mode = SATA_OOB_MODE;
|
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);
|
spin_lock_irqsave(&phy->sas_phy.frame_rcvd_lock, flags);
|
||||||
memcpy(phy->frame_rcvd, ((u8 *)&pPayload->sata_fis - 4),
|
memcpy(phy->frame_rcvd, ((u8 *)&pPayload->sata_fis - 4),
|
||||||
sizeof(struct dev_to_host_fis));
|
sizeof(struct dev_to_host_fis));
|
||||||
@@ -3728,11 +3732,13 @@ static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void* piomb)
|
|||||||
break;
|
break;
|
||||||
case HW_EVENT_SATA_SPINUP_HOLD:
|
case HW_EVENT_SATA_SPINUP_HOLD:
|
||||||
pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_SATA_SPINUP_HOLD\n");
|
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;
|
break;
|
||||||
case HW_EVENT_PHY_DOWN:
|
case HW_EVENT_PHY_DOWN:
|
||||||
pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_PHY_DOWN\n");
|
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_attached = 0;
|
||||||
phy->phy_state = 0;
|
phy->phy_state = 0;
|
||||||
hw_event_phy_down(pm8001_ha, piomb);
|
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");
|
pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_PORT_INVALID\n");
|
||||||
sas_phy_disconnected(sas_phy);
|
sas_phy_disconnected(sas_phy);
|
||||||
phy->phy_attached = 0;
|
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;
|
break;
|
||||||
/* the broadcast change primitive received, tell the LIBSAS this event
|
/* the broadcast change primitive received, tell the LIBSAS this event
|
||||||
to revalidate the sas domain*/
|
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);
|
spin_lock_irqsave(&sas_phy->sas_prim_lock, flags);
|
||||||
sas_phy->sas_prim = HW_EVENT_BROADCAST_CHANGE;
|
sas_phy->sas_prim = HW_EVENT_BROADCAST_CHANGE;
|
||||||
spin_unlock_irqrestore(&sas_phy->sas_prim_lock, flags);
|
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;
|
break;
|
||||||
case HW_EVENT_PHY_ERROR:
|
case HW_EVENT_PHY_ERROR:
|
||||||
pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_PHY_ERROR\n");
|
pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_PHY_ERROR\n");
|
||||||
sas_phy_disconnected(&phy->sas_phy);
|
sas_phy_disconnected(&phy->sas_phy);
|
||||||
phy->phy_attached = 0;
|
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;
|
break;
|
||||||
case HW_EVENT_BROADCAST_EXP:
|
case HW_EVENT_BROADCAST_EXP:
|
||||||
pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_BROADCAST_EXP\n");
|
pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_BROADCAST_EXP\n");
|
||||||
spin_lock_irqsave(&sas_phy->sas_prim_lock, flags);
|
spin_lock_irqsave(&sas_phy->sas_prim_lock, flags);
|
||||||
sas_phy->sas_prim = HW_EVENT_BROADCAST_EXP;
|
sas_phy->sas_prim = HW_EVENT_BROADCAST_EXP;
|
||||||
spin_unlock_irqrestore(&sas_phy->sas_prim_lock, flags);
|
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;
|
break;
|
||||||
case HW_EVENT_LINK_ERR_INVALID_DWORD:
|
case HW_EVENT_LINK_ERR_INVALID_DWORD:
|
||||||
pm8001_dbg(pm8001_ha, MSG,
|
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);
|
HW_EVENT_LINK_ERR_INVALID_DWORD, port_id, phy_id, 0, 0);
|
||||||
sas_phy_disconnected(sas_phy);
|
sas_phy_disconnected(sas_phy);
|
||||||
phy->phy_attached = 0;
|
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;
|
break;
|
||||||
case HW_EVENT_LINK_ERR_DISPARITY_ERROR:
|
case HW_EVENT_LINK_ERR_DISPARITY_ERROR:
|
||||||
pm8001_dbg(pm8001_ha, MSG,
|
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);
|
port_id, phy_id, 0, 0);
|
||||||
sas_phy_disconnected(sas_phy);
|
sas_phy_disconnected(sas_phy);
|
||||||
phy->phy_attached = 0;
|
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;
|
break;
|
||||||
case HW_EVENT_LINK_ERR_CODE_VIOLATION:
|
case HW_EVENT_LINK_ERR_CODE_VIOLATION:
|
||||||
pm8001_dbg(pm8001_ha, MSG,
|
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);
|
port_id, phy_id, 0, 0);
|
||||||
sas_phy_disconnected(sas_phy);
|
sas_phy_disconnected(sas_phy);
|
||||||
phy->phy_attached = 0;
|
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;
|
break;
|
||||||
case HW_EVENT_LINK_ERR_LOSS_OF_DWORD_SYNCH:
|
case HW_EVENT_LINK_ERR_LOSS_OF_DWORD_SYNCH:
|
||||||
pm8001_dbg(pm8001_ha, MSG,
|
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);
|
port_id, phy_id, 0, 0);
|
||||||
sas_phy_disconnected(sas_phy);
|
sas_phy_disconnected(sas_phy);
|
||||||
phy->phy_attached = 0;
|
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;
|
break;
|
||||||
case HW_EVENT_MALFUNCTION:
|
case HW_EVENT_MALFUNCTION:
|
||||||
pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_MALFUNCTION\n");
|
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);
|
spin_lock_irqsave(&sas_phy->sas_prim_lock, flags);
|
||||||
sas_phy->sas_prim = HW_EVENT_BROADCAST_SES;
|
sas_phy->sas_prim = HW_EVENT_BROADCAST_SES;
|
||||||
spin_unlock_irqrestore(&sas_phy->sas_prim_lock, flags);
|
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;
|
break;
|
||||||
case HW_EVENT_INBOUND_CRC_ERROR:
|
case HW_EVENT_INBOUND_CRC_ERROR:
|
||||||
pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_INBOUND_CRC_ERROR\n");
|
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;
|
break;
|
||||||
case HW_EVENT_HARD_RESET_RECEIVED:
|
case HW_EVENT_HARD_RESET_RECEIVED:
|
||||||
pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_HARD_RESET_RECEIVED\n");
|
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;
|
break;
|
||||||
case HW_EVENT_ID_FRAME_TIMEOUT:
|
case HW_EVENT_ID_FRAME_TIMEOUT:
|
||||||
pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_ID_FRAME_TIMEOUT\n");
|
pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_ID_FRAME_TIMEOUT\n");
|
||||||
sas_phy_disconnected(sas_phy);
|
sas_phy_disconnected(sas_phy);
|
||||||
phy->phy_attached = 0;
|
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;
|
break;
|
||||||
case HW_EVENT_LINK_ERR_PHY_RESET_FAILED:
|
case HW_EVENT_LINK_ERR_PHY_RESET_FAILED:
|
||||||
pm8001_dbg(pm8001_ha, MSG,
|
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);
|
port_id, phy_id, 0, 0);
|
||||||
sas_phy_disconnected(sas_phy);
|
sas_phy_disconnected(sas_phy);
|
||||||
phy->phy_attached = 0;
|
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;
|
break;
|
||||||
case HW_EVENT_PORT_RESET_TIMER_TMO:
|
case HW_EVENT_PORT_RESET_TIMER_TMO:
|
||||||
pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_PORT_RESET_TIMER_TMO\n");
|
pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_PORT_RESET_TIMER_TMO\n");
|
||||||
sas_phy_disconnected(sas_phy);
|
sas_phy_disconnected(sas_phy);
|
||||||
phy->phy_attached = 0;
|
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;
|
break;
|
||||||
case HW_EVENT_PORT_RECOVERY_TIMER_TMO:
|
case HW_EVENT_PORT_RECOVERY_TIMER_TMO:
|
||||||
pm8001_dbg(pm8001_ha, MSG,
|
pm8001_dbg(pm8001_ha, MSG,
|
||||||
"HW_EVENT_PORT_RECOVERY_TIMER_TMO\n");
|
"HW_EVENT_PORT_RECOVERY_TIMER_TMO\n");
|
||||||
sas_phy_disconnected(sas_phy);
|
sas_phy_disconnected(sas_phy);
|
||||||
phy->phy_attached = 0;
|
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;
|
break;
|
||||||
case HW_EVENT_PORT_RECOVER:
|
case HW_EVENT_PORT_RECOVER:
|
||||||
pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_PORT_RECOVER\n");
|
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,
|
.fw_flash_update_req = pm8001_chip_fw_flash_update_req,
|
||||||
.set_dev_state_req = pm8001_chip_set_dev_state_req,
|
.set_dev_state_req = pm8001_chip_set_dev_state_req,
|
||||||
.sas_re_init_req = pm8001_chip_sas_re_initialization,
|
.sas_re_init_req = pm8001_chip_sas_re_initialization,
|
||||||
|
.fatal_errors = pm80xx_fatal_errors,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -423,7 +423,7 @@ err_out_shost:
|
|||||||
err_out_nodev:
|
err_out_nodev:
|
||||||
for (i = 0; i < pm8001_ha->max_memcnt; i++) {
|
for (i = 0; i < pm8001_ha->max_memcnt; i++) {
|
||||||
if (pm8001_ha->memoryMap.region[i].virt_ptr != NULL) {
|
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].total_len +
|
||||||
pm8001_ha->memoryMap.region[i].alignment),
|
pm8001_ha->memoryMap.region[i].alignment),
|
||||||
pm8001_ha->memoryMap.region[i].virt_ptr,
|
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 =
|
pm8001_ha->io_mem[logicalBar].memvirtaddr =
|
||||||
ioremap(pm8001_ha->io_mem[logicalBar].membase,
|
ioremap(pm8001_ha->io_mem[logicalBar].membase,
|
||||||
pm8001_ha->io_mem[logicalBar].memsize);
|
pm8001_ha->io_mem[logicalBar].memsize);
|
||||||
|
if (!pm8001_ha->io_mem[logicalBar].memvirtaddr) {
|
||||||
pm8001_dbg(pm8001_ha, INIT,
|
pm8001_dbg(pm8001_ha, INIT,
|
||||||
"PCI: bar %d, logicalBar %d\n",
|
"Failed to ioremap bar %d, logicalBar %d",
|
||||||
bar, logicalBar);
|
bar, logicalBar);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
pm8001_dbg(pm8001_ha, INIT,
|
pm8001_dbg(pm8001_ha, INIT,
|
||||||
"base addr %llx virt_addr=%llx len=%d\n",
|
"base addr %llx virt_addr=%llx len=%d\n",
|
||||||
(u64)pm8001_ha->io_mem[logicalBar].membase,
|
(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,
|
tasklet_init(&pm8001_ha->tasklet[j], pm8001_tasklet,
|
||||||
(unsigned long)&(pm8001_ha->irq_vector[j]));
|
(unsigned long)&(pm8001_ha->irq_vector[j]));
|
||||||
#endif
|
#endif
|
||||||
pm8001_ioremap(pm8001_ha);
|
if (pm8001_ioremap(pm8001_ha))
|
||||||
|
goto failed_pci_alloc;
|
||||||
if (!pm8001_alloc(pm8001_ha, ent))
|
if (!pm8001_alloc(pm8001_ha, ent))
|
||||||
return pm8001_ha;
|
return pm8001_ha;
|
||||||
|
failed_pci_alloc:
|
||||||
pm8001_free(pm8001_ha);
|
pm8001_free(pm8001_ha);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -1192,12 +1197,13 @@ pm8001_init_ccb_tag(struct pm8001_hba_info *pm8001_ha, struct Scsi_Host *shost,
|
|||||||
goto err_out_noccb;
|
goto err_out_noccb;
|
||||||
}
|
}
|
||||||
for (i = 0; i < ccb_count; i++) {
|
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,
|
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) {
|
if (!pm8001_ha->ccb_info[i].buf_prd) {
|
||||||
pm8001_dbg(pm8001_ha, FAIL,
|
pm8001_dbg(pm8001_ha, FAIL,
|
||||||
"pm80xx: ccb prd memory allocation error\n");
|
"ccb prd memory allocation error\n");
|
||||||
goto err_out;
|
goto err_out;
|
||||||
}
|
}
|
||||||
pm8001_ha->ccb_info[i].task = NULL;
|
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;
|
int rc = 0, phy_id = sas_phy->id;
|
||||||
struct pm8001_hba_info *pm8001_ha = NULL;
|
struct pm8001_hba_info *pm8001_ha = NULL;
|
||||||
struct sas_phy_linkrates *rates;
|
struct sas_phy_linkrates *rates;
|
||||||
struct sas_ha_struct *sas_ha;
|
|
||||||
struct pm8001_phy *phy;
|
struct pm8001_phy *phy;
|
||||||
DECLARE_COMPLETION_ONSTACK(completion);
|
DECLARE_COMPLETION_ONSTACK(completion);
|
||||||
unsigned long flags;
|
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->chip_id != chip_8001) {
|
||||||
if (pm8001_ha->phy[phy_id].phy_state ==
|
if (pm8001_ha->phy[phy_id].phy_state ==
|
||||||
PHY_STATE_LINK_UP_SPCV) {
|
PHY_STATE_LINK_UP_SPCV) {
|
||||||
sas_ha = pm8001_ha->sas;
|
|
||||||
sas_phy_disconnected(&phy->sas_phy);
|
sas_phy_disconnected(&phy->sas_phy);
|
||||||
sas_ha->notify_phy_event(&phy->sas_phy,
|
sas_notify_phy_event(&phy->sas_phy,
|
||||||
PHYE_LOSS_OF_SIGNAL);
|
PHYE_LOSS_OF_SIGNAL, GFP_KERNEL);
|
||||||
phy->phy_attached = 0;
|
phy->phy_attached = 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (pm8001_ha->phy[phy_id].phy_state ==
|
if (pm8001_ha->phy[phy_id].phy_state ==
|
||||||
PHY_STATE_LINK_UP_SPC) {
|
PHY_STATE_LINK_UP_SPC) {
|
||||||
sas_ha = pm8001_ha->sas;
|
|
||||||
sas_phy_disconnected(&phy->sas_phy);
|
sas_phy_disconnected(&phy->sas_phy);
|
||||||
sas_ha->notify_phy_event(&phy->sas_phy,
|
sas_notify_phy_event(&phy->sas_phy,
|
||||||
PHYE_LOSS_OF_SIGNAL);
|
PHYE_LOSS_OF_SIGNAL, GFP_KERNEL);
|
||||||
phy->phy_attached = 0;
|
phy->phy_attached = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1183,12 +1180,21 @@ int pm8001_abort_task(struct sas_task *task)
|
|||||||
int rc = TMF_RESP_FUNC_FAILED, ret;
|
int rc = TMF_RESP_FUNC_FAILED, ret;
|
||||||
u32 phy_id;
|
u32 phy_id;
|
||||||
struct sas_task_slow slow_task;
|
struct sas_task_slow slow_task;
|
||||||
|
|
||||||
if (unlikely(!task || !task->lldd_task || !task->dev))
|
if (unlikely(!task || !task->lldd_task || !task->dev))
|
||||||
return TMF_RESP_FUNC_FAILED;
|
return TMF_RESP_FUNC_FAILED;
|
||||||
|
|
||||||
dev = task->dev;
|
dev = task->dev;
|
||||||
pm8001_dev = dev->lldd_dev;
|
pm8001_dev = dev->lldd_dev;
|
||||||
pm8001_ha = pm8001_find_ha_by_dev(dev);
|
pm8001_ha = pm8001_find_ha_by_dev(dev);
|
||||||
phy_id = pm8001_dev->attached_phy;
|
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);
|
ret = pm8001_find_tag(task, &tag);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
pm8001_info(pm8001_ha, "no tag for task:%p\n", task);
|
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;
|
tmf_task.tmf = TMF_CLEAR_TASK_SET;
|
||||||
return pm8001_issue_ssp_tmf(dev, lun, &tmf_task);
|
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,
|
int (*sas_diag_execute_req)(struct pm8001_hba_info *pm8001_ha,
|
||||||
u32 state);
|
u32 state);
|
||||||
int (*sas_re_init_req)(struct pm8001_hba_info *pm8001_ha);
|
int (*sas_re_init_req)(struct pm8001_hba_info *pm8001_ha);
|
||||||
|
int (*fatal_errors)(struct pm8001_hba_info *pm8001_ha);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct pm8001_chip_info {
|
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,
|
ssize_t pm80xx_get_non_fatal_dump(struct device *cdev,
|
||||||
struct device_attribute *attr, char *buf);
|
struct device_attribute *attr, char *buf);
|
||||||
ssize_t pm8001_get_gsm_dump(struct device *cdev, u32, 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 */
|
/* ctl shared API */
|
||||||
extern struct device_attribute *pm8001_host_attrs[];
|
extern struct device_attribute *pm8001_host_attrs[];
|
||||||
|
|
||||||
|
|||||||
@@ -349,6 +349,11 @@ moreData:
|
|||||||
sprintf(
|
sprintf(
|
||||||
pm8001_ha->forensic_info.data_buf.direct_data,
|
pm8001_ha->forensic_info.data_buf.direct_data,
|
||||||
"%08x ", 0xFFFFFFFF);
|
"%08x ", 0xFFFFFFFF);
|
||||||
|
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,
|
pm8001_cw32(pm8001_ha, 0,
|
||||||
MEMBASE_II_SHIFT_REGISTER,
|
MEMBASE_II_SHIFT_REGISTER,
|
||||||
pm8001_ha->fatal_forensic_shift_offset);
|
pm8001_ha->fatal_forensic_shift_offset);
|
||||||
@@ -362,24 +367,19 @@ moreData:
|
|||||||
goto moreData;
|
goto moreData;
|
||||||
} else {
|
} else {
|
||||||
pm8001_ha->forensic_info.data_buf.direct_data +=
|
pm8001_ha->forensic_info.data_buf.direct_data +=
|
||||||
sprintf(
|
sprintf(pm8001_ha->forensic_info.data_buf.direct_data,
|
||||||
pm8001_ha->forensic_info.data_buf.direct_data,
|
|
||||||
"%08x ", 4);
|
"%08x ", 4);
|
||||||
pm8001_ha->forensic_info.data_buf.read_len
|
pm8001_ha->forensic_info.data_buf.read_len = 0xFFFFFFFF;
|
||||||
= 0xFFFFFFFF;
|
pm8001_ha->forensic_info.data_buf.direct_len = 0;
|
||||||
pm8001_ha->forensic_info.data_buf.direct_len
|
pm8001_ha->forensic_info.data_buf.direct_offset = 0;
|
||||||
= 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 = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
offset = (int)((char *)pm8001_ha->forensic_info.data_buf.direct_data
|
offset = (int)((char *)pm8001_ha->forensic_info.data_buf.direct_data
|
||||||
- (char *)buf);
|
- (char *)buf);
|
||||||
pm8001_dbg(pm8001_ha, IO, "get_fatal_spcv: return4 0x%x\n", offset);
|
pm8001_dbg(pm8001_ha, IO, "get_fatal_spcv: return4 0x%x\n", offset);
|
||||||
return (char *)pm8001_ha->forensic_info.data_buf.direct_data -
|
return ((char *)pm8001_ha->forensic_info.data_buf.direct_data -
|
||||||
(char *)buf;
|
(char *)buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* pm80xx_get_non_fatal_dump - dump the nonfatal data from the dma
|
/* 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;
|
max_wait_count = SPC_DOORBELL_CLEAR_TIMEOUT;
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
udelay(1);
|
msleep(FW_READY_INTERVAL);
|
||||||
value = pm8001_cr32(pm8001_ha, 0, MSGU_IBDB_SET);
|
value = pm8001_cr32(pm8001_ha, 0, MSGU_IBDB_SET);
|
||||||
value &= SPCv_MSGU_CFG_TABLE_UPDATE;
|
value &= SPCv_MSGU_CFG_TABLE_UPDATE;
|
||||||
} while ((value != 0) && (--max_wait_count));
|
} while ((value != 0) && (--max_wait_count));
|
||||||
@@ -1010,9 +1010,9 @@ static int mpi_init_check(struct pm8001_hba_info *pm8001_ha)
|
|||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
/* check the MPI-State for initialization upto 100ms*/
|
/* check the MPI-State for initialization upto 100ms*/
|
||||||
max_wait_count = 100 * 1000;/* 100 msec */
|
max_wait_count = 5;/* 100 msec */
|
||||||
do {
|
do {
|
||||||
udelay(1);
|
msleep(FW_READY_INTERVAL);
|
||||||
gst_len_mpistate =
|
gst_len_mpistate =
|
||||||
pm8001_mr32(pm8001_ha->general_stat_tbl_addr,
|
pm8001_mr32(pm8001_ha->general_stat_tbl_addr,
|
||||||
GST_GSTLEN_MPIS_OFFSET);
|
GST_GSTLEN_MPIS_OFFSET);
|
||||||
@@ -1039,6 +1039,7 @@ static int check_fw_ready(struct pm8001_hba_info *pm8001_ha)
|
|||||||
u32 value;
|
u32 value;
|
||||||
u32 max_wait_count;
|
u32 max_wait_count;
|
||||||
u32 max_wait_time;
|
u32 max_wait_time;
|
||||||
|
u32 expected_mask;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
/* reset / PCIe ready */
|
/* 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);
|
value = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_1);
|
||||||
} while ((value == 0xFFFFFFFF) && (--max_wait_count));
|
} while ((value == 0xFFFFFFFF) && (--max_wait_count));
|
||||||
|
|
||||||
/* check ila status */
|
/* check ila, RAAE and iops 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 */
|
|
||||||
if ((pm8001_ha->chip_id != chip_8008) &&
|
if ((pm8001_ha->chip_id != chip_8008) &&
|
||||||
(pm8001_ha->chip_id != chip_8009)) {
|
(pm8001_ha->chip_id != chip_8009)) {
|
||||||
/* 200 milli sec */
|
max_wait_time = max_wait_count = 180; /* 3600 milli sec */
|
||||||
max_wait_time = max_wait_count = 10;
|
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 {
|
do {
|
||||||
msleep(FW_READY_INTERVAL);
|
msleep(FW_READY_INTERVAL);
|
||||||
value = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_1);
|
value = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_1);
|
||||||
} while (((value & SCRATCH_PAD_IOP1_READY) !=
|
} while (((value & expected_mask) !=
|
||||||
SCRATCH_PAD_IOP1_READY) && (--max_wait_count));
|
expected_mask) && (--max_wait_count));
|
||||||
if (!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;
|
ret = -1;
|
||||||
else {
|
} else {
|
||||||
pm8001_dbg(pm8001_ha, MSG,
|
pm8001_dbg(pm8001_ha, MSG,
|
||||||
"iop1 ready status in %d millisec\n",
|
"All FW components ready by %d ms\n",
|
||||||
(max_wait_time - max_wait_count));
|
(max_wait_time - max_wait_count) * FW_READY_INTERVAL);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
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;
|
void __iomem *base_addr;
|
||||||
u32 value;
|
u32 value;
|
||||||
@@ -1124,15 +1090,48 @@ static void init_pci_device_addresses(struct pm8001_hba_info *pm8001_ha)
|
|||||||
u32 pcilogic;
|
u32 pcilogic;
|
||||||
|
|
||||||
value = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_0);
|
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 */
|
offset = value & 0x03FFFFFF; /* scratch pad 0 TBL address */
|
||||||
|
|
||||||
pm8001_dbg(pm8001_ha, DEV, "Scratchpad 0 Offset: 0x%x value 0x%x\n",
|
pm8001_dbg(pm8001_ha, DEV, "Scratchpad 0 Offset: 0x%x value 0x%x\n",
|
||||||
offset, value);
|
offset, value);
|
||||||
|
/**
|
||||||
|
* Upper 6 bits describe the offset within PCI config space where BAR
|
||||||
|
* is located.
|
||||||
|
*/
|
||||||
pcilogic = (value & 0xFC000000) >> 26;
|
pcilogic = (value & 0xFC000000) >> 26;
|
||||||
pcibar = get_pci_bar_index(pcilogic);
|
pcibar = get_pci_bar_index(pcilogic);
|
||||||
pm8001_dbg(pm8001_ha, INIT, "Scratchpad 0 PCI BAR: %d\n", pcibar);
|
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->main_cfg_tbl_addr = base_addr =
|
||||||
pm8001_ha->io_mem[pcibar].memvirtaddr + offset;
|
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 =
|
pm8001_ha->general_stat_tbl_addr =
|
||||||
base_addr + (pm8001_cr32(pm8001_ha, pcibar, offset + 0x18) &
|
base_addr + (pm8001_cr32(pm8001_ha, pcibar, offset + 0x18) &
|
||||||
0xFFFFFF);
|
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_dbg(pm8001_ha, INIT, "addr - pspa %p ivt %p\n",
|
||||||
pm8001_ha->pspa_q_tbl_addr,
|
pm8001_ha->pspa_q_tbl_addr,
|
||||||
pm8001_ha->ivt_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;
|
pm8001_ha->controller_fatal_error = false;
|
||||||
|
|
||||||
/* Initialize pci space address eg: mpi offset */
|
/* 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);
|
init_default_table_values(pm8001_ha);
|
||||||
read_main_config_table(pm8001_ha);
|
read_main_config_table(pm8001_ha);
|
||||||
read_general_status_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 max_wait_count;
|
||||||
u32 value;
|
u32 value;
|
||||||
u32 gst_len_mpistate;
|
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
|
/* Write bit1=1 to Inbound DoorBell Register to tell the SPC FW the
|
||||||
table is stop */
|
table is stop */
|
||||||
pm8001_cw32(pm8001_ha, 0, MSGU_IBDB_SET, SPCv_MSGU_CFG_TABLE_RESET);
|
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;
|
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
|
* pm8001_chip_soft_rst - soft reset the PM8001 chip, so that the clear all
|
||||||
* the FW register status to the originated status.
|
* the FW register status to the originated status.
|
||||||
@@ -2385,10 +2433,11 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unlikely(status))
|
if (status != IO_SUCCESS) {
|
||||||
pm8001_dbg(pm8001_ha, IOERR,
|
pm8001_dbg(pm8001_ha, FAIL,
|
||||||
"status:0x%x, tag:0x%x, task::0x%p\n",
|
"IO failed device_id %u status 0x%x tag %d\n",
|
||||||
status, tag, t);
|
pm8001_dev->device_id, status, tag);
|
||||||
|
}
|
||||||
|
|
||||||
/* Print sas address of IO failed device */
|
/* Print sas address of IO failed device */
|
||||||
if ((status != IO_SUCCESS) && (status != IO_OVERFLOW) &&
|
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);
|
atomic_dec(&pm8001_dev->running_req);
|
||||||
break;
|
break;
|
||||||
default:
|
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 */
|
/* not allowed case. Therefore, return failed status */
|
||||||
ts->resp = SAS_TASK_COMPLETE;
|
ts->resp = SAS_TASK_COMPLETE;
|
||||||
ts->stat = SAS_DEV_NO_RESPONSE;
|
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);
|
u8 portstate = (u8)(phyid_npip_portstate & 0x0000000F);
|
||||||
|
|
||||||
struct pm8001_port *port = &pm8001_ha->port[port_id];
|
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];
|
struct pm8001_phy *phy = &pm8001_ha->phy[phy_id];
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
u8 deviceType = pPayload->sas_identify.dev_type;
|
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)
|
else if (phy->identify.device_type != SAS_PHY_UNUSED)
|
||||||
phy->identify.target_port_protocols = SAS_PROTOCOL_SMP;
|
phy->identify.target_port_protocols = SAS_PROTOCOL_SMP;
|
||||||
phy->sas_phy.oob_mode = SAS_OOB_MODE;
|
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);
|
spin_lock_irqsave(&phy->sas_phy.frame_rcvd_lock, flags);
|
||||||
memcpy(phy->frame_rcvd, &pPayload->sas_identify,
|
memcpy(phy->frame_rcvd, &pPayload->sas_identify,
|
||||||
sizeof(struct sas_identify_frame)-4);
|
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);
|
u8 portstate = (u8)(phyid_npip_portstate & 0x0000000F);
|
||||||
|
|
||||||
struct pm8001_port *port = &pm8001_ha->port[port_id];
|
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];
|
struct pm8001_phy *phy = &pm8001_ha->phy[phy_id];
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
pm8001_dbg(pm8001_ha, DEVIO,
|
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_type |= PORT_TYPE_SATA;
|
||||||
phy->phy_attached = 1;
|
phy->phy_attached = 1;
|
||||||
phy->sas_phy.oob_mode = SATA_OOB_MODE;
|
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);
|
spin_lock_irqsave(&phy->sas_phy.frame_rcvd_lock, flags);
|
||||||
memcpy(phy->frame_rcvd, ((u8 *)&pPayload->sata_fis - 4),
|
memcpy(phy->frame_rcvd, ((u8 *)&pPayload->sata_fis - 4),
|
||||||
sizeof(struct dev_to_host_fis));
|
sizeof(struct dev_to_host_fis));
|
||||||
@@ -3418,11 +3467,9 @@ hw_event_phy_down(struct pm8001_hba_info *pm8001_ha, void *piomb)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
if (port_sata && (portstate != PORT_IN_RESET)) {
|
if (port_sata && (portstate != PORT_IN_RESET))
|
||||||
struct sas_ha_struct *sas_ha = pm8001_ha->sas;
|
sas_notify_phy_event(&phy->sas_phy, PHYE_LOSS_OF_SIGNAL,
|
||||||
|
GFP_ATOMIC);
|
||||||
sas_ha->notify_phy_event(&phy->sas_phy, PHYE_LOSS_OF_SIGNAL);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mpi_phy_start_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
|
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;
|
break;
|
||||||
case HW_EVENT_SATA_SPINUP_HOLD:
|
case HW_EVENT_SATA_SPINUP_HOLD:
|
||||||
pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_SATA_SPINUP_HOLD\n");
|
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;
|
break;
|
||||||
case HW_EVENT_PHY_DOWN:
|
case HW_EVENT_PHY_DOWN:
|
||||||
pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_PHY_DOWN\n");
|
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");
|
pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_PORT_INVALID\n");
|
||||||
sas_phy_disconnected(sas_phy);
|
sas_phy_disconnected(sas_phy);
|
||||||
phy->phy_attached = 0;
|
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;
|
break;
|
||||||
/* the broadcast change primitive received, tell the LIBSAS this event
|
/* the broadcast change primitive received, tell the LIBSAS this event
|
||||||
to revalidate the sas domain*/
|
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);
|
spin_lock_irqsave(&sas_phy->sas_prim_lock, flags);
|
||||||
sas_phy->sas_prim = HW_EVENT_BROADCAST_CHANGE;
|
sas_phy->sas_prim = HW_EVENT_BROADCAST_CHANGE;
|
||||||
spin_unlock_irqrestore(&sas_phy->sas_prim_lock, flags);
|
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;
|
break;
|
||||||
case HW_EVENT_PHY_ERROR:
|
case HW_EVENT_PHY_ERROR:
|
||||||
pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_PHY_ERROR\n");
|
pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_PHY_ERROR\n");
|
||||||
sas_phy_disconnected(&phy->sas_phy);
|
sas_phy_disconnected(&phy->sas_phy);
|
||||||
phy->phy_attached = 0;
|
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;
|
break;
|
||||||
case HW_EVENT_BROADCAST_EXP:
|
case HW_EVENT_BROADCAST_EXP:
|
||||||
pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_BROADCAST_EXP\n");
|
pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_BROADCAST_EXP\n");
|
||||||
spin_lock_irqsave(&sas_phy->sas_prim_lock, flags);
|
spin_lock_irqsave(&sas_phy->sas_prim_lock, flags);
|
||||||
sas_phy->sas_prim = HW_EVENT_BROADCAST_EXP;
|
sas_phy->sas_prim = HW_EVENT_BROADCAST_EXP;
|
||||||
spin_unlock_irqrestore(&sas_phy->sas_prim_lock, flags);
|
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;
|
break;
|
||||||
case HW_EVENT_LINK_ERR_INVALID_DWORD:
|
case HW_EVENT_LINK_ERR_INVALID_DWORD:
|
||||||
pm8001_dbg(pm8001_ha, MSG,
|
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);
|
spin_lock_irqsave(&sas_phy->sas_prim_lock, flags);
|
||||||
sas_phy->sas_prim = HW_EVENT_BROADCAST_SES;
|
sas_phy->sas_prim = HW_EVENT_BROADCAST_SES;
|
||||||
spin_unlock_irqrestore(&sas_phy->sas_prim_lock, flags);
|
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;
|
break;
|
||||||
case HW_EVENT_INBOUND_CRC_ERROR:
|
case HW_EVENT_INBOUND_CRC_ERROR:
|
||||||
pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_INBOUND_CRC_ERROR\n");
|
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;
|
break;
|
||||||
case HW_EVENT_HARD_RESET_RECEIVED:
|
case HW_EVENT_HARD_RESET_RECEIVED:
|
||||||
pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_HARD_RESET_RECEIVED\n");
|
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;
|
break;
|
||||||
case HW_EVENT_ID_FRAME_TIMEOUT:
|
case HW_EVENT_ID_FRAME_TIMEOUT:
|
||||||
pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_ID_FRAME_TIMEOUT\n");
|
pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_ID_FRAME_TIMEOUT\n");
|
||||||
sas_phy_disconnected(sas_phy);
|
sas_phy_disconnected(sas_phy);
|
||||||
phy->phy_attached = 0;
|
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;
|
break;
|
||||||
case HW_EVENT_LINK_ERR_PHY_RESET_FAILED:
|
case HW_EVENT_LINK_ERR_PHY_RESET_FAILED:
|
||||||
pm8001_dbg(pm8001_ha, MSG,
|
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);
|
port_id, phy_id, 0, 0);
|
||||||
sas_phy_disconnected(sas_phy);
|
sas_phy_disconnected(sas_phy);
|
||||||
phy->phy_attached = 0;
|
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;
|
break;
|
||||||
case HW_EVENT_PORT_RESET_TIMER_TMO:
|
case HW_EVENT_PORT_RESET_TIMER_TMO:
|
||||||
pm8001_dbg(pm8001_ha, MSG, "HW_EVENT_PORT_RESET_TIMER_TMO\n");
|
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);
|
port_id, phy_id, 0, 0);
|
||||||
sas_phy_disconnected(sas_phy);
|
sas_phy_disconnected(sas_phy);
|
||||||
phy->phy_attached = 0;
|
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) {
|
if (pm8001_ha->phy[phy_id].reset_completion) {
|
||||||
pm8001_ha->phy[phy_id].port_reset_status =
|
pm8001_ha->phy[phy_id].port_reset_status =
|
||||||
PORT_RESET_TMO;
|
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++) {
|
for (i = 0; i < pm8001_ha->chip->n_phy; i++) {
|
||||||
if (port->wide_port_phymap & (1 << i)) {
|
if (port->wide_port_phymap & (1 << i)) {
|
||||||
phy = &pm8001_ha->phy[i];
|
phy = &pm8001_ha->phy[i];
|
||||||
sas_ha->notify_phy_event(&phy->sas_phy,
|
sas_notify_phy_event(&phy->sas_phy,
|
||||||
PHYE_LOSS_OF_SIGNAL);
|
PHYE_LOSS_OF_SIGNAL, GFP_ATOMIC);
|
||||||
port->wide_port_phymap &= ~(1 << i);
|
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,
|
.set_nvmd_req = pm8001_chip_set_nvmd_req,
|
||||||
.fw_flash_update_req = pm8001_chip_fw_flash_update_req,
|
.fw_flash_update_req = pm8001_chip_fw_flash_update_req,
|
||||||
.set_dev_state_req = pm8001_chip_set_dev_state_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_DOPNRJT_RTRY_TMO 128
|
||||||
#define SAS_COPNRJT_RTRY_TMO 128
|
#define SAS_COPNRJT_RTRY_TMO 128
|
||||||
|
|
||||||
#define SPCV_DOORBELL_CLEAR_TIMEOUT (30 * 1000 * 1000) /* 30 sec */
|
#define SPCV_DOORBELL_CLEAR_TIMEOUT (30 * 50) /* 30 sec */
|
||||||
#define SPC_DOORBELL_CLEAR_TIMEOUT (15 * 1000 * 1000) /* 15 sec */
|
#define SPC_DOORBELL_CLEAR_TIMEOUT (15 * 50) /* 15 sec */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Making ORR bigger than IT NEXUS LOSS which is 2000000us = 2 second.
|
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_6 0x6C
|
||||||
#define MSGU_HOST_SCRATCH_PAD_7 0x70
|
#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 */
|
/* bit definition for ODMR register */
|
||||||
#define ODMR_MASK_ALL 0xFFFFFFFF/* mask all
|
#define ODMR_MASK_ALL 0xFFFFFFFF/* mask all
|
||||||
interrupt vector */
|
interrupt vector */
|
||||||
|
|||||||
@@ -3713,7 +3713,7 @@ static void __qedf_remove(struct pci_dev *pdev, int mode)
|
|||||||
else
|
else
|
||||||
fc_fabric_logoff(qedf->lport);
|
fc_fabric_logoff(qedf->lport);
|
||||||
|
|
||||||
if (qedf_wait_for_upload(qedf) == false)
|
if (!qedf_wait_for_upload(qedf))
|
||||||
QEDF_ERR(&qedf->dbg_ctx, "Could not upload all sessions.\n");
|
QEDF_ERR(&qedf->dbg_ctx, "Could not upload all sessions.\n");
|
||||||
|
|
||||||
#ifdef CONFIG_DEBUG_FS
|
#ifdef CONFIG_DEBUG_FS
|
||||||
|
|||||||
@@ -3906,18 +3906,18 @@ qla1280_get_target_parameters(struct scsi_qla_host *ha,
|
|||||||
printk(KERN_INFO "scsi(%li:%d:%d:%d):", ha->host_no, bus, target, lun);
|
printk(KERN_INFO "scsi(%li:%d:%d:%d):", ha->host_no, bus, target, lun);
|
||||||
|
|
||||||
if (mb[3] != 0) {
|
if (mb[3] != 0) {
|
||||||
printk(" Sync: period %d, offset %d",
|
printk(KERN_CONT " Sync: period %d, offset %d",
|
||||||
(mb[3] & 0xff), (mb[3] >> 8));
|
(mb[3] & 0xff), (mb[3] >> 8));
|
||||||
if (mb[2] & BIT_13)
|
if (mb[2] & BIT_13)
|
||||||
printk(", Wide");
|
printk(KERN_CONT ", Wide");
|
||||||
if ((mb[2] & BIT_5) && ((mb[6] >> 8) & 0xff) >= 2)
|
if ((mb[2] & BIT_5) && ((mb[6] >> 8) & 0xff) >= 2)
|
||||||
printk(", DT");
|
printk(KERN_CONT ", DT");
|
||||||
} else
|
} else
|
||||||
printk(" Async");
|
printk(KERN_CONT " Async");
|
||||||
|
|
||||||
if (device->simple_tags)
|
if (device->simple_tags)
|
||||||
printk(", Tagged queuing: depth %d", device->queue_depth);
|
printk(KERN_CONT ", Tagged queuing: depth %d", device->queue_depth);
|
||||||
printk("\n");
|
printk(KERN_CONT "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -710,6 +710,12 @@ qla2x00_sysfs_write_reset(struct file *filp, struct kobject *kobj,
|
|||||||
ql_log(ql_log_info, vha, 0x706e,
|
ql_log(ql_log_info, vha, 0x706e,
|
||||||
"Issuing ISP reset.\n");
|
"Issuing ISP reset.\n");
|
||||||
|
|
||||||
|
if (vha->hw->flags.port_isolated) {
|
||||||
|
ql_log(ql_log_info, vha, 0x706e,
|
||||||
|
"Port is isolated, returning.\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
scsi_block_requests(vha->host);
|
scsi_block_requests(vha->host);
|
||||||
if (IS_QLA82XX(ha)) {
|
if (IS_QLA82XX(ha)) {
|
||||||
ha->flags.isp82xx_no_md_cap = 1;
|
ha->flags.isp82xx_no_md_cap = 1;
|
||||||
@@ -2717,6 +2723,9 @@ qla2x00_issue_lip(struct Scsi_Host *shost)
|
|||||||
if (IS_QLAFX00(vha->hw))
|
if (IS_QLAFX00(vha->hw))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if (vha->hw->flags.port_isolated)
|
||||||
|
return 0;
|
||||||
|
|
||||||
qla2x00_loop_reset(vha);
|
qla2x00_loop_reset(vha);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
* Copyright (c) 2003-2014 QLogic Corporation
|
* Copyright (c) 2003-2014 QLogic Corporation
|
||||||
*/
|
*/
|
||||||
#include "qla_def.h"
|
#include "qla_def.h"
|
||||||
|
#include "qla_gbl.h"
|
||||||
|
|
||||||
#include <linux/kthread.h>
|
#include <linux/kthread.h>
|
||||||
#include <linux/vmalloc.h>
|
#include <linux/vmalloc.h>
|
||||||
@@ -2444,6 +2445,323 @@ qla2x00_get_flash_image_status(struct bsg_job *bsg_job)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
qla2x00_manage_host_stats(struct bsg_job *bsg_job)
|
||||||
|
{
|
||||||
|
scsi_qla_host_t *vha = shost_priv(fc_bsg_to_shost(bsg_job));
|
||||||
|
struct fc_bsg_reply *bsg_reply = bsg_job->reply;
|
||||||
|
struct ql_vnd_mng_host_stats_param *req_data;
|
||||||
|
struct ql_vnd_mng_host_stats_resp rsp_data;
|
||||||
|
u32 req_data_len;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (!vha->flags.online) {
|
||||||
|
ql_log(ql_log_warn, vha, 0x0000, "Host is not online.\n");
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
req_data_len = bsg_job->request_payload.payload_len;
|
||||||
|
|
||||||
|
if (req_data_len != sizeof(struct ql_vnd_mng_host_stats_param)) {
|
||||||
|
ql_log(ql_log_warn, vha, 0x0000, "req_data_len invalid.\n");
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
req_data = kzalloc(sizeof(*req_data), GFP_KERNEL);
|
||||||
|
if (!req_data) {
|
||||||
|
ql_log(ql_log_warn, vha, 0x0000, "req_data memory allocation failure.\n");
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy the request buffer in req_data */
|
||||||
|
sg_copy_to_buffer(bsg_job->request_payload.sg_list,
|
||||||
|
bsg_job->request_payload.sg_cnt, req_data,
|
||||||
|
req_data_len);
|
||||||
|
|
||||||
|
switch (req_data->action) {
|
||||||
|
case QLA_STOP:
|
||||||
|
ret = qla2xxx_stop_stats(vha->host, req_data->stat_type);
|
||||||
|
break;
|
||||||
|
case QLA_START:
|
||||||
|
ret = qla2xxx_start_stats(vha->host, req_data->stat_type);
|
||||||
|
break;
|
||||||
|
case QLA_CLEAR:
|
||||||
|
ret = qla2xxx_reset_stats(vha->host, req_data->stat_type);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ql_log(ql_log_warn, vha, 0x0000, "Invalid action.\n");
|
||||||
|
ret = -EIO;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
kfree(req_data);
|
||||||
|
|
||||||
|
/* Prepare response */
|
||||||
|
rsp_data.status = ret;
|
||||||
|
bsg_job->reply_payload.payload_len = sizeof(struct ql_vnd_mng_host_stats_resp);
|
||||||
|
|
||||||
|
bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = EXT_STATUS_OK;
|
||||||
|
bsg_reply->reply_payload_rcv_len =
|
||||||
|
sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
|
||||||
|
bsg_job->reply_payload.sg_cnt,
|
||||||
|
&rsp_data,
|
||||||
|
sizeof(struct ql_vnd_mng_host_stats_resp));
|
||||||
|
|
||||||
|
bsg_reply->result = DID_OK;
|
||||||
|
bsg_job_done(bsg_job, bsg_reply->result,
|
||||||
|
bsg_reply->reply_payload_rcv_len);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
qla2x00_get_host_stats(struct bsg_job *bsg_job)
|
||||||
|
{
|
||||||
|
scsi_qla_host_t *vha = shost_priv(fc_bsg_to_shost(bsg_job));
|
||||||
|
struct fc_bsg_reply *bsg_reply = bsg_job->reply;
|
||||||
|
struct ql_vnd_stats_param *req_data;
|
||||||
|
struct ql_vnd_host_stats_resp rsp_data;
|
||||||
|
u32 req_data_len;
|
||||||
|
int ret = 0;
|
||||||
|
u64 ini_entry_count = 0;
|
||||||
|
u64 entry_count = 0;
|
||||||
|
u64 tgt_num = 0;
|
||||||
|
u64 tmp_stat_type = 0;
|
||||||
|
u64 response_len = 0;
|
||||||
|
void *data;
|
||||||
|
|
||||||
|
req_data_len = bsg_job->request_payload.payload_len;
|
||||||
|
|
||||||
|
if (req_data_len != sizeof(struct ql_vnd_stats_param)) {
|
||||||
|
ql_log(ql_log_warn, vha, 0x0000, "req_data_len invalid.\n");
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
req_data = kzalloc(sizeof(*req_data), GFP_KERNEL);
|
||||||
|
if (!req_data) {
|
||||||
|
ql_log(ql_log_warn, vha, 0x0000, "req_data memory allocation failure.\n");
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy the request buffer in req_data */
|
||||||
|
sg_copy_to_buffer(bsg_job->request_payload.sg_list,
|
||||||
|
bsg_job->request_payload.sg_cnt, req_data, req_data_len);
|
||||||
|
|
||||||
|
/* Copy stat type to work on it */
|
||||||
|
tmp_stat_type = req_data->stat_type;
|
||||||
|
|
||||||
|
if (tmp_stat_type & QLA2XX_TGT_SHT_LNK_DOWN) {
|
||||||
|
/* Num of tgts connected to this host */
|
||||||
|
tgt_num = qla2x00_get_num_tgts(vha);
|
||||||
|
/* unset BIT_17 */
|
||||||
|
tmp_stat_type &= ~(1 << 17);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Total ini stats */
|
||||||
|
ini_entry_count = qla2x00_count_set_bits(tmp_stat_type);
|
||||||
|
|
||||||
|
/* Total number of entries */
|
||||||
|
entry_count = ini_entry_count + tgt_num;
|
||||||
|
|
||||||
|
response_len = sizeof(struct ql_vnd_host_stats_resp) +
|
||||||
|
(sizeof(struct ql_vnd_stat_entry) * entry_count);
|
||||||
|
|
||||||
|
if (response_len > bsg_job->reply_payload.payload_len) {
|
||||||
|
rsp_data.status = EXT_STATUS_BUFFER_TOO_SMALL;
|
||||||
|
bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = EXT_STATUS_BUFFER_TOO_SMALL;
|
||||||
|
bsg_job->reply_payload.payload_len = sizeof(struct ql_vnd_mng_host_stats_resp);
|
||||||
|
|
||||||
|
bsg_reply->reply_payload_rcv_len =
|
||||||
|
sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
|
||||||
|
bsg_job->reply_payload.sg_cnt, &rsp_data,
|
||||||
|
sizeof(struct ql_vnd_mng_host_stats_resp));
|
||||||
|
|
||||||
|
bsg_reply->result = DID_OK;
|
||||||
|
bsg_job_done(bsg_job, bsg_reply->result,
|
||||||
|
bsg_reply->reply_payload_rcv_len);
|
||||||
|
goto host_stat_out;
|
||||||
|
}
|
||||||
|
|
||||||
|
data = kzalloc(response_len, GFP_KERNEL);
|
||||||
|
|
||||||
|
ret = qla2xxx_get_ini_stats(fc_bsg_to_shost(bsg_job), req_data->stat_type,
|
||||||
|
data, response_len);
|
||||||
|
|
||||||
|
rsp_data.status = EXT_STATUS_OK;
|
||||||
|
bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = EXT_STATUS_OK;
|
||||||
|
|
||||||
|
bsg_reply->reply_payload_rcv_len = sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
|
||||||
|
bsg_job->reply_payload.sg_cnt,
|
||||||
|
data, response_len);
|
||||||
|
bsg_reply->result = DID_OK;
|
||||||
|
bsg_job_done(bsg_job, bsg_reply->result,
|
||||||
|
bsg_reply->reply_payload_rcv_len);
|
||||||
|
|
||||||
|
kfree(data);
|
||||||
|
host_stat_out:
|
||||||
|
kfree(req_data);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct fc_rport *
|
||||||
|
qla2xxx_find_rport(scsi_qla_host_t *vha, uint32_t tgt_num)
|
||||||
|
{
|
||||||
|
fc_port_t *fcport = NULL;
|
||||||
|
|
||||||
|
list_for_each_entry(fcport, &vha->vp_fcports, list) {
|
||||||
|
if (fcport->rport->number == tgt_num)
|
||||||
|
return fcport->rport;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
qla2x00_get_tgt_stats(struct bsg_job *bsg_job)
|
||||||
|
{
|
||||||
|
scsi_qla_host_t *vha = shost_priv(fc_bsg_to_shost(bsg_job));
|
||||||
|
struct fc_bsg_reply *bsg_reply = bsg_job->reply;
|
||||||
|
struct ql_vnd_tgt_stats_param *req_data;
|
||||||
|
u32 req_data_len;
|
||||||
|
int ret = 0;
|
||||||
|
u64 response_len = 0;
|
||||||
|
struct ql_vnd_tgt_stats_resp *data = NULL;
|
||||||
|
struct fc_rport *rport = NULL;
|
||||||
|
|
||||||
|
if (!vha->flags.online) {
|
||||||
|
ql_log(ql_log_warn, vha, 0x0000, "Host is not online.\n");
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
req_data_len = bsg_job->request_payload.payload_len;
|
||||||
|
|
||||||
|
if (req_data_len != sizeof(struct ql_vnd_stat_entry)) {
|
||||||
|
ql_log(ql_log_warn, vha, 0x0000, "req_data_len invalid.\n");
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
req_data = kzalloc(sizeof(*req_data), GFP_KERNEL);
|
||||||
|
if (!req_data) {
|
||||||
|
ql_log(ql_log_warn, vha, 0x0000, "req_data memory allocation failure.\n");
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy the request buffer in req_data */
|
||||||
|
sg_copy_to_buffer(bsg_job->request_payload.sg_list,
|
||||||
|
bsg_job->request_payload.sg_cnt,
|
||||||
|
req_data, req_data_len);
|
||||||
|
|
||||||
|
response_len = sizeof(struct ql_vnd_tgt_stats_resp) +
|
||||||
|
sizeof(struct ql_vnd_stat_entry);
|
||||||
|
|
||||||
|
/* structure + size for one entry */
|
||||||
|
data = kzalloc(response_len, GFP_KERNEL);
|
||||||
|
if (!data) {
|
||||||
|
kfree(req_data);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response_len > bsg_job->reply_payload.payload_len) {
|
||||||
|
data->status = EXT_STATUS_BUFFER_TOO_SMALL;
|
||||||
|
bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = EXT_STATUS_BUFFER_TOO_SMALL;
|
||||||
|
bsg_job->reply_payload.payload_len = sizeof(struct ql_vnd_mng_host_stats_resp);
|
||||||
|
|
||||||
|
bsg_reply->reply_payload_rcv_len =
|
||||||
|
sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
|
||||||
|
bsg_job->reply_payload.sg_cnt, data,
|
||||||
|
sizeof(struct ql_vnd_tgt_stats_resp));
|
||||||
|
|
||||||
|
bsg_reply->result = DID_OK;
|
||||||
|
bsg_job_done(bsg_job, bsg_reply->result,
|
||||||
|
bsg_reply->reply_payload_rcv_len);
|
||||||
|
goto tgt_stat_out;
|
||||||
|
}
|
||||||
|
|
||||||
|
rport = qla2xxx_find_rport(vha, req_data->tgt_id);
|
||||||
|
if (!rport) {
|
||||||
|
ql_log(ql_log_warn, vha, 0x0000, "target %d not found.\n", req_data->tgt_id);
|
||||||
|
ret = EXT_STATUS_INVALID_PARAM;
|
||||||
|
data->status = EXT_STATUS_INVALID_PARAM;
|
||||||
|
goto reply;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = qla2xxx_get_tgt_stats(fc_bsg_to_shost(bsg_job), req_data->stat_type,
|
||||||
|
rport, (void *)data, response_len);
|
||||||
|
|
||||||
|
bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = EXT_STATUS_OK;
|
||||||
|
reply:
|
||||||
|
bsg_reply->reply_payload_rcv_len =
|
||||||
|
sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
|
||||||
|
bsg_job->reply_payload.sg_cnt, data,
|
||||||
|
response_len);
|
||||||
|
bsg_reply->result = DID_OK;
|
||||||
|
bsg_job_done(bsg_job, bsg_reply->result,
|
||||||
|
bsg_reply->reply_payload_rcv_len);
|
||||||
|
|
||||||
|
tgt_stat_out:
|
||||||
|
kfree(data);
|
||||||
|
kfree(req_data);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
qla2x00_manage_host_port(struct bsg_job *bsg_job)
|
||||||
|
{
|
||||||
|
scsi_qla_host_t *vha = shost_priv(fc_bsg_to_shost(bsg_job));
|
||||||
|
struct fc_bsg_reply *bsg_reply = bsg_job->reply;
|
||||||
|
struct ql_vnd_mng_host_port_param *req_data;
|
||||||
|
struct ql_vnd_mng_host_port_resp rsp_data;
|
||||||
|
u32 req_data_len;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
req_data_len = bsg_job->request_payload.payload_len;
|
||||||
|
|
||||||
|
if (req_data_len != sizeof(struct ql_vnd_mng_host_port_param)) {
|
||||||
|
ql_log(ql_log_warn, vha, 0x0000, "req_data_len invalid.\n");
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
req_data = kzalloc(sizeof(*req_data), GFP_KERNEL);
|
||||||
|
if (!req_data) {
|
||||||
|
ql_log(ql_log_warn, vha, 0x0000, "req_data memory allocation failure.\n");
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy the request buffer in req_data */
|
||||||
|
sg_copy_to_buffer(bsg_job->request_payload.sg_list,
|
||||||
|
bsg_job->request_payload.sg_cnt, req_data, req_data_len);
|
||||||
|
|
||||||
|
switch (req_data->action) {
|
||||||
|
case QLA_ENABLE:
|
||||||
|
ret = qla2xxx_enable_port(vha->host);
|
||||||
|
break;
|
||||||
|
case QLA_DISABLE:
|
||||||
|
ret = qla2xxx_disable_port(vha->host);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ql_log(ql_log_warn, vha, 0x0000, "Invalid action.\n");
|
||||||
|
ret = -EIO;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
kfree(req_data);
|
||||||
|
|
||||||
|
/* Prepare response */
|
||||||
|
rsp_data.status = ret;
|
||||||
|
bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = EXT_STATUS_OK;
|
||||||
|
bsg_job->reply_payload.payload_len = sizeof(struct ql_vnd_mng_host_port_resp);
|
||||||
|
|
||||||
|
bsg_reply->reply_payload_rcv_len =
|
||||||
|
sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
|
||||||
|
bsg_job->reply_payload.sg_cnt, &rsp_data,
|
||||||
|
sizeof(struct ql_vnd_mng_host_port_resp));
|
||||||
|
bsg_reply->result = DID_OK;
|
||||||
|
bsg_job_done(bsg_job, bsg_reply->result,
|
||||||
|
bsg_reply->reply_payload_rcv_len);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
qla2x00_process_vendor_specific(struct bsg_job *bsg_job)
|
qla2x00_process_vendor_specific(struct bsg_job *bsg_job)
|
||||||
{
|
{
|
||||||
@@ -2520,6 +2838,18 @@ qla2x00_process_vendor_specific(struct bsg_job *bsg_job)
|
|||||||
case QL_VND_SS_GET_FLASH_IMAGE_STATUS:
|
case QL_VND_SS_GET_FLASH_IMAGE_STATUS:
|
||||||
return qla2x00_get_flash_image_status(bsg_job);
|
return qla2x00_get_flash_image_status(bsg_job);
|
||||||
|
|
||||||
|
case QL_VND_MANAGE_HOST_STATS:
|
||||||
|
return qla2x00_manage_host_stats(bsg_job);
|
||||||
|
|
||||||
|
case QL_VND_GET_HOST_STATS:
|
||||||
|
return qla2x00_get_host_stats(bsg_job);
|
||||||
|
|
||||||
|
case QL_VND_GET_TGT_STATS:
|
||||||
|
return qla2x00_get_tgt_stats(bsg_job);
|
||||||
|
|
||||||
|
case QL_VND_MANAGE_HOST_PORT:
|
||||||
|
return qla2x00_manage_host_port(bsg_job);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
}
|
}
|
||||||
@@ -2547,6 +2877,17 @@ qla24xx_bsg_request(struct bsg_job *bsg_job)
|
|||||||
vha = shost_priv(host);
|
vha = shost_priv(host);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Disable port will bring down the chip, allow enable command */
|
||||||
|
if (bsg_request->rqst_data.h_vendor.vendor_cmd[0] == QL_VND_MANAGE_HOST_PORT ||
|
||||||
|
bsg_request->rqst_data.h_vendor.vendor_cmd[0] == QL_VND_GET_HOST_STATS)
|
||||||
|
goto skip_chip_chk;
|
||||||
|
|
||||||
|
if (vha->hw->flags.port_isolated) {
|
||||||
|
bsg_reply->result = DID_ERROR;
|
||||||
|
/* operation not permitted */
|
||||||
|
return -EPERM;
|
||||||
|
}
|
||||||
|
|
||||||
if (qla2x00_chip_is_down(vha)) {
|
if (qla2x00_chip_is_down(vha)) {
|
||||||
ql_dbg(ql_dbg_user, vha, 0x709f,
|
ql_dbg(ql_dbg_user, vha, 0x709f,
|
||||||
"BSG: ISP abort active/needed -- cmd=%d.\n",
|
"BSG: ISP abort active/needed -- cmd=%d.\n",
|
||||||
@@ -2554,6 +2895,7 @@ qla24xx_bsg_request(struct bsg_job *bsg_job)
|
|||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
skip_chip_chk:
|
||||||
ql_dbg(ql_dbg_user, vha, 0x7000,
|
ql_dbg(ql_dbg_user, vha, 0x7000,
|
||||||
"Entered %s msgcode=0x%x.\n", __func__, bsg_request->msgcode);
|
"Entered %s msgcode=0x%x.\n", __func__, bsg_request->msgcode);
|
||||||
|
|
||||||
|
|||||||
@@ -31,6 +31,10 @@
|
|||||||
#define QL_VND_DPORT_DIAGNOSTICS 0x19
|
#define QL_VND_DPORT_DIAGNOSTICS 0x19
|
||||||
#define QL_VND_GET_PRIV_STATS_EX 0x1A
|
#define QL_VND_GET_PRIV_STATS_EX 0x1A
|
||||||
#define QL_VND_SS_GET_FLASH_IMAGE_STATUS 0x1E
|
#define QL_VND_SS_GET_FLASH_IMAGE_STATUS 0x1E
|
||||||
|
#define QL_VND_MANAGE_HOST_STATS 0x23
|
||||||
|
#define QL_VND_GET_HOST_STATS 0x24
|
||||||
|
#define QL_VND_GET_TGT_STATS 0x25
|
||||||
|
#define QL_VND_MANAGE_HOST_PORT 0x26
|
||||||
|
|
||||||
/* BSG Vendor specific subcode returns */
|
/* BSG Vendor specific subcode returns */
|
||||||
#define EXT_STATUS_OK 0
|
#define EXT_STATUS_OK 0
|
||||||
@@ -40,6 +44,7 @@
|
|||||||
#define EXT_STATUS_DATA_OVERRUN 7
|
#define EXT_STATUS_DATA_OVERRUN 7
|
||||||
#define EXT_STATUS_DATA_UNDERRUN 8
|
#define EXT_STATUS_DATA_UNDERRUN 8
|
||||||
#define EXT_STATUS_MAILBOX 11
|
#define EXT_STATUS_MAILBOX 11
|
||||||
|
#define EXT_STATUS_BUFFER_TOO_SMALL 16
|
||||||
#define EXT_STATUS_NO_MEMORY 17
|
#define EXT_STATUS_NO_MEMORY 17
|
||||||
#define EXT_STATUS_DEVICE_OFFLINE 22
|
#define EXT_STATUS_DEVICE_OFFLINE 22
|
||||||
|
|
||||||
|
|||||||
@@ -202,6 +202,7 @@ qla24xx_dump_ram(struct qla_hw_data *ha, uint32_t addr, __be32 *ram,
|
|||||||
wrt_reg_word(®->mailbox0, MBC_DUMP_RISC_RAM_EXTENDED);
|
wrt_reg_word(®->mailbox0, MBC_DUMP_RISC_RAM_EXTENDED);
|
||||||
wrt_reg_word(®->mailbox1, LSW(addr));
|
wrt_reg_word(®->mailbox1, LSW(addr));
|
||||||
wrt_reg_word(®->mailbox8, MSW(addr));
|
wrt_reg_word(®->mailbox8, MSW(addr));
|
||||||
|
wrt_reg_word(®->mailbox10, 0);
|
||||||
|
|
||||||
wrt_reg_word(®->mailbox2, MSW(LSD(dump_dma)));
|
wrt_reg_word(®->mailbox2, MSW(LSD(dump_dma)));
|
||||||
wrt_reg_word(®->mailbox3, LSW(LSD(dump_dma)));
|
wrt_reg_word(®->mailbox3, LSW(LSD(dump_dma)));
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user