aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/scsi/hpsa.txt107
-rw-r--r--MAINTAINERS8
-rw-r--r--arch/s390/include/asm/qdio.h6
-rw-r--r--drivers/message/fusion/mptbase.c49
-rw-r--r--drivers/message/fusion/mptbase.h13
-rw-r--r--drivers/message/fusion/mptctl.c38
-rw-r--r--drivers/message/fusion/mptfc.c9
-rw-r--r--drivers/message/fusion/mptlan.c4
-rw-r--r--drivers/message/fusion/mptsas.c278
-rw-r--r--drivers/message/fusion/mptsas.h1
-rw-r--r--drivers/message/fusion/mptscsih.c54
-rw-r--r--drivers/message/fusion/mptspi.c9
-rw-r--r--drivers/misc/enclosure.c7
-rw-r--r--drivers/s390/cio/qdio_setup.c2
-rw-r--r--drivers/s390/scsi/zfcp_aux.c10
-rw-r--r--drivers/s390/scsi/zfcp_cfdc.c12
-rw-r--r--drivers/s390/scsi/zfcp_dbf.c5
-rw-r--r--drivers/s390/scsi/zfcp_dbf.h1
-rw-r--r--drivers/s390/scsi/zfcp_def.h5
-rw-r--r--drivers/s390/scsi/zfcp_erp.c24
-rw-r--r--drivers/s390/scsi/zfcp_ext.h11
-rw-r--r--drivers/s390/scsi/zfcp_fc.c54
-rw-r--r--drivers/s390/scsi/zfcp_fc.h27
-rw-r--r--drivers/s390/scsi/zfcp_fsf.c169
-rw-r--r--drivers/s390/scsi/zfcp_fsf.h34
-rw-r--r--drivers/s390/scsi/zfcp_qdio.c206
-rw-r--r--drivers/s390/scsi/zfcp_qdio.h95
-rw-r--r--drivers/s390/scsi/zfcp_scsi.c103
-rw-r--r--drivers/s390/scsi/zfcp_sysfs.c12
-rw-r--r--drivers/scsi/Kconfig4
-rw-r--r--drivers/scsi/Makefile1
-rw-r--r--drivers/scsi/aacraid/linit.c14
-rw-r--r--drivers/scsi/aic7xxx/aic7770.c12
-rw-r--r--drivers/scsi/aic7xxx/aic7770_osm.c2
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_core.c624
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_osm.c108
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_osm.h7
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_osm_pci.c8
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_pci.c56
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_proc.c13
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_93cx6.c10
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_core.c430
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_osm.c76
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_osm.h7
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_osm_pci.c8
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_pci.c74
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_proc.c15
-rw-r--r--drivers/scsi/aic94xx/aic94xx_task.c2
-rw-r--r--drivers/scsi/arcmsr/arcmsr.h315
-rw-r--r--drivers/scsi/arcmsr/arcmsr_hba.c2309
-rw-r--r--drivers/scsi/be2iscsi/Kconfig2
-rw-r--r--drivers/scsi/be2iscsi/be.h6
-rw-r--r--drivers/scsi/be2iscsi/be_cmds.c116
-rw-r--r--drivers/scsi/be2iscsi/be_cmds.h27
-rw-r--r--drivers/scsi/be2iscsi/be_iscsi.c199
-rw-r--r--drivers/scsi/be2iscsi/be_iscsi.h2
-rw-r--r--drivers/scsi/be2iscsi/be_main.c333
-rw-r--r--drivers/scsi/be2iscsi/be_main.h29
-rw-r--r--drivers/scsi/be2iscsi/be_mgmt.c64
-rw-r--r--drivers/scsi/be2iscsi/be_mgmt.h19
-rw-r--r--drivers/scsi/bfa/Makefile2
-rw-r--r--drivers/scsi/bfa/bfa_cb_ioim_macros.h7
-rw-r--r--drivers/scsi/bfa/bfa_core.c1
-rw-r--r--drivers/scsi/bfa/bfa_fcpim.c29
-rw-r--r--drivers/scsi/bfa/bfa_fcpim_priv.h6
-rw-r--r--drivers/scsi/bfa/bfa_fcport.c139
-rw-r--r--drivers/scsi/bfa/bfa_fcs.c10
-rw-r--r--drivers/scsi/bfa/bfa_fcs_lport.c3
-rw-r--r--drivers/scsi/bfa/bfa_fcxp.c14
-rw-r--r--drivers/scsi/bfa/bfa_fwimg_priv.h25
-rw-r--r--drivers/scsi/bfa/bfa_hw_cb.c7
-rw-r--r--drivers/scsi/bfa/bfa_hw_ct.c7
-rw-r--r--drivers/scsi/bfa/bfa_intr.c1
-rw-r--r--drivers/scsi/bfa/bfa_ioc.c172
-rw-r--r--drivers/scsi/bfa/bfa_ioc.h12
-rw-r--r--drivers/scsi/bfa/bfa_ioc_cb.c36
-rw-r--r--drivers/scsi/bfa/bfa_ioc_ct.c71
-rw-r--r--drivers/scsi/bfa/bfa_iocfc.c107
-rw-r--r--drivers/scsi/bfa/bfa_iocfc.h19
-rw-r--r--drivers/scsi/bfa/bfa_ioim.c63
-rw-r--r--drivers/scsi/bfa/bfa_log_module.c86
-rw-r--r--drivers/scsi/bfa/bfa_lps.c6
-rw-r--r--drivers/scsi/bfa/bfa_port.c31
-rw-r--r--drivers/scsi/bfa/bfa_port_priv.h7
-rw-r--r--drivers/scsi/bfa/bfa_priv.h3
-rw-r--r--drivers/scsi/bfa/bfa_rport.c5
-rw-r--r--drivers/scsi/bfa/bfa_sgpg.c5
-rw-r--r--drivers/scsi/bfa/bfa_uf.c10
-rw-r--r--drivers/scsi/bfa/bfad.c114
-rw-r--r--drivers/scsi/bfa/bfad_attr.c46
-rw-r--r--drivers/scsi/bfa/bfad_debugfs.c547
-rw-r--r--drivers/scsi/bfa/bfad_drv.h36
-rw-r--r--drivers/scsi/bfa/bfad_fwimg.c76
-rw-r--r--drivers/scsi/bfa/bfad_im.c33
-rw-r--r--drivers/scsi/bfa/bfad_im_compat.h13
-rw-r--r--drivers/scsi/bfa/bfad_intr.c8
-rw-r--r--drivers/scsi/bfa/fabric.c44
-rw-r--r--drivers/scsi/bfa/fcpim.c32
-rw-r--r--drivers/scsi/bfa/fcs_fabric.h5
-rw-r--r--drivers/scsi/bfa/fcs_rport.h3
-rw-r--r--drivers/scsi/bfa/fcs_vport.h1
-rw-r--r--drivers/scsi/bfa/fdmi.c6
-rw-r--r--drivers/scsi/bfa/include/aen/bfa_aen_ioc.h8
-rw-r--r--drivers/scsi/bfa/include/bfa.h4
-rw-r--r--drivers/scsi/bfa/include/bfa_fcpim.h20
-rw-r--r--drivers/scsi/bfa/include/bfa_svc.h1
-rw-r--r--drivers/scsi/bfa/include/bfi/bfi_ctreg.h3
-rw-r--r--drivers/scsi/bfa/include/bfi/bfi_ioc.h20
-rw-r--r--drivers/scsi/bfa/include/bfi/bfi_iocfc.h2
-rw-r--r--drivers/scsi/bfa/include/bfi/bfi_pbc.h62
-rw-r--r--drivers/scsi/bfa/include/cna/port/bfa_port.h1
-rw-r--r--drivers/scsi/bfa/include/cs/bfa_debug.h3
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_adapter.h3
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_auth.h6
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_boot.h10
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_driver.h2
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_fcport.h26
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_ioc.h7
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_iocfc.h12
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_itnim.h10
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_mfg.h41
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_pci.h11
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_port.h14
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_pport.h29
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_status.h46
-rw-r--r--drivers/scsi/bfa/include/fcb/bfa_fcb_vport.h3
-rw-r--r--drivers/scsi/bfa/include/fcs/bfa_fcs.h4
-rw-r--r--drivers/scsi/bfa/include/fcs/bfa_fcs_fcpim.h1
-rw-r--r--drivers/scsi/bfa/include/fcs/bfa_fcs_rport.h1
-rw-r--r--drivers/scsi/bfa/include/fcs/bfa_fcs_vport.h4
-rw-r--r--drivers/scsi/bfa/include/log/bfa_log_linux.h6
-rw-r--r--drivers/scsi/bfa/include/protocol/fc.h1
-rw-r--r--drivers/scsi/bfa/lport_api.c30
-rw-r--r--drivers/scsi/bfa/ms.c9
-rw-r--r--drivers/scsi/bfa/ns.c14
-rw-r--r--drivers/scsi/bfa/rport.c88
-rw-r--r--drivers/scsi/bfa/rport_api.c11
-rw-r--r--drivers/scsi/bfa/rport_ftrs.c14
-rw-r--r--drivers/scsi/bfa/scn.c2
-rw-r--r--drivers/scsi/bfa/vport.c54
-rw-r--r--drivers/scsi/bnx2i/bnx2i.h14
-rw-r--r--drivers/scsi/bnx2i/bnx2i_hwi.c4
-rw-r--r--drivers/scsi/bnx2i/bnx2i_init.c37
-rw-r--r--drivers/scsi/bnx2i/bnx2i_iscsi.c236
-rw-r--r--drivers/scsi/cxgb3i/cxgb3i_ddp.c2
-rw-r--r--drivers/scsi/cxgb3i/cxgb3i_offload.c5
-rw-r--r--drivers/scsi/device_handler/scsi_dh_rdac.c1
-rw-r--r--drivers/scsi/dpt_i2o.c26
-rw-r--r--drivers/scsi/fcoe/fcoe.c147
-rw-r--r--drivers/scsi/fcoe/libfcoe.c1519
-rw-r--r--drivers/scsi/fnic/fnic_main.c11
-rw-r--r--drivers/scsi/fnic/fnic_scsi.c22
-rw-r--r--drivers/scsi/hosts.c14
-rw-r--r--drivers/scsi/hpsa.c754
-rw-r--r--drivers/scsi/hpsa.h1
-rw-r--r--drivers/scsi/hpsa_cmd.h4
-rw-r--r--drivers/scsi/hptiop.c2
-rw-r--r--drivers/scsi/ibmvscsi/ibmvfc.c85
-rw-r--r--drivers/scsi/ibmvscsi/ibmvfc.h6
-rw-r--r--drivers/scsi/ibmvscsi/ibmvscsi.c157
-rw-r--r--drivers/scsi/ibmvscsi/ibmvscsi.h4
-rw-r--r--drivers/scsi/ibmvscsi/ibmvstgt.c4
-rw-r--r--drivers/scsi/ibmvscsi/rpa_vscsi.c16
-rw-r--r--drivers/scsi/ipr.c148
-rw-r--r--drivers/scsi/ipr.h30
-rw-r--r--drivers/scsi/libfc/fc_disc.c39
-rw-r--r--drivers/scsi/libfc/fc_elsct.c2
-rw-r--r--drivers/scsi/libfc/fc_exch.c215
-rw-r--r--drivers/scsi/libfc/fc_fcp.c15
-rw-r--r--drivers/scsi/libfc/fc_libfc.c78
-rw-r--r--drivers/scsi/libfc/fc_libfc.h2
-rw-r--r--drivers/scsi/libfc/fc_lport.c210
-rw-r--r--drivers/scsi/libfc/fc_rport.c707
-rw-r--r--drivers/scsi/libsas/sas_ata.c12
-rw-r--r--drivers/scsi/libsas/sas_expander.c2
-rw-r--r--drivers/scsi/libsas/sas_scsi_host.c4
-rw-r--r--drivers/scsi/libsas/sas_task.c6
-rw-r--r--drivers/scsi/lpfc/lpfc.h17
-rw-r--r--drivers/scsi/lpfc/lpfc_attr.c96
-rw-r--r--drivers/scsi/lpfc/lpfc_bsg.c36
-rw-r--r--drivers/scsi/lpfc/lpfc_crtn.h11
-rw-r--r--drivers/scsi/lpfc/lpfc_disc.h2
-rw-r--r--drivers/scsi/lpfc/lpfc_els.c112
-rw-r--r--drivers/scsi/lpfc/lpfc_hbadisc.c220
-rw-r--r--drivers/scsi/lpfc/lpfc_hw.h17
-rw-r--r--drivers/scsi/lpfc/lpfc_init.c279
-rw-r--r--drivers/scsi/lpfc/lpfc_mbox.c23
-rw-r--r--drivers/scsi/lpfc/lpfc_nportdisc.c31
-rw-r--r--drivers/scsi/lpfc/lpfc_scsi.c86
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c345
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.h2
-rw-r--r--drivers/scsi/lpfc/lpfc_sli4.h8
-rw-r--r--drivers/scsi/lpfc/lpfc_version.h2
-rw-r--r--drivers/scsi/lpfc/lpfc_vport.c2
-rw-r--r--drivers/scsi/mpt2sas/mpi/mpi2.h17
-rw-r--r--drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h193
-rw-r--r--drivers/scsi/mpt2sas/mpi/mpi2_init.h17
-rw-r--r--drivers/scsi/mpt2sas/mpi/mpi2_ioc.h119
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_base.c172
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_base.h34
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_config.c6
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_ctl.c411
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_scsih.c744
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_transport.c575
-rw-r--r--drivers/scsi/mvsas/mv_sas.c20
-rw-r--r--drivers/scsi/pm8001/pm8001_hwi.c14
-rw-r--r--drivers/scsi/pm8001/pm8001_sas.c4
-rw-r--r--drivers/scsi/pmcraid.c893
-rw-r--r--drivers/scsi/pmcraid.h305
-rw-r--r--drivers/scsi/qla2xxx/qla_attr.c33
-rw-r--r--drivers/scsi/qla2xxx/qla_bsg.c294
-rw-r--r--drivers/scsi/qla2xxx/qla_bsg.h9
-rw-r--r--drivers/scsi/qla2xxx/qla_dbg.c2
-rw-r--r--drivers/scsi/qla2xxx/qla_dbg.h2
-rw-r--r--drivers/scsi/qla2xxx/qla_def.h54
-rw-r--r--drivers/scsi/qla2xxx/qla_dfs.c2
-rw-r--r--drivers/scsi/qla2xxx/qla_fw.h2
-rw-r--r--drivers/scsi/qla2xxx/qla_gbl.h29
-rw-r--r--drivers/scsi/qla2xxx/qla_gs.c74
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c178
-rw-r--r--drivers/scsi/qla2xxx/qla_inline.h2
-rw-r--r--drivers/scsi/qla2xxx/qla_iocb.c257
-rw-r--r--drivers/scsi/qla2xxx/qla_isr.c206
-rw-r--r--drivers/scsi/qla2xxx/qla_mbx.c158
-rw-r--r--drivers/scsi/qla2xxx/qla_mid.c61
-rw-r--r--drivers/scsi/qla2xxx/qla_nx.c550
-rw-r--r--drivers/scsi/qla2xxx/qla_nx.h43
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c109
-rw-r--r--drivers/scsi/qla2xxx/qla_settings.h2
-rw-r--r--drivers/scsi/qla2xxx/qla_sup.c49
-rw-r--r--drivers/scsi/qla2xxx/qla_version.h8
-rw-r--r--drivers/scsi/qla4xxx/Kconfig8
-rw-r--r--drivers/scsi/qla4xxx/Makefile2
-rw-r--r--drivers/scsi/qla4xxx/ql4_def.h143
-rw-r--r--drivers/scsi/qla4xxx/ql4_fw.h139
-rw-r--r--drivers/scsi/qla4xxx/ql4_glbl.h106
-rw-r--r--drivers/scsi/qla4xxx/ql4_init.c240
-rw-r--r--drivers/scsi/qla4xxx/ql4_inline.h2
-rw-r--r--drivers/scsi/qla4xxx/ql4_iocb.c73
-rw-r--r--drivers/scsi/qla4xxx/ql4_isr.c396
-rw-r--r--drivers/scsi/qla4xxx/ql4_mbx.c191
-rw-r--r--drivers/scsi/qla4xxx/ql4_nvram.c2
-rw-r--r--drivers/scsi/qla4xxx/ql4_nvram.h10
-rw-r--r--drivers/scsi/qla4xxx/ql4_nx.c2321
-rw-r--r--drivers/scsi/qla4xxx/ql4_nx.h779
-rw-r--r--drivers/scsi/qla4xxx/ql4_os.c758
-rw-r--r--drivers/scsi/qla4xxx/ql4_version.h2
-rw-r--r--drivers/scsi/scsi_debug.c6
-rw-r--r--drivers/scsi/scsi_error.c29
-rw-r--r--drivers/scsi/scsi_pm.c206
-rw-r--r--drivers/scsi/scsi_priv.h19
-rw-r--r--drivers/scsi/scsi_scan.c24
-rw-r--r--drivers/scsi/scsi_sysfs.c68
-rw-r--r--drivers/scsi/scsi_transport_iscsi.c81
-rw-r--r--drivers/scsi/sd.c21
-rw-r--r--drivers/scsi/sg.c12
-rw-r--r--include/scsi/fc/fc_els.h11
-rw-r--r--include/scsi/fc/fc_fcoe.h15
-rw-r--r--include/scsi/fc/fc_fip.h46
-rw-r--r--include/scsi/fc/fc_ns.h7
-rw-r--r--include/scsi/fc_encode.h7
-rw-r--r--include/scsi/fc_frame.h52
-rw-r--r--include/scsi/iscsi_if.h2
-rw-r--r--include/scsi/libfc.h75
-rw-r--r--include/scsi/libfcoe.h72
-rw-r--r--include/scsi/libsas.h11
-rw-r--r--include/scsi/scsi_device.h8
-rw-r--r--include/scsi/scsi_transport_iscsi.h2
268 files changed, 19599 insertions, 6501 deletions
diff --git a/Documentation/scsi/hpsa.txt b/Documentation/scsi/hpsa.txt
new file mode 100644
index 00000000000..dca658362cb
--- /dev/null
+++ b/Documentation/scsi/hpsa.txt
@@ -0,0 +1,107 @@
+
+HPSA - Hewlett Packard Smart Array driver
+-----------------------------------------
+
+This file describes the hpsa SCSI driver for HP Smart Array controllers.
+The hpsa driver is intended to supplant the cciss driver for newer
+Smart Array controllers. The hpsa driver is a SCSI driver, while the
+cciss driver is a "block" driver. Actually cciss is both a block
+driver (for logical drives) AND a SCSI driver (for tape drives). This
+"split-brained" design of the cciss driver is a source of excess
+complexity and eliminating that complexity is one of the reasons
+for hpsa to exist.
+
+Supported devices:
+------------------
+
+Smart Array P212
+Smart Array P410
+Smart Array P410i
+Smart Array P411
+Smart Array P812
+Smart Array P712m
+Smart Array P711m
+StorageWorks P1210m
+
+Additionally, older Smart Arrays may work with the hpsa driver if the kernel
+boot parameter "hpsa_allow_any=1" is specified, however these are not tested
+nor supported by HP with this driver. For older Smart Arrays, the cciss
+driver should still be used.
+
+HPSA specific entries in /sys
+-----------------------------
+
+ In addition to the generic SCSI attributes available in /sys, hpsa supports
+ the following attributes:
+
+ HPSA specific host attributes:
+ ------------------------------
+
+ /sys/class/scsi_host/host*/rescan
+ /sys/class/scsi_host/host*/firmware_revision
+
+ the host "rescan" attribute is a write only attribute. Writing to this
+ attribute will cause the driver to scan for new, changed, or removed devices
+ (e.g. hot-plugged tape drives, or newly configured or deleted logical drives,
+ etc.) and notify the SCSI midlayer of any changes detected. Normally this is
+ triggered automatically by HP's Array Configuration Utility (either the GUI or
+ command line variety) so for logical drive changes, the user should not
+ normally have to use this. It may be useful when hot plugging devices like
+ tape drives, or entire storage boxes containing pre-configured logical drives.
+
+ The "firmware_revision" attribute contains the firmware version of the Smart Array.
+ For example:
+
+ root@host:/sys/class/scsi_host/host4# cat firmware_revision
+ 7.14
+
+ HPSA specific disk attributes:
+ ------------------------------
+
+ /sys/class/scsi_disk/c:b:t:l/device/unique_id
+ /sys/class/scsi_disk/c:b:t:l/device/raid_level
+ /sys/class/scsi_disk/c:b:t:l/device/lunid
+
+ (where c:b:t:l are the controller, bus, target and lun of the device)
+
+ For example:
+
+ root@host:/sys/class/scsi_disk/4:0:0:0/device# cat unique_id
+ 600508B1001044395355323037570F77
+ root@host:/sys/class/scsi_disk/4:0:0:0/device# cat lunid
+ 0x0000004000000000
+ root@host:/sys/class/scsi_disk/4:0:0:0/device# cat raid_level
+ RAID 0
+
+HPSA specific ioctls:
+---------------------
+
+ For compatibility with applications written for the cciss driver, many, but
+ not all of the ioctls supported by the cciss driver are also supported by the
+ hpsa driver. The data structures used by these are described in
+ include/linux/cciss_ioctl.h
+
+ CCISS_DEREGDISK
+ CCISS_REGNEWDISK
+ CCISS_REGNEWD
+
+ The above three ioctls all do exactly the same thing, which is to cause the driver
+ to rescan for new devices. This does exactly the same thing as writing to the
+ hpsa specific host "rescan" attribute.
+
+ CCISS_GETPCIINFO
+
+ Returns PCI domain, bus, device and function and "board ID" (PCI subsystem ID).
+
+ CCISS_GETDRIVVER
+
+ Returns driver version in three bytes encoded as:
+ (major_version << 16) | (minor_version << 8) | (subminor_version)
+
+ CCISS_PASSTHRU
+ CCISS_BIG_PASSTHRU
+
+ Allows "BMIC" and "CISS" commands to be passed through to the Smart Array.
+ These are used extensively by the HP Array Configuration Utility, SNMP storage
+ agents, etc. See cciss_vol_status at http://cciss.sf.net for some examples.
+
diff --git a/MAINTAINERS b/MAINTAINERS
index 7c3b67c34e5..88ec0447a4f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2625,6 +2625,14 @@ S: Maintained
F: Documentation/blockdev/cpqarray.txt
F: drivers/block/cpqarray.*
+HEWLETT-PACKARD SMART ARRAY RAID DRIVER (hpsa)
+M: Stephen M. Cameron <scameron@beardog.cce.hp.com>
+L: iss_storagedev@hp.com
+S: Supported
+F: Documentation/scsi/hpsa.txt
+F: drivers/scsi/hpsa*.[ch]
+F: include/linux/cciss*.h
+
HEWLETT-PACKARD SMART CISS RAID DRIVER (cciss)
M: Mike Miller <mike.miller@hp.com>
L: iss_storagedev@hp.com
diff --git a/arch/s390/include/asm/qdio.h b/arch/s390/include/asm/qdio.h
index 0eaae626027..2ba63027629 100644
--- a/arch/s390/include/asm/qdio.h
+++ b/arch/s390/include/asm/qdio.h
@@ -84,6 +84,7 @@ struct qdr {
#define QIB_AC_OUTBOUND_PCI_SUPPORTED 0x40
#define QIB_RFLAGS_ENABLE_QEBSM 0x80
+#define QIB_RFLAGS_ENABLE_DATA_DIV 0x02
/**
* struct qib - queue information block (QIB)
@@ -284,6 +285,9 @@ struct slsb {
u8 val[QDIO_MAX_BUFFERS_PER_Q];
} __attribute__ ((packed, aligned(256)));
+#define CHSC_AC2_DATA_DIV_AVAILABLE 0x0010
+#define CHSC_AC2_DATA_DIV_ENABLED 0x0002
+
struct qdio_ssqd_desc {
u8 flags;
u8:8;
@@ -332,6 +336,7 @@ typedef void qdio_handler_t(struct ccw_device *, unsigned int, int,
* @adapter_name: name for the adapter
* @qib_param_field_format: format for qib_parm_field
* @qib_param_field: pointer to 128 bytes or NULL, if no param field
+ * @qib_rflags: rflags to set
* @input_slib_elements: pointer to no_input_qs * 128 words of data or NULL
* @output_slib_elements: pointer to no_output_qs * 128 words of data or NULL
* @no_input_qs: number of input queues
@@ -348,6 +353,7 @@ struct qdio_initialize {
unsigned char adapter_name[8];
unsigned int qib_param_field_format;
unsigned char *qib_param_field;
+ unsigned char qib_rflags;
unsigned long *input_slib_elements;
unsigned long *output_slib_elements;
unsigned int no_input_qs;
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
index a6a57011ba6..2a52559058a 100644
--- a/drivers/message/fusion/mptbase.c
+++ b/drivers/message/fusion/mptbase.c
@@ -115,6 +115,7 @@ MODULE_PARM_DESC(mpt_fwfault_debug, "Enable detection of Firmware fault"
" and halt Firmware on fault - (default=0)");
+static char MptCallbacksName[MPT_MAX_PROTOCOL_DRIVERS][50];
#ifdef MFCNT
static int mfcounter = 0;
@@ -213,7 +214,7 @@ static int ProcessEventNotification(MPT_ADAPTER *ioc,
static void mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf);
static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info);
static void mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info);
-static void mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info);
+static void mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info , u8 cb_idx);
static int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc);
static void mpt_inactive_raid_list_free(MPT_ADAPTER *ioc);
@@ -490,7 +491,7 @@ mpt_reply(MPT_ADAPTER *ioc, u32 pa)
else if (ioc->bus_type == SPI)
mpt_spi_log_info(ioc, log_info);
else if (ioc->bus_type == SAS)
- mpt_sas_log_info(ioc, log_info);
+ mpt_sas_log_info(ioc, log_info, cb_idx);
}
if (ioc_stat & MPI_IOCSTATUS_MASK)
@@ -644,7 +645,7 @@ mptbase_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply)
* considered an error by the caller.
*/
u8
-mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass)
+mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass, char *func_name)
{
u8 cb_idx;
last_drv_idx = MPT_MAX_PROTOCOL_DRIVERS;
@@ -659,6 +660,8 @@ mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass)
MptDriverClass[cb_idx] = dclass;
MptEvHandlers[cb_idx] = NULL;
last_drv_idx = cb_idx;
+ memcpy(MptCallbacksName[cb_idx], func_name,
+ strlen(func_name) > 50 ? 50 : strlen(func_name));
break;
}
}
@@ -1632,6 +1635,7 @@ mpt_mapresources(MPT_ADAPTER *ioc)
} else {
printk(MYIOC_s_WARN_FMT "no suitable DMA mask for %s\n",
ioc->name, pci_name(pdev));
+ pci_release_selected_regions(pdev, ioc->bars);
return r;
}
} else {
@@ -1645,6 +1649,7 @@ mpt_mapresources(MPT_ADAPTER *ioc)
} else {
printk(MYIOC_s_WARN_FMT "no suitable DMA mask for %s\n",
ioc->name, pci_name(pdev));
+ pci_release_selected_regions(pdev, ioc->bars);
return r;
}
}
@@ -1675,6 +1680,7 @@ mpt_mapresources(MPT_ADAPTER *ioc)
if (mem == NULL) {
printk(MYIOC_s_ERR_FMT ": ERROR - Unable to map adapter"
" memory!\n", ioc->name);
+ pci_release_selected_regions(pdev, ioc->bars);
return -EINVAL;
}
ioc->memmap = mem;
@@ -1770,7 +1776,6 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
ioc->req_sz = MPT_DEFAULT_FRAME_SIZE; /* avoid div by zero! */
ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
- ioc->pcidev = pdev;
spin_lock_init(&ioc->taskmgmt_lock);
mutex_init(&ioc->internal_cmds.mutex);
@@ -1913,6 +1918,9 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
ioc->msi_enable = 0;
break;
}
+
+ ioc->fw_events_off = 1;
+
if (ioc->errata_flag_1064)
pci_disable_io_access(pdev);
@@ -2051,7 +2059,6 @@ mpt_detach(struct pci_dev *pdev)
mpt_adapter_dispose(ioc);
- pci_set_drvdata(pdev, NULL);
}
/**************************************************************************
@@ -5062,8 +5069,9 @@ mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode)
if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET)
goto out;
if (!timeleft) {
- printk(KERN_DEBUG "%s: Issuing Reset from %s!!\n",
- ioc->name, __func__);
+ printk(MYIOC_s_WARN_FMT
+ "Issuing Reset from %s!!, doorbell=0x%08x\n",
+ ioc->name, __func__, mpt_GetIocState(ioc, 0));
mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
mpt_free_msg_frame(ioc, mf);
}
@@ -6454,8 +6462,9 @@ out:
mutex_unlock(&ioc->mptbase_cmds.mutex);
if (issue_hard_reset) {
issue_hard_reset = 0;
- printk(MYIOC_s_WARN_FMT "Issuing Reset from %s!!\n",
- ioc->name, __func__);
+ printk(MYIOC_s_WARN_FMT
+ "Issuing Reset from %s!!, doorbell=0x%08x\n",
+ ioc->name, __func__, mpt_GetIocState(ioc, 0));
if (retry_count == 0) {
if (mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP) != 0)
retry_count++;
@@ -6971,6 +6980,7 @@ mpt_SoftResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
if (ioc->taskmgmt_in_progress) {
+ ioc->ioc_reset_in_progress = 0;
spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
return -1;
}
@@ -7144,7 +7154,8 @@ mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag);
if (rc != 0) {
printk(KERN_WARNING MYNAM
- ": WARNING - (%d) Cannot recover %s\n", rc, ioc->name);
+ ": WARNING - (%d) Cannot recover %s, doorbell=0x%08x\n",
+ rc, ioc->name, mpt_GetIocState(ioc, 0));
} else {
if (ioc->hard_resets < -1)
ioc->hard_resets++;
@@ -7997,7 +8008,7 @@ mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info)
* Refer to lsi/mpi_log_sas.h.
**/
static void
-mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info)
+mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info, u8 cb_idx)
{
union loginfo_type {
u32 loginfo;
@@ -8051,21 +8062,22 @@ union loginfo_type {
if (sub_code_desc != NULL)
printk(MYIOC_s_INFO_FMT
"LogInfo(0x%08x): Originator={%s}, Code={%s},"
- " SubCode={%s}\n",
+ " SubCode={%s} cb_idx %s\n",
ioc->name, log_info, originator_desc, code_desc,
- sub_code_desc);
+ sub_code_desc, MptCallbacksName[cb_idx]);
else if (code_desc != NULL)
printk(MYIOC_s_INFO_FMT
"LogInfo(0x%08x): Originator={%s}, Code={%s},"
- " SubCode(0x%04x)\n",
+ " SubCode(0x%04x) cb_idx %s\n",
ioc->name, log_info, originator_desc, code_desc,
- sas_loginfo.dw.subcode);
+ sas_loginfo.dw.subcode, MptCallbacksName[cb_idx]);
else
printk(MYIOC_s_INFO_FMT
"LogInfo(0x%08x): Originator={%s}, Code=(0x%02x),"
- " SubCode(0x%04x)\n",
+ " SubCode(0x%04x) cb_idx %s\n",
ioc->name, log_info, originator_desc,
- sas_loginfo.dw.code, sas_loginfo.dw.subcode);
+ sas_loginfo.dw.code, sas_loginfo.dw.subcode,
+ MptCallbacksName[cb_idx]);
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -8430,7 +8442,8 @@ fusion_init(void)
/* Register ourselves (mptbase) in order to facilitate
* EventNotification handling.
*/
- mpt_base_index = mpt_register(mptbase_reply, MPTBASE_DRIVER);
+ mpt_base_index = mpt_register(mptbase_reply, MPTBASE_DRIVER,
+ "mptbase_reply");
/* Register for hard reset handling callbacks.
*/
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h
index b613eb3d470..23ed3dec72a 100644
--- a/drivers/message/fusion/mptbase.h
+++ b/drivers/message/fusion/mptbase.h
@@ -76,8 +76,8 @@
#define COPYRIGHT "Copyright (c) 1999-2008 " MODULEAUTHOR
#endif
-#define MPT_LINUX_VERSION_COMMON "3.04.15"
-#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.04.15"
+#define MPT_LINUX_VERSION_COMMON "3.04.17"
+#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.04.17"
#define WHAT_MAGIC_STRING "@" "(" "#" ")"
#define show_mptmod_ver(s,ver) \
@@ -396,6 +396,8 @@ typedef struct _VirtTarget {
u8 raidVolume; /* set, if RAID Volume */
u8 type; /* byte 0 of Inquiry data */
u8 deleted; /* target in process of being removed */
+ u8 inDMD; /* currently in the device
+ removal delay timer */
u32 num_luns;
} VirtTarget;
@@ -580,6 +582,7 @@ struct mptfc_rport_info
typedef void (*MPT_ADD_SGE)(void *pAddr, u32 flagslength, dma_addr_t dma_addr);
typedef void (*MPT_ADD_CHAIN)(void *pAddr, u8 next, u16 length,
dma_addr_t dma_addr);
+typedef void (*MPT_SCHEDULE_TARGET_RESET)(void *ioc);
/*
* Adapter Structure - pci_dev specific. Maximum: MPT_MAX_ADAPTERS
@@ -601,7 +604,7 @@ typedef struct _MPT_ADAPTER
u16 nvdata_version_default;
int debug_level;
u8 io_missing_delay;
- u8 device_missing_delay;
+ u16 device_missing_delay;
SYSIF_REGS __iomem *chip; /* == c8817000 (mmap) */
SYSIF_REGS __iomem *pio_chip; /* Programmed IO (downloadboot) */
u8 bus_type;
@@ -738,6 +741,7 @@ typedef struct _MPT_ADAPTER
int taskmgmt_in_progress;
u8 taskmgmt_quiesce_io;
u8 ioc_reset_in_progress;
+ MPT_SCHEDULE_TARGET_RESET schedule_target_reset;
struct work_struct sas_persist_task;
struct work_struct fc_setup_reset_work;
@@ -922,7 +926,8 @@ extern void mpt_detach(struct pci_dev *pdev);
extern int mpt_suspend(struct pci_dev *pdev, pm_message_t state);
extern int mpt_resume(struct pci_dev *pdev);
#endif
-extern u8 mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass);
+extern u8 mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass,
+ char *func_name);
extern void mpt_deregister(u8 cb_idx);
extern int mpt_event_register(u8 cb_idx, MPT_EVHANDLER ev_cbfunc);
extern void mpt_event_deregister(u8 cb_idx);
diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c
index f06b29193b4..d8ddfdf8be1 100644
--- a/drivers/message/fusion/mptctl.c
+++ b/drivers/message/fusion/mptctl.c
@@ -261,10 +261,16 @@ mptctl_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply)
/* We are done, issue wake up
*/
if (ioc->ioctl_cmds.status & MPT_MGMT_STATUS_PENDING) {
- if (req->u.hdr.Function == MPI_FUNCTION_SCSI_TASK_MGMT)
+ if (req->u.hdr.Function == MPI_FUNCTION_SCSI_TASK_MGMT) {
mpt_clear_taskmgmt_in_progress_flag(ioc);
- ioc->ioctl_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
- complete(&ioc->ioctl_cmds.done);
+ ioc->ioctl_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
+ complete(&ioc->ioctl_cmds.done);
+ if (ioc->bus_type == SAS)
+ ioc->schedule_target_reset(ioc);
+ } else {
+ ioc->ioctl_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
+ complete(&ioc->ioctl_cmds.done);
+ }
}
out_continuation:
@@ -298,6 +304,8 @@ mptctl_taskmgmt_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
mpt_clear_taskmgmt_in_progress_flag(ioc);
ioc->taskmgmt_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
complete(&ioc->taskmgmt_cmds.done);
+ if (ioc->bus_type == SAS)
+ ioc->schedule_target_reset(ioc);
return 1;
}
return 0;
@@ -946,9 +954,12 @@ retry_wait:
mpt_free_msg_frame(iocp, mf);
goto fwdl_out;
}
- if (!timeleft)
+ if (!timeleft) {
+ printk(MYIOC_s_WARN_FMT
+ "FW download timeout, doorbell=0x%08x\n",
+ iocp->name, mpt_GetIocState(iocp, 0));
mptctl_timeout_expired(iocp, mf);
- else
+ } else
goto retry_wait;
goto fwdl_out;
}
@@ -2293,6 +2304,10 @@ retry_wait:
goto done_free_mem;
}
if (!timeleft) {
+ printk(MYIOC_s_WARN_FMT
+ "mpt cmd timeout, doorbell=0x%08x"
+ " function=0x%x\n",
+ ioc->name, mpt_GetIocState(ioc, 0), function);
if (function == MPI_FUNCTION_SCSI_TASK_MGMT)
mutex_unlock(&ioc->taskmgmt_cmds.mutex);
mptctl_timeout_expired(ioc, mf);
@@ -2600,9 +2615,12 @@ retry_wait:
mpt_free_msg_frame(ioc, mf);
goto out;
}
- if (!timeleft)
+ if (!timeleft) {
+ printk(MYIOC_s_WARN_FMT
+ "HOST INFO command timeout, doorbell=0x%08x\n",
+ ioc->name, mpt_GetIocState(ioc, 0));
mptctl_timeout_expired(ioc, mf);
- else
+ } else
goto retry_wait;
goto out;
}
@@ -3000,7 +3018,8 @@ static int __init mptctl_init(void)
* Install our handler
*/
++where;
- mptctl_id = mpt_register(mptctl_reply, MPTCTL_DRIVER);
+ mptctl_id = mpt_register(mptctl_reply, MPTCTL_DRIVER,
+ "mptctl_reply");
if (!mptctl_id || mptctl_id >= MPT_MAX_PROTOCOL_DRIVERS) {
printk(KERN_ERR MYNAM ": ERROR: Failed to register with Fusion MPT base driver\n");
misc_deregister(&mptctl_miscdev);
@@ -3008,7 +3027,8 @@ static int __init mptctl_init(void)
goto out_fail;
}
- mptctl_taskmgmt_id = mpt_register(mptctl_taskmgmt_reply, MPTCTL_DRIVER);
+ mptctl_taskmgmt_id = mpt_register(mptctl_taskmgmt_reply, MPTCTL_DRIVER,
+ "mptctl_taskmgmt_reply");
if (!mptctl_taskmgmt_id || mptctl_taskmgmt_id >= MPT_MAX_PROTOCOL_DRIVERS) {
printk(KERN_ERR MYNAM ": ERROR: Failed to register with Fusion MPT base driver\n");
mpt_deregister(mptctl_id);
diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c
index b5f03ad8156..e15220ff52f 100644
--- a/drivers/message/fusion/mptfc.c
+++ b/drivers/message/fusion/mptfc.c
@@ -1472,9 +1472,12 @@ mptfc_init(void)
if (!mptfc_transport_template)
return -ENODEV;
- mptfcDoneCtx = mpt_register(mptscsih_io_done, MPTFC_DRIVER);
- mptfcTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTFC_DRIVER);
- mptfcInternalCtx = mpt_register(mptscsih_scandv_complete, MPTFC_DRIVER);
+ mptfcDoneCtx = mpt_register(mptscsih_io_done, MPTFC_DRIVER,
+ "mptscsih_scandv_complete");
+ mptfcTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTFC_DRIVER,
+ "mptscsih_scandv_complete");
+ mptfcInternalCtx = mpt_register(mptscsih_scandv_complete, MPTFC_DRIVER,
+ "mptscsih_scandv_complete");
mpt_event_register(mptfcDoneCtx, mptfc_event_process);
mpt_reset_register(mptfcDoneCtx, mptfc_ioc_reset);
diff --git a/drivers/message/fusion/mptlan.c b/drivers/message/fusion/mptlan.c
index 4fa9665cbe9..cbe96072a6c 100644
--- a/drivers/message/fusion/mptlan.c
+++ b/drivers/message/fusion/mptlan.c
@@ -1452,7 +1452,9 @@ static int __init mpt_lan_init (void)
{
show_mptmod_ver(LANAME, LANVER);
- if ((LanCtx = mpt_register(lan_reply, MPTLAN_DRIVER)) <= 0) {
+ LanCtx = mpt_register(lan_reply, MPTLAN_DRIVER,
+ "lan_reply");
+ if (LanCtx <= 0) {
printk (KERN_ERR MYNAM ": Failed to register with MPT base driver\n");
return -EBUSY;
}
diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c
index ac000e83db0..83a5115f025 100644
--- a/drivers/message/fusion/mptsas.c
+++ b/drivers/message/fusion/mptsas.c
@@ -57,6 +57,7 @@
#include <scsi/scsi_device.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_transport_sas.h>
+#include <scsi/scsi_transport.h>
#include <scsi/scsi_dbg.h>
#include "mptbase.h"
@@ -126,6 +127,7 @@ static void mptsas_scan_sas_topology(MPT_ADAPTER *ioc);
static void mptsas_broadcast_primative_work(struct fw_event_work *fw_event);
static void mptsas_handle_queue_full_event(struct fw_event_work *fw_event);
static void mptsas_volume_delete(MPT_ADAPTER *ioc, u8 id);
+void mptsas_schedule_target_reset(void *ioc);
static void mptsas_print_phy_data(MPT_ADAPTER *ioc,
MPI_SAS_IO_UNIT0_PHY_DATA *phy_data)
@@ -1139,6 +1141,44 @@ mptsas_target_reset_queue(MPT_ADAPTER *ioc,
}
/**
+ * mptsas_schedule_target_reset- send pending target reset
+ * @iocp: per adapter object
+ *
+ * This function will delete scheduled target reset from the list and
+ * try to send next target reset. This will be called from completion
+ * context of any Task managment command.
+ */
+
+void
+mptsas_schedule_target_reset(void *iocp)
+{
+ MPT_ADAPTER *ioc = (MPT_ADAPTER *)(iocp);
+ MPT_SCSI_HOST *hd = shost_priv(ioc->sh);
+ struct list_head *head = &hd->target_reset_list;
+ struct mptsas_target_reset_event *target_reset_list;
+ u8 id, channel;
+ /*
+ * issue target reset to next device in the queue
+ */
+
+ head = &hd->target_reset_list;
+ if (list_empty(head))
+ return;
+
+ target_reset_list = list_entry(head->next,
+ struct mptsas_target_reset_event, list);
+
+ id = target_reset_list->sas_event_data.TargetID;
+ channel = target_reset_list->sas_event_data.Bus;
+ target_reset_list->time_count = jiffies;
+
+ if (mptsas_target_reset(ioc, channel, id))
+ target_reset_list->target_reset_issued = 1;
+ return;
+}
+
+
+/**
* mptsas_taskmgmt_complete - complete SAS task management function
* @ioc: Pointer to MPT_ADAPTER structure
*
@@ -1222,28 +1262,12 @@ mptsas_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
* enable work queue to remove device from upper layers
*/
list_del(&target_reset_list->list);
- if ((mptsas_find_vtarget(ioc, channel, id)) && !ioc->fw_events_off)
+ if (!ioc->fw_events_off)
mptsas_queue_device_delete(ioc,
&target_reset_list->sas_event_data);
- /*
- * issue target reset to next device in the queue
- */
-
- head = &hd->target_reset_list;
- if (list_empty(head))
- return 1;
-
- target_reset_list = list_entry(head->next, struct mptsas_target_reset_event,
- list);
-
- id = target_reset_list->sas_event_data.TargetID;
- channel = target_reset_list->sas_event_data.Bus;
- target_reset_list->time_count = jiffies;
-
- if (mptsas_target_reset(ioc, channel, id))
- target_reset_list->target_reset_issued = 1;
+ ioc->schedule_target_reset(ioc);
return 1;
}
@@ -1889,6 +1913,48 @@ mptsas_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
return mptscsih_qcmd(SCpnt,done);
}
+/**
+ * mptsas_mptsas_eh_timed_out - resets the scsi_cmnd timeout
+ * if the device under question is currently in the
+ * device removal delay.
+ * @sc: scsi command that the midlayer is about to time out
+ *
+ **/
+static enum blk_eh_timer_return mptsas_eh_timed_out(struct scsi_cmnd *sc)
+{
+ MPT_SCSI_HOST *hd;
+ MPT_ADAPTER *ioc;
+ VirtDevice *vdevice;
+ enum blk_eh_timer_return rc = BLK_EH_NOT_HANDLED;
+
+ hd = shost_priv(sc->device->host);
+ if (hd == NULL) {
+ printk(KERN_ERR MYNAM ": %s: Can't locate host! (sc=%p)\n",
+ __func__, sc);
+ goto done;
+ }
+
+ ioc = hd->ioc;
+ if (ioc->bus_type != SAS) {
+ printk(KERN_ERR MYNAM ": %s: Wrong bus type (sc=%p)\n",
+ __func__, sc);
+ goto done;
+ }
+
+ vdevice = sc->device->hostdata;
+ if (vdevice && vdevice->vtarget && (vdevice->vtarget->inDMD
+ || vdevice->vtarget->deleted)) {
+ dtmprintk(ioc, printk(MYIOC_s_WARN_FMT ": %s: target removed "
+ "or in device removal delay (sc=%p)\n",
+ ioc->name, __func__, sc));
+ rc = BLK_EH_RESET_TIMER;
+ goto done;
+ }
+
+done:
+ return rc;
+}
+
static struct scsi_host_template mptsas_driver_template = {
.module = THIS_MODULE,
@@ -2364,7 +2430,7 @@ mptsas_sas_io_unit_pg1(MPT_ADAPTER *ioc)
SasIOUnitPage1_t *buffer;
dma_addr_t dma_handle;
int error;
- u16 device_missing_delay;
+ u8 device_missing_delay;
memset(&hdr, 0, sizeof(ConfigExtendedPageHeader_t));
memset(&cfg, 0, sizeof(CONFIGPARMS));
@@ -2401,7 +2467,7 @@ mptsas_sas_io_unit_pg1(MPT_ADAPTER *ioc)
ioc->io_missing_delay =
le16_to_cpu(buffer->IODeviceMissingDelay);
- device_missing_delay = le16_to_cpu(buffer->ReportDeviceMissingDelay);
+ device_missing_delay = buffer->ReportDeviceMissingDelay;
ioc->device_missing_delay = (device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_UNIT_16) ?
(device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_TIMEOUT_MASK) * 16 :
device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_TIMEOUT_MASK;
@@ -2549,6 +2615,7 @@ mptsas_sas_device_pg0(MPT_ADAPTER *ioc, struct mptsas_devinfo *device_info,
device_info->sas_address = le64_to_cpu(sas_address);
device_info->device_info =
le32_to_cpu(buffer->DeviceInfo);
+ device_info->flags = le16_to_cpu(buffer->Flags);
out_free_consistent:
pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
@@ -2960,6 +3027,7 @@ static int mptsas_probe_one_phy(struct device *dev,
struct sas_phy *phy;
struct sas_port *port;
int error = 0;
+ VirtTarget *vtarget;
if (!dev) {
error = -ENODEV;
@@ -3182,6 +3250,16 @@ static int mptsas_probe_one_phy(struct device *dev,
rphy_to_expander_device(rphy));
}
+ /* If the device exists,verify it wasn't previously flagged
+ as a missing device. If so, clear it */
+ vtarget = mptsas_find_vtarget(ioc,
+ phy_info->attached.channel,
+ phy_info->attached.id);
+ if (vtarget && vtarget->inDMD) {
+ printk(KERN_INFO "Device returned, unsetting inDMD\n");
+ vtarget->inDMD = 0;
+ }
+
out:
return error;
}
@@ -3635,9 +3713,42 @@ mptsas_send_link_status_event(struct fw_event_work *fw_event)
MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION)
phy_info->phy->negotiated_linkrate =
SAS_LINK_RATE_FAILED;
- else
+ else {
phy_info->phy->negotiated_linkrate =
SAS_LINK_RATE_UNKNOWN;
+ if (ioc->device_missing_delay &&
+ mptsas_is_end_device(&phy_info->attached)) {
+ struct scsi_device *sdev;
+ VirtDevice *vdevice;
+ u8 channel, id;
+ id = phy_info->attached.id;
+ channel = phy_info->attached.channel;
+ devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
+ "Link down for fw_id %d:fw_channel %d\n",
+ ioc->name, phy_info->attached.id,
+ phy_info->attached.channel));
+
+ shost_for_each_device(sdev, ioc->sh) {
+ vdevice = sdev->hostdata;
+ if ((vdevice == NULL) ||
+ (vdevice->vtarget == NULL))
+ continue;
+ if ((vdevice->vtarget->tflags &
+ MPT_TARGET_FLAGS_RAID_COMPONENT ||
+ vdevice->vtarget->raidVolume))
+ continue;
+ if (vdevice->vtarget->id == id &&
+ vdevice->vtarget->channel ==
+ channel)
+ devtprintk(ioc,
+ printk(MYIOC_s_DEBUG_FMT
+ "SDEV OUTSTANDING CMDS"
+ "%d\n", ioc->name,
+ sdev->device_busy));
+ }
+
+ }
+ }
}
out:
mptsas_free_fw_event(ioc, fw_event);
@@ -3840,6 +3951,13 @@ mptsas_probe_devices(MPT_ADAPTER *ioc)
MPI_SAS_DEVICE_INFO_SATA_DEVICE)) == 0)
continue;
+ /* If there is no FW B_T mapping for this device then continue
+ * */
+ if (!(sas_device.flags & MPI_SAS_DEVICE0_FLAGS_DEVICE_PRESENT)
+ || !(sas_device.flags &
+ MPI_SAS_DEVICE0_FLAGS_DEVICE_MAPPED))
+ continue;
+
phy_info = mptsas_refreshing_device_handles(ioc, &sas_device);
if (!phy_info)
continue;
@@ -4149,6 +4267,14 @@ mptsas_adding_inactive_raid_components(MPT_ADAPTER *ioc, u8 channel, u8 id)
phys_disk.PhysDiskID))
continue;
+ /* If there is no FW B_T mapping for this device then continue
+ * */
+ if (!(sas_device.flags & MPI_SAS_DEVICE0_FLAGS_DEVICE_PRESENT)
+ || !(sas_device.flags &
+ MPI_SAS_DEVICE0_FLAGS_DEVICE_MAPPED))
+ continue;
+
+
phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
sas_device.sas_address);
mptsas_add_end_device(ioc, phy_info);
@@ -4171,6 +4297,7 @@ mptsas_hotplug_work(MPT_ADAPTER *ioc, struct fw_event_work *fw_event,
struct mptsas_devinfo sas_device;
VirtTarget *vtarget;
int i;
+ struct mptsas_portinfo *port_info;
switch (hot_plug_info->event_type) {
@@ -4199,12 +4326,47 @@ mptsas_hotplug_work(MPT_ADAPTER *ioc, struct fw_event_work *fw_event,
(hot_plug_info->channel << 8) +
hot_plug_info->id);
+ /* If there is no FW B_T mapping for this device then break
+ * */
+ if (!(sas_device.flags & MPI_SAS_DEVICE0_FLAGS_DEVICE_PRESENT)
+ || !(sas_device.flags &
+ MPI_SAS_DEVICE0_FLAGS_DEVICE_MAPPED))
+ break;
+
if (!sas_device.handle)
return;
phy_info = mptsas_refreshing_device_handles(ioc, &sas_device);
- if (!phy_info)
+ /* Only For SATA Device ADD */
+ if (!phy_info && (sas_device.device_info &
+ MPI_SAS_DEVICE_INFO_SATA_DEVICE)) {
+ devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
+ "%s %d SATA HOT PLUG: "
+ "parent handle of device %x\n", ioc->name,
+ __func__, __LINE__, sas_device.handle_parent));
+ port_info = mptsas_find_portinfo_by_handle(ioc,
+ sas_device.handle_parent);
+
+ if (port_info == ioc->hba_port_info)
+ mptsas_probe_hba_phys(ioc);
+ else if (port_info)
+ mptsas_expander_refresh(ioc, port_info);
+ else {
+ dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
+ "%s %d port info is NULL\n",
+ ioc->name, __func__, __LINE__));
+ break;
+ }
+ phy_info = mptsas_refreshing_device_handles
+ (ioc, &sas_device);
+ }
+
+ if (!phy_info) {
+ dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
+ "%s %d phy info is NULL\n",
+ ioc->name, __func__, __LINE__));
break;
+ }
if (mptsas_get_rphy(phy_info))
break;
@@ -4241,6 +4403,13 @@ mptsas_hotplug_work(MPT_ADAPTER *ioc, struct fw_event_work *fw_event,
break;
}
+ /* If there is no FW B_T mapping for this device then break
+ * */
+ if (!(sas_device.flags & MPI_SAS_DEVICE0_FLAGS_DEVICE_PRESENT)
+ || !(sas_device.flags &
+ MPI_SAS_DEVICE0_FLAGS_DEVICE_MAPPED))
+ break;
+
phy_info = mptsas_find_phyinfo_by_sas_address(
ioc, sas_device.sas_address);
@@ -4294,6 +4463,13 @@ mptsas_hotplug_work(MPT_ADAPTER *ioc, struct fw_event_work *fw_event,
break;
}
+ /* If there is no FW B_T mapping for this device then break
+ * */
+ if (!(sas_device.flags & MPI_SAS_DEVICE0_FLAGS_DEVICE_PRESENT)
+ || !(sas_device.flags &
+ MPI_SAS_DEVICE0_FLAGS_DEVICE_MAPPED))
+ break;
+
phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
sas_device.sas_address);
if (!phy_info) {
@@ -4727,8 +4903,9 @@ mptsas_broadcast_primative_work(struct fw_event_work *fw_event)
mutex_unlock(&ioc->taskmgmt_cmds.mutex);
if (issue_reset) {
- printk(MYIOC_s_WARN_FMT "Issuing Reset from %s!!\n",
- ioc->name, __func__);
+ printk(MYIOC_s_WARN_FMT
+ "Issuing Reset from %s!! doorbell=0x%08x\n",
+ ioc->name, __func__, mpt_GetIocState(ioc, 0));
mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
}
mptsas_free_fw_event(ioc, fw_event);
@@ -4816,12 +4993,47 @@ mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply)
{
EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data =
(EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *)reply->Data;
+ u16 ioc_stat;
+ ioc_stat = le16_to_cpu(reply->IOCStatus);
if (sas_event_data->ReasonCode ==
MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING) {
mptsas_target_reset_queue(ioc, sas_event_data);
return 0;
}
+ if (sas_event_data->ReasonCode ==
+ MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET &&
+ ioc->device_missing_delay &&
+ (ioc_stat & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE)) {
+ VirtTarget *vtarget = NULL;
+ u8 id, channel;
+ u32 log_info = le32_to_cpu(reply->IOCLogInfo);
+
+ id = sas_event_data->TargetID;
+ channel = sas_event_data->Bus;
+
+ vtarget = mptsas_find_vtarget(ioc, channel, id);
+ if (vtarget) {
+ devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
+ "LogInfo (0x%x) available for "
+ "INTERNAL_DEVICE_RESET"
+ "fw_id %d fw_channel %d\n", ioc->name,
+ log_info, id, channel));
+ if (vtarget->raidVolume) {
+ devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
+ "Skipping Raid Volume for inDMD\n",
+ ioc->name));
+ } else {
+ devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
+ "Setting device flag inDMD\n",
+ ioc->name));
+ vtarget->inDMD = 1;
+ }
+
+ }
+
+ }
+
break;
}
case MPI_EVENT_SAS_EXPANDER_STATUS_CHANGE:
@@ -4924,7 +5136,7 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
ioc->DoneCtx = mptsasDoneCtx;
ioc->TaskCtx = mptsasTaskCtx;
ioc->InternalCtx = mptsasInternalCtx;
-
+ ioc->schedule_target_reset = &mptsas_schedule_target_reset;
/* Added sanity check on readiness of the MPT adapter.
*/
if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
@@ -5154,14 +5366,20 @@ mptsas_init(void)
sas_attach_transport(&mptsas_transport_functions);
if (!mptsas_transport_template)
return -ENODEV;
+ mptsas_transport_template->eh_timed_out = mptsas_eh_timed_out;
- mptsasDoneCtx = mpt_register(mptscsih_io_done, MPTSAS_DRIVER);
- mptsasTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSAS_DRIVER);
+ mptsasDoneCtx = mpt_register(mptscsih_io_done, MPTSAS_DRIVER,
+ "mptscsih_io_done");
+ mptsasTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSAS_DRIVER,
+ "mptscsih_taskmgmt_complete");
mptsasInternalCtx =
- mpt_register(mptscsih_scandv_complete, MPTSAS_DRIVER);
- mptsasMgmtCtx = mpt_register(mptsas_mgmt_done, MPTSAS_DRIVER);
+ mpt_register(mptscsih_scandv_complete, MPTSAS_DRIVER,
+ "mptscsih_scandv_complete");
+ mptsasMgmtCtx = mpt_register(mptsas_mgmt_done, MPTSAS_DRIVER,
+ "mptsas_mgmt_done");
mptsasDeviceResetCtx =
- mpt_register(mptsas_taskmgmt_complete, MPTSAS_DRIVER);
+ mpt_register(mptsas_taskmgmt_complete, MPTSAS_DRIVER,
+ "mptsas_taskmgmt_complete");
mpt_event_register(mptsasDoneCtx, mptsas_event_process);
mpt_reset_register(mptsasDoneCtx, mptsas_ioc_reset);
diff --git a/drivers/message/fusion/mptsas.h b/drivers/message/fusion/mptsas.h
index 7b249edbda7..57e86ab7766 100644
--- a/drivers/message/fusion/mptsas.h
+++ b/drivers/message/fusion/mptsas.h
@@ -140,6 +140,7 @@ struct mptsas_devinfo {
u64 sas_address; /* WWN of this device,
SATA is assigned by HBA,expander */
u32 device_info; /* bitfield detailed info about this device */
+ u16 flags; /* sas device pg0 flags */
};
/*
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
index 5c53624e0e8..59b8f53d1ec 100644
--- a/drivers/message/fusion/mptscsih.c
+++ b/drivers/message/fusion/mptscsih.c
@@ -664,6 +664,7 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
u32 log_info;
status = le16_to_cpu(pScsiReply->IOCStatus) & MPI_IOCSTATUS_MASK;
+
scsi_state = pScsiReply->SCSIState;
scsi_status = pScsiReply->SCSIStatus;
xfer_cnt = le32_to_cpu(pScsiReply->TransferCount);
@@ -738,13 +739,36 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
if ( ioc->bus_type == SAS ) {
- u16 ioc_status = le16_to_cpu(pScsiReply->IOCStatus);
- if (ioc_status & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
- if ((log_info & SAS_LOGINFO_MASK)
- == SAS_LOGINFO_NEXUS_LOSS) {
- sc->result = (DID_BUS_BUSY << 16);
- break;
- }
+ u16 ioc_status =
+ le16_to_cpu(pScsiReply->IOCStatus);
+ if ((ioc_status &
+ MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE)
+ &&
+ ((log_info & SAS_LOGINFO_MASK) ==
+ SAS_LOGINFO_NEXUS_LOSS)) {
+ VirtDevice *vdevice =
+ sc->device->hostdata;
+
+ /* flag the device as being in
+ * device removal delay so we can
+ * notify the midlayer to hold off
+ * on timeout eh */
+ if (vdevice && vdevice->
+ vtarget &&
+ vdevice->vtarget->
+ raidVolume)
+ printk(KERN_INFO
+ "Skipping Raid Volume"
+ "for inDMD\n");
+ else if (vdevice &&
+ vdevice->vtarget)
+ vdevice->vtarget->
+ inDMD = 1;
+
+ sc->result =
+ (DID_TRANSPORT_DISRUPTED
+ << 16);
+ break;
}
} else if (ioc->bus_type == FC) {
/*
@@ -1704,8 +1728,9 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun,
CLEAR_MGMT_STATUS(ioc->taskmgmt_cmds.status)
if (issue_hard_reset) {
- printk(MYIOC_s_WARN_FMT "Issuing Reset from %s!!\n",
- ioc->name, __func__);
+ printk(MYIOC_s_WARN_FMT
+ "Issuing Reset from %s!! doorbell=0x%08x\n",
+ ioc->name, __func__, mpt_GetIocState(ioc, 0));
retval = mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
mpt_free_msg_frame(ioc, mf);
}
@@ -2132,6 +2157,8 @@ mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf,
mpt_clear_taskmgmt_in_progress_flag(ioc);
ioc->taskmgmt_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
complete(&ioc->taskmgmt_cmds.done);
+ if (ioc->bus_type == SAS)
+ ioc->schedule_target_reset(ioc);
return 1;
}
return 0;
@@ -2459,6 +2486,8 @@ mptscsih_slave_configure(struct scsi_device *sdev)
ioc->name,sdev->tagged_supported, sdev->simple_tags,
sdev->ordered_tags));
+ blk_queue_dma_alignment (sdev->request_queue, 512 - 1);
+
return 0;
}
@@ -3045,8 +3074,11 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
goto out;
}
if (!timeleft) {
- printk(MYIOC_s_WARN_FMT "Issuing Reset from %s!!\n",
- ioc->name, __func__);
+ printk(MYIOC_s_WARN_FMT
+ "Issuing Reset from %s!! doorbell=0x%08xh"
+ " cmd=0x%02x\n",
+ ioc->name, __func__, mpt_GetIocState(ioc, 0),
+ cmd);
mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
mpt_free_msg_frame(ioc, mf);
}
diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c
index 1abaa5d01ae..0e2803155ae 100644
--- a/drivers/message/fusion/mptspi.c
+++ b/drivers/message/fusion/mptspi.c
@@ -1551,9 +1551,12 @@ mptspi_init(void)
if (!mptspi_transport_template)
return -ENODEV;
- mptspiDoneCtx = mpt_register(mptscsih_io_done, MPTSPI_DRIVER);
- mptspiTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSPI_DRIVER);
- mptspiInternalCtx = mpt_register(mptscsih_scandv_complete, MPTSPI_DRIVER);
+ mptspiDoneCtx = mpt_register(mptscsih_io_done, MPTSPI_DRIVER,
+ "mptscsih_io_done");
+ mptspiTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSPI_DRIVER,
+ "mptscsih_taskmgmt_complete");
+ mptspiInternalCtx = mpt_register(mptscsih_scandv_complete,
+ MPTSPI_DRIVER, "mptscsih_scandv_complete");
mpt_event_register(mptspiDoneCtx, mptspi_event_process);
mpt_reset_register(mptspiDoneCtx, mptspi_ioc_reset);
diff --git a/drivers/misc/enclosure.c b/drivers/misc/enclosure.c
index 48c84a58163..00e5fcac8fd 100644
--- a/drivers/misc/enclosure.c
+++ b/drivers/misc/enclosure.c
@@ -285,8 +285,11 @@ enclosure_component_register(struct enclosure_device *edev,
cdev->groups = enclosure_groups;
err = device_register(cdev);
- if (err)
- ERR_PTR(err);
+ if (err) {
+ ecomp->number = -1;
+ put_device(cdev);
+ return ERR_PTR(err);
+ }
return ecomp;
}
diff --git a/drivers/s390/cio/qdio_setup.c b/drivers/s390/cio/qdio_setup.c
index 6326b67c45d..34c7e4046df 100644
--- a/drivers/s390/cio/qdio_setup.c
+++ b/drivers/s390/cio/qdio_setup.c
@@ -368,6 +368,8 @@ static void setup_qib(struct qdio_irq *irq_ptr,
if (qebsm_possible())
irq_ptr->qib.rflags |= QIB_RFLAGS_ENABLE_QEBSM;
+ irq_ptr->qib.rflags |= init_data->qib_rflags;
+
irq_ptr->qib.qfmt = init_data->q_format;
if (init_data->no_input_qs)
irq_ptr->qib.isliba =
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c
index e331df2122f..96fa1f53639 100644
--- a/drivers/s390/scsi/zfcp_aux.c
+++ b/drivers/s390/scsi/zfcp_aux.c
@@ -98,13 +98,11 @@ static void __init zfcp_init_device_setup(char *devstr)
u64 wwpn, lun;
/* duplicate devstr and keep the original for sysfs presentation*/
- str_saved = kmalloc(strlen(devstr) + 1, GFP_KERNEL);
+ str_saved = kstrdup(devstr, GFP_KERNEL);
str = str_saved;
if (!str)
return;
- strcpy(str, devstr);
-
token = strsep(&str, ",");
if (!token || strlen(token) >= ZFCP_BUS_ID_SIZE)
goto err_out;
@@ -314,7 +312,7 @@ struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *port, u64 fcp_lun)
}
retval = -EINVAL;
- INIT_WORK(&unit->scsi_work, zfcp_scsi_scan);
+ INIT_WORK(&unit->scsi_work, zfcp_scsi_scan_work);
spin_lock_init(&unit->latencies.lock);
unit->latencies.write.channel.min = 0xFFFFFFFF;
@@ -526,6 +524,10 @@ struct zfcp_adapter *zfcp_adapter_enqueue(struct ccw_device *ccw_device)
rwlock_init(&adapter->port_list_lock);
INIT_LIST_HEAD(&adapter->port_list);
+ INIT_LIST_HEAD(&adapter->events.list);
+ INIT_WORK(&adapter->events.work, zfcp_fc_post_event);
+ spin_lock_init(&adapter->events.list_lock);
+
init_waitqueue_head(&adapter->erp_ready_wq);
init_waitqueue_head(&adapter->erp_done_wqh);
diff --git a/drivers/s390/scsi/zfcp_cfdc.c b/drivers/s390/scsi/zfcp_cfdc.c
index 1a2db0a3573..fcbd2b756da 100644
--- a/drivers/s390/scsi/zfcp_cfdc.c
+++ b/drivers/s390/scsi/zfcp_cfdc.c
@@ -189,18 +189,12 @@ static long zfcp_cfdc_dev_ioctl(struct file *file, unsigned int command,
if (!fsf_cfdc)
return -ENOMEM;
- data = kmalloc(sizeof(struct zfcp_cfdc_data), GFP_KERNEL);
- if (!data) {
- retval = -ENOMEM;
+ data = memdup_user(data_user, sizeof(*data_user));
+ if (IS_ERR(data)) {
+ retval = PTR_ERR(data);
goto no_mem_sense;
}
- retval = copy_from_user(data, data_user, sizeof(*data));
- if (retval) {
- retval = -EFAULT;
- goto free_buffer;
- }
-
if (data->signature != 0xCFDCACDF) {
retval = -EINVAL;
goto free_buffer;
diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c
index 075852f6968..a86117b0d6e 100644
--- a/drivers/s390/scsi/zfcp_dbf.c
+++ b/drivers/s390/scsi/zfcp_dbf.c
@@ -155,6 +155,8 @@ void _zfcp_dbf_hba_fsf_response(const char *tag2, int level,
if (scsi_cmnd) {
response->u.fcp.cmnd = (unsigned long)scsi_cmnd;
response->u.fcp.serial = scsi_cmnd->serial_number;
+ response->u.fcp.data_dir =
+ qtcb->bottom.io.data_direction;
}
break;
@@ -326,6 +328,7 @@ static void zfcp_dbf_hba_view_response(char **p,
case FSF_QTCB_FCP_CMND:
if (r->fsf_req_status & ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT)
break;
+ zfcp_dbf_out(p, "data_direction", "0x%04x", r->u.fcp.data_dir);
zfcp_dbf_out(p, "scsi_cmnd", "0x%0Lx", r->u.fcp.cmnd);
zfcp_dbf_out(p, "scsi_serial", "0x%016Lx", r->u.fcp.serial);
*p += sprintf(*p, "\n");
@@ -1005,7 +1008,7 @@ int zfcp_dbf_adapter_register(struct zfcp_adapter *adapter)
char dbf_name[DEBUG_MAX_NAME_LEN];
struct zfcp_dbf *dbf;
- dbf = kmalloc(sizeof(struct zfcp_dbf), GFP_KERNEL);
+ dbf = kzalloc(sizeof(struct zfcp_dbf), GFP_KERNEL);
if (!dbf)
return -ENOMEM;
diff --git a/drivers/s390/scsi/zfcp_dbf.h b/drivers/s390/scsi/zfcp_dbf.h
index 457e046f2d2..2bcc3403126 100644
--- a/drivers/s390/scsi/zfcp_dbf.h
+++ b/drivers/s390/scsi/zfcp_dbf.h
@@ -111,6 +111,7 @@ struct zfcp_dbf_hba_record_response {
struct {
u64 cmnd;
u64 serial;
+ u32 data_dir;
} fcp;
struct {
u64 wwpn;
diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h
index 9fa1b064893..e1c6b6e05a7 100644
--- a/drivers/s390/scsi/zfcp_def.h
+++ b/drivers/s390/scsi/zfcp_def.h
@@ -37,6 +37,7 @@
#include <asm/ebcdic.h>
#include <asm/sysinfo.h>
#include "zfcp_fsf.h"
+#include "zfcp_fc.h"
#include "zfcp_qdio.h"
struct zfcp_reqlist;
@@ -72,10 +73,12 @@ struct zfcp_reqlist;
/* adapter status */
#define ZFCP_STATUS_ADAPTER_QDIOUP 0x00000002
+#define ZFCP_STATUS_ADAPTER_SIOSL_ISSUED 0x00000004
#define ZFCP_STATUS_ADAPTER_XCONFIG_OK 0x00000008
#define ZFCP_STATUS_ADAPTER_HOST_CON_INIT 0x00000010
#define ZFCP_STATUS_ADAPTER_ERP_PENDING 0x00000100
#define ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED 0x00000200
+#define ZFCP_STATUS_ADAPTER_DATA_DIV_ENABLED 0x00000400
/* remote port status */
#define ZFCP_STATUS_PORT_PHYS_OPEN 0x00000001
@@ -190,6 +193,7 @@ struct zfcp_adapter {
struct service_level service_level;
struct workqueue_struct *work_queue;
struct device_dma_parameters dma_parms;
+ struct zfcp_fc_events events;
};
struct zfcp_port {
@@ -212,6 +216,7 @@ struct zfcp_port {
struct work_struct test_link_work;
struct work_struct rport_work;
enum { RPORT_NONE, RPORT_ADD, RPORT_DEL } rport_task;
+ unsigned int starget_id;
};
struct zfcp_unit {
diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c
index fd068bc1bd0..160b432c907 100644
--- a/drivers/s390/scsi/zfcp_erp.c
+++ b/drivers/s390/scsi/zfcp_erp.c
@@ -141,9 +141,13 @@ static int zfcp_erp_required_act(int want, struct zfcp_adapter *adapter,
if (!(p_status & ZFCP_STATUS_COMMON_UNBLOCKED))
need = ZFCP_ERP_ACTION_REOPEN_PORT;
/* fall through */
- case ZFCP_ERP_ACTION_REOPEN_PORT:
case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED:
p_status = atomic_read(&port->status);
+ if (!(p_status & ZFCP_STATUS_COMMON_OPEN))
+ need = ZFCP_ERP_ACTION_REOPEN_PORT;
+ /* fall through */
+ case ZFCP_ERP_ACTION_REOPEN_PORT:
+ p_status = atomic_read(&port->status);
if (p_status & ZFCP_STATUS_COMMON_ERP_INUSE)
return 0;
a_status = atomic_read(&adapter->status);
@@ -893,8 +897,7 @@ static int zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *act)
}
if (port->d_id && !(p_status & ZFCP_STATUS_COMMON_NOESC)) {
port->d_id = 0;
- _zfcp_erp_port_reopen(port, 0, "erpsoc1", NULL);
- return ZFCP_ERP_EXIT;
+ return ZFCP_ERP_FAILED;
}
/* fall through otherwise */
}
@@ -1188,19 +1191,14 @@ static void zfcp_erp_action_cleanup(struct zfcp_erp_action *act, int result)
switch (act->action) {
case ZFCP_ERP_ACTION_REOPEN_UNIT:
- if ((result == ZFCP_ERP_SUCCEEDED) && !unit->device) {
- get_device(&unit->dev);
- if (scsi_queue_work(unit->port->adapter->scsi_host,
- &unit->scsi_work) <= 0)
- put_device(&unit->dev);
- }
put_device(&unit->dev);
break;
- case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED:
case ZFCP_ERP_ACTION_REOPEN_PORT:
if (result == ZFCP_ERP_SUCCEEDED)
zfcp_scsi_schedule_rport_register(port);
+ /* fall through */
+ case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED:
put_device(&port->dev);
break;
@@ -1247,6 +1245,11 @@ static int zfcp_erp_strategy(struct zfcp_erp_action *erp_action)
goto unlock;
}
+ if (erp_action->status & ZFCP_STATUS_ERP_TIMEDOUT) {
+ retval = ZFCP_ERP_FAILED;
+ goto check_target;
+ }
+
zfcp_erp_action_to_running(erp_action);
/* no lock to allow for blocking operations */
@@ -1279,6 +1282,7 @@ static int zfcp_erp_strategy(struct zfcp_erp_action *erp_action)
goto unlock;
}
+check_target:
retval = zfcp_erp_strategy_check_target(erp_action, retval);
zfcp_erp_action_dequeue(erp_action);
retval = zfcp_erp_strategy_statechange(erp_action, retval);
diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h
index 48a8f93b72f..3b93239c6f6 100644
--- a/drivers/s390/scsi/zfcp_ext.h
+++ b/drivers/s390/scsi/zfcp_ext.h
@@ -96,6 +96,9 @@ extern void zfcp_erp_adapter_access_changed(struct zfcp_adapter *, char *,
extern void zfcp_erp_timeout_handler(unsigned long);
/* zfcp_fc.c */
+extern void zfcp_fc_enqueue_event(struct zfcp_adapter *,
+ enum fc_host_event_code event_code, u32);
+extern void zfcp_fc_post_event(struct work_struct *);
extern void zfcp_fc_scan_ports(struct work_struct *);
extern void zfcp_fc_incoming_els(struct zfcp_fsf_req *);
extern void zfcp_fc_port_did_lookup(struct work_struct *);
@@ -146,9 +149,10 @@ extern void zfcp_qdio_destroy(struct zfcp_qdio *);
extern int zfcp_qdio_sbal_get(struct zfcp_qdio *);
extern int zfcp_qdio_send(struct zfcp_qdio *, struct zfcp_qdio_req *);
extern int zfcp_qdio_sbals_from_sg(struct zfcp_qdio *, struct zfcp_qdio_req *,
- struct scatterlist *, int);
+ struct scatterlist *);
extern int zfcp_qdio_open(struct zfcp_qdio *);
extern void zfcp_qdio_close(struct zfcp_qdio *);
+extern void zfcp_qdio_siosl(struct zfcp_adapter *);
/* zfcp_scsi.c */
extern struct zfcp_data zfcp_data;
@@ -159,7 +163,10 @@ extern void zfcp_scsi_rport_work(struct work_struct *);
extern void zfcp_scsi_schedule_rport_register(struct zfcp_port *);
extern void zfcp_scsi_schedule_rport_block(struct zfcp_port *);
extern void zfcp_scsi_schedule_rports_block(struct zfcp_adapter *);
-extern void zfcp_scsi_scan(struct work_struct *);
+extern void zfcp_scsi_scan(struct zfcp_unit *);
+extern void zfcp_scsi_scan_work(struct work_struct *);
+extern void zfcp_scsi_set_prot(struct zfcp_adapter *);
+extern void zfcp_scsi_dif_sense_error(struct scsi_cmnd *, int);
/* zfcp_sysfs.c */
extern struct attribute_group zfcp_sysfs_unit_attrs;
diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c
index 6f8ab43a485..6f3ed2b9a34 100644
--- a/drivers/s390/scsi/zfcp_fc.c
+++ b/drivers/s390/scsi/zfcp_fc.c
@@ -23,6 +23,58 @@ static u32 zfcp_fc_rscn_range_mask[] = {
[ELS_ADDR_FMT_FAB] = 0x000000,
};
+/**
+ * zfcp_fc_post_event - post event to userspace via fc_transport
+ * @work: work struct with enqueued events
+ */
+void zfcp_fc_post_event(struct work_struct *work)
+{
+ struct zfcp_fc_event *event = NULL, *tmp = NULL;
+ LIST_HEAD(tmp_lh);
+ struct zfcp_fc_events *events = container_of(work,
+ struct zfcp_fc_events, work);
+ struct zfcp_adapter *adapter = container_of(events, struct zfcp_adapter,
+ events);
+
+ spin_lock_bh(&events->list_lock);
+ list_splice_init(&events->list, &tmp_lh);
+ spin_unlock_bh(&events->list_lock);
+
+ list_for_each_entry_safe(event, tmp, &tmp_lh, list) {
+ fc_host_post_event(adapter->scsi_host, fc_get_event_number(),
+ event->code, event->data);
+ list_del(&event->list);
+ kfree(event);
+ }
+
+}
+
+/**
+ * zfcp_fc_enqueue_event - safely enqueue FC HBA API event from irq context
+ * @adapter: The adapter where to enqueue the event
+ * @event_code: The event code (as defined in fc_host_event_code in
+ * scsi_transport_fc.h)
+ * @event_data: The event data (e.g. n_port page in case of els)
+ */
+void zfcp_fc_enqueue_event(struct zfcp_adapter *adapter,
+ enum fc_host_event_code event_code, u32 event_data)
+{
+ struct zfcp_fc_event *event;
+
+ event = kmalloc(sizeof(struct zfcp_fc_event), GFP_ATOMIC);
+ if (!event)
+ return;
+
+ event->code = event_code;
+ event->data = event_data;
+
+ spin_lock(&adapter->events.list_lock);
+ list_add_tail(&event->list, &adapter->events.list);
+ spin_unlock(&adapter->events.list_lock);
+
+ queue_work(adapter->work_queue, &adapter->events.work);
+}
+
static int zfcp_fc_wka_port_get(struct zfcp_fc_wka_port *wka_port)
{
if (mutex_lock_interruptible(&wka_port->mutex))
@@ -148,6 +200,8 @@ static void zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req)
afmt = page->rscn_page_flags & ELS_RSCN_ADDR_FMT_MASK;
_zfcp_fc_incoming_rscn(fsf_req, zfcp_fc_rscn_range_mask[afmt],
page);
+ zfcp_fc_enqueue_event(fsf_req->adapter, FCH_EVT_RSCN,
+ *(u32 *)page);
}
queue_work(fsf_req->adapter->work_queue, &fsf_req->adapter->scan_work);
}
diff --git a/drivers/s390/scsi/zfcp_fc.h b/drivers/s390/scsi/zfcp_fc.h
index 0747b087390..938d5036016 100644
--- a/drivers/s390/scsi/zfcp_fc.h
+++ b/drivers/s390/scsi/zfcp_fc.h
@@ -30,6 +30,30 @@
#define ZFCP_FC_CTELS_TMO (2 * FC_DEF_R_A_TOV / 1000)
/**
+ * struct zfcp_fc_event - FC HBAAPI event for internal queueing from irq context
+ * @code: Event code
+ * @data: Event data
+ * @list: list_head for zfcp_fc_events list
+ */
+struct zfcp_fc_event {
+ enum fc_host_event_code code;
+ u32 data;
+ struct list_head list;
+};
+
+/**
+ * struct zfcp_fc_events - Infrastructure for posting FC events from irq context
+ * @list: List for queueing of events from irq context to workqueue
+ * @list_lock: Lock for event list
+ * @work: work_struct for forwarding events in workqueue
+*/
+struct zfcp_fc_events {
+ struct list_head list;
+ spinlock_t list_lock;
+ struct work_struct work;
+};
+
+/**
* struct zfcp_fc_gid_pn_req - container for ct header plus gid_pn request
* @ct_hdr: FC GS common transport header
* @gid_pn: GID_PN request
@@ -196,6 +220,9 @@ void zfcp_fc_scsi_to_fcp(struct fcp_cmnd *fcp, struct scsi_cmnd *scsi)
memcpy(fcp->fc_cdb, scsi->cmnd, scsi->cmd_len);
fcp->fc_dl = scsi_bufflen(scsi);
+
+ if (scsi_get_prot_type(scsi) == SCSI_PROT_DIF_TYPE1)
+ fcp->fc_dl += fcp->fc_dl / scsi->device->sector_size * 8;
}
/**
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index 71663fb7731..9d1d7d1842c 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -21,6 +21,7 @@
static void zfcp_fsf_request_timeout_handler(unsigned long data)
{
struct zfcp_adapter *adapter = (struct zfcp_adapter *) data;
+ zfcp_qdio_siosl(adapter);
zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED,
"fsrth_1", NULL);
}
@@ -274,6 +275,7 @@ static void zfcp_fsf_status_read_handler(struct zfcp_fsf_req *req)
break;
case FSF_STATUS_READ_LINK_DOWN:
zfcp_fsf_status_read_link_down(req);
+ zfcp_fc_enqueue_event(adapter, FCH_EVT_LINKDOWN, 0);
break;
case FSF_STATUS_READ_LINK_UP:
dev_info(&adapter->ccw_device->dev,
@@ -286,6 +288,8 @@ static void zfcp_fsf_status_read_handler(struct zfcp_fsf_req *req)
ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED |
ZFCP_STATUS_COMMON_ERP_FAILED,
"fssrh_2", req);
+ zfcp_fc_enqueue_event(adapter, FCH_EVT_LINKUP, 0);
+
break;
case FSF_STATUS_READ_NOTIFICATION_LOST:
if (sr_buf->status_subtype & FSF_STATUS_READ_SUB_ACT_UPDATED)
@@ -323,6 +327,7 @@ static void zfcp_fsf_fsfstatus_qual_eval(struct zfcp_fsf_req *req)
dev_err(&req->adapter->ccw_device->dev,
"The FCP adapter reported a problem "
"that cannot be recovered\n");
+ zfcp_qdio_siosl(req->adapter);
zfcp_erp_adapter_shutdown(req->adapter, 0, "fsfsqe1", req);
break;
}
@@ -413,6 +418,7 @@ static void zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *req)
dev_err(&adapter->ccw_device->dev,
"0x%x is not a valid transfer protocol status\n",
qtcb->prefix.prot_status);
+ zfcp_qdio_siosl(adapter);
zfcp_erp_adapter_shutdown(adapter, 0, "fspse_9", req);
}
req->status |= ZFCP_STATUS_FSFREQ_ERROR;
@@ -495,7 +501,7 @@ static int zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *req)
fc_host_supported_classes(shost) = FC_COS_CLASS2 | FC_COS_CLASS3;
adapter->hydra_version = bottom->adapter_type;
- adapter->timer_ticks = bottom->timer_interval;
+ adapter->timer_ticks = bottom->timer_interval & ZFCP_FSF_TIMER_INT_MASK;
adapter->stat_read_buf_num = max(bottom->status_read_buf_num,
(u16)FSF_STATUS_READS_RECOM);
@@ -523,6 +529,8 @@ static int zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *req)
return -EIO;
}
+ zfcp_scsi_set_prot(adapter);
+
return 0;
}
@@ -732,7 +740,7 @@ static int zfcp_fsf_req_send(struct zfcp_fsf_req *req)
zfcp_reqlist_add(adapter->req_list, req);
- req->qdio_req.qdio_outb_usage = atomic_read(&qdio->req_q.count);
+ req->qdio_req.qdio_outb_usage = atomic_read(&qdio->req_q_free);
req->issued = get_clock();
if (zfcp_qdio_send(qdio, &req->qdio_req)) {
del_timer(&req->timer);
@@ -959,8 +967,7 @@ static void zfcp_fsf_setup_ct_els_unchained(struct zfcp_qdio *qdio,
static int zfcp_fsf_setup_ct_els_sbals(struct zfcp_fsf_req *req,
struct scatterlist *sg_req,
- struct scatterlist *sg_resp,
- int max_sbals)
+ struct scatterlist *sg_resp)
{
struct zfcp_adapter *adapter = req->adapter;
u32 feat = adapter->adapter_features;
@@ -983,18 +990,19 @@ static int zfcp_fsf_setup_ct_els_sbals(struct zfcp_fsf_req *req,
return 0;
}
- bytes = zfcp_qdio_sbals_from_sg(adapter->qdio, &req->qdio_req,
- sg_req, max_sbals);
+ bytes = zfcp_qdio_sbals_from_sg(adapter->qdio, &req->qdio_req, sg_req);
if (bytes <= 0)
return -EIO;
+ zfcp_qdio_set_sbale_last(adapter->qdio, &req->qdio_req);
req->qtcb->bottom.support.req_buf_length = bytes;
zfcp_qdio_skip_to_last_sbale(&req->qdio_req);
bytes = zfcp_qdio_sbals_from_sg(adapter->qdio, &req->qdio_req,
- sg_resp, max_sbals);
+ sg_resp);
req->qtcb->bottom.support.resp_buf_length = bytes;
if (bytes <= 0)
return -EIO;
+ zfcp_qdio_set_sbale_last(adapter->qdio, &req->qdio_req);
return 0;
}
@@ -1002,11 +1010,11 @@ static int zfcp_fsf_setup_ct_els_sbals(struct zfcp_fsf_req *req,
static int zfcp_fsf_setup_ct_els(struct zfcp_fsf_req *req,
struct scatterlist *sg_req,
struct scatterlist *sg_resp,
- int max_sbals, unsigned int timeout)
+ unsigned int timeout)
{
int ret;
- ret = zfcp_fsf_setup_ct_els_sbals(req, sg_req, sg_resp, max_sbals);
+ ret = zfcp_fsf_setup_ct_els_sbals(req, sg_req, sg_resp);
if (ret)
return ret;
@@ -1046,8 +1054,7 @@ int zfcp_fsf_send_ct(struct zfcp_fc_wka_port *wka_port,
}
req->status |= ZFCP_STATUS_FSFREQ_CLEANUP;
- ret = zfcp_fsf_setup_ct_els(req, ct->req, ct->resp,
- ZFCP_FSF_MAX_SBALS_PER_REQ, timeout);
+ ret = zfcp_fsf_setup_ct_els(req, ct->req, ct->resp, timeout);
if (ret)
goto failed_send;
@@ -1143,7 +1150,10 @@ int zfcp_fsf_send_els(struct zfcp_adapter *adapter, u32 d_id,
}
req->status |= ZFCP_STATUS_FSFREQ_CLEANUP;
- ret = zfcp_fsf_setup_ct_els(req, els->req, els->resp, 2, timeout);
+
+ zfcp_qdio_sbal_limit(qdio, &req->qdio_req, 2);
+
+ ret = zfcp_fsf_setup_ct_els(req, els->req, els->resp, timeout);
if (ret)
goto failed_send;
@@ -2025,7 +2035,7 @@ static void zfcp_fsf_req_trace(struct zfcp_fsf_req *req, struct scsi_cmnd *scsi)
blktrc.magic = ZFCP_BLK_DRV_DATA_MAGIC;
if (req->status & ZFCP_STATUS_FSFREQ_ERROR)
blktrc.flags |= ZFCP_BLK_REQ_ERROR;
- blktrc.inb_usage = req->qdio_req.qdio_inb_usage;
+ blktrc.inb_usage = 0;
blktrc.outb_usage = req->qdio_req.qdio_outb_usage;
if (req->adapter->adapter_features & FSF_FEATURE_MEASUREMENT_DATA &&
@@ -2035,9 +2045,13 @@ static void zfcp_fsf_req_trace(struct zfcp_fsf_req *req, struct scsi_cmnd *scsi)
blktrc.fabric_lat = lat_in->fabric_lat * ticks;
switch (req->qtcb->bottom.io.data_direction) {
+ case FSF_DATADIR_DIF_READ_STRIP:
+ case FSF_DATADIR_DIF_READ_CONVERT:
case FSF_DATADIR_READ:
lat = &unit->latencies.read;
break;
+ case FSF_DATADIR_DIF_WRITE_INSERT:
+ case FSF_DATADIR_DIF_WRITE_CONVERT:
case FSF_DATADIR_WRITE:
lat = &unit->latencies.write;
break;
@@ -2078,6 +2092,21 @@ static void zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *req)
goto skip_fsfstatus;
}
+ switch (req->qtcb->header.fsf_status) {
+ case FSF_INCONSISTENT_PROT_DATA:
+ case FSF_INVALID_PROT_PARM:
+ set_host_byte(scpnt, DID_ERROR);
+ goto skip_fsfstatus;
+ case FSF_BLOCK_GUARD_CHECK_FAILURE:
+ zfcp_scsi_dif_sense_error(scpnt, 0x1);
+ goto skip_fsfstatus;
+ case FSF_APP_TAG_CHECK_FAILURE:
+ zfcp_scsi_dif_sense_error(scpnt, 0x2);
+ goto skip_fsfstatus;
+ case FSF_REF_TAG_CHECK_FAILURE:
+ zfcp_scsi_dif_sense_error(scpnt, 0x3);
+ goto skip_fsfstatus;
+ }
fcp_rsp = (struct fcp_resp_with_ext *) &req->qtcb->bottom.io.fcp_rsp;
zfcp_fc_eval_fcp_rsp(fcp_rsp, scpnt);
@@ -2187,6 +2216,44 @@ skip_fsfstatus:
}
}
+static int zfcp_fsf_set_data_dir(struct scsi_cmnd *scsi_cmnd, u32 *data_dir)
+{
+ switch (scsi_get_prot_op(scsi_cmnd)) {
+ case SCSI_PROT_NORMAL:
+ switch (scsi_cmnd->sc_data_direction) {
+ case DMA_NONE:
+ *data_dir = FSF_DATADIR_CMND;
+ break;
+ case DMA_FROM_DEVICE:
+ *data_dir = FSF_DATADIR_READ;
+ break;
+ case DMA_TO_DEVICE:
+ *data_dir = FSF_DATADIR_WRITE;
+ break;
+ case DMA_BIDIRECTIONAL:
+ return -EINVAL;
+ }
+ break;
+
+ case SCSI_PROT_READ_STRIP:
+ *data_dir = FSF_DATADIR_DIF_READ_STRIP;
+ break;
+ case SCSI_PROT_WRITE_INSERT:
+ *data_dir = FSF_DATADIR_DIF_WRITE_INSERT;
+ break;
+ case SCSI_PROT_READ_PASS:
+ *data_dir = FSF_DATADIR_DIF_READ_CONVERT;
+ break;
+ case SCSI_PROT_WRITE_PASS:
+ *data_dir = FSF_DATADIR_DIF_WRITE_CONVERT;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
/**
* zfcp_fsf_send_fcp_command_task - initiate an FCP command (for a SCSI command)
* @unit: unit where command is sent to
@@ -2198,16 +2265,17 @@ int zfcp_fsf_send_fcp_command_task(struct zfcp_unit *unit,
struct zfcp_fsf_req *req;
struct fcp_cmnd *fcp_cmnd;
unsigned int sbtype = SBAL_FLAGS0_TYPE_READ;
- int real_bytes, retval = -EIO;
+ int real_bytes, retval = -EIO, dix_bytes = 0;
struct zfcp_adapter *adapter = unit->port->adapter;
struct zfcp_qdio *qdio = adapter->qdio;
+ struct fsf_qtcb_bottom_io *io;
if (unlikely(!(atomic_read(&unit->status) &
ZFCP_STATUS_COMMON_UNBLOCKED)))
return -EBUSY;
spin_lock(&qdio->req_q_lock);
- if (atomic_read(&qdio->req_q.count) <= 0) {
+ if (atomic_read(&qdio->req_q_free) <= 0) {
atomic_inc(&qdio->req_q_full);
goto out;
}
@@ -2223,56 +2291,45 @@ int zfcp_fsf_send_fcp_command_task(struct zfcp_unit *unit,
goto out;
}
+ scsi_cmnd->host_scribble = (unsigned char *) req->req_id;
+
+ io = &req->qtcb->bottom.io;
req->status |= ZFCP_STATUS_FSFREQ_CLEANUP;
req->unit = unit;
req->data = scsi_cmnd;
req->handler = zfcp_fsf_send_fcp_command_handler;
req->qtcb->header.lun_handle = unit->handle;
req->qtcb->header.port_handle = unit->port->handle;
- req->qtcb->bottom.io.service_class = FSF_CLASS_3;
- req->qtcb->bottom.io.fcp_cmnd_length = FCP_CMND_LEN;
+ io->service_class = FSF_CLASS_3;
+ io->fcp_cmnd_length = FCP_CMND_LEN;
- scsi_cmnd->host_scribble = (unsigned char *) req->req_id;
-
- /*
- * set depending on data direction:
- * data direction bits in SBALE (SB Type)
- * data direction bits in QTCB
- */
- switch (scsi_cmnd->sc_data_direction) {
- case DMA_NONE:
- req->qtcb->bottom.io.data_direction = FSF_DATADIR_CMND;
- break;
- case DMA_FROM_DEVICE:
- req->qtcb->bottom.io.data_direction = FSF_DATADIR_READ;
- break;
- case DMA_TO_DEVICE:
- req->qtcb->bottom.io.data_direction = FSF_DATADIR_WRITE;
- break;
- case DMA_BIDIRECTIONAL:
- goto failed_scsi_cmnd;
+ if (scsi_get_prot_op(scsi_cmnd) != SCSI_PROT_NORMAL) {
+ io->data_block_length = scsi_cmnd->device->sector_size;
+ io->ref_tag_value = scsi_get_lba(scsi_cmnd) & 0xFFFFFFFF;
}
+ zfcp_fsf_set_data_dir(scsi_cmnd, &io->data_direction);
+
get_device(&unit->dev);
fcp_cmnd = (struct fcp_cmnd *) &req->qtcb->bottom.io.fcp_cmnd;
zfcp_fc_scsi_to_fcp(fcp_cmnd, scsi_cmnd);
+ if (scsi_prot_sg_count(scsi_cmnd)) {
+ zfcp_qdio_set_data_div(qdio, &req->qdio_req,
+ scsi_prot_sg_count(scsi_cmnd));
+ dix_bytes = zfcp_qdio_sbals_from_sg(qdio, &req->qdio_req,
+ scsi_prot_sglist(scsi_cmnd));
+ io->prot_data_length = dix_bytes;
+ }
+
real_bytes = zfcp_qdio_sbals_from_sg(qdio, &req->qdio_req,
- scsi_sglist(scsi_cmnd),
- ZFCP_FSF_MAX_SBALS_PER_REQ);
- if (unlikely(real_bytes < 0)) {
- if (req->qdio_req.sbal_number >= ZFCP_FSF_MAX_SBALS_PER_REQ) {
- dev_err(&adapter->ccw_device->dev,
- "Oversize data package, unit 0x%016Lx "
- "on port 0x%016Lx closed\n",
- (unsigned long long)unit->fcp_lun,
- (unsigned long long)unit->port->wwpn);
- zfcp_erp_unit_shutdown(unit, 0, "fssfct1", req);
- retval = -EINVAL;
- }
+ scsi_sglist(scsi_cmnd));
+
+ if (unlikely(real_bytes < 0) || unlikely(dix_bytes < 0))
goto failed_scsi_cmnd;
- }
+
+ zfcp_qdio_set_sbale_last(adapter->qdio, &req->qdio_req);
retval = zfcp_fsf_req_send(req);
if (unlikely(retval))
@@ -2391,13 +2448,13 @@ struct zfcp_fsf_req *zfcp_fsf_control_file(struct zfcp_adapter *adapter,
bottom->operation_subtype = FSF_CFDC_OPERATION_SUBTYPE;
bottom->option = fsf_cfdc->option;
- bytes = zfcp_qdio_sbals_from_sg(qdio, &req->qdio_req,
- fsf_cfdc->sg,
- ZFCP_FSF_MAX_SBALS_PER_REQ);
+ bytes = zfcp_qdio_sbals_from_sg(qdio, &req->qdio_req, fsf_cfdc->sg);
+
if (bytes != ZFCP_CFDC_MAX_SIZE) {
zfcp_fsf_req_free(req);
goto out;
}
+ zfcp_qdio_set_sbale_last(adapter->qdio, &req->qdio_req);
zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT);
retval = zfcp_fsf_req_send(req);
@@ -2419,7 +2476,7 @@ out:
void zfcp_fsf_reqid_check(struct zfcp_qdio *qdio, int sbal_idx)
{
struct zfcp_adapter *adapter = qdio->adapter;
- struct qdio_buffer *sbal = qdio->resp_q.sbal[sbal_idx];
+ struct qdio_buffer *sbal = qdio->res_q[sbal_idx];
struct qdio_buffer_element *sbale;
struct zfcp_fsf_req *fsf_req;
unsigned long req_id;
@@ -2431,17 +2488,17 @@ void zfcp_fsf_reqid_check(struct zfcp_qdio *qdio, int sbal_idx)
req_id = (unsigned long) sbale->addr;
fsf_req = zfcp_reqlist_find_rm(adapter->req_list, req_id);
- if (!fsf_req)
+ if (!fsf_req) {
/*
* Unknown request means that we have potentially memory
* corruption and must stop the machine immediately.
*/
+ zfcp_qdio_siosl(adapter);
panic("error: unknown req_id (%lx) on adapter %s.\n",
req_id, dev_name(&adapter->ccw_device->dev));
+ }
fsf_req->qdio_req.sbal_response = sbal_idx;
- fsf_req->qdio_req.qdio_inb_usage =
- atomic_read(&qdio->resp_q.count);
zfcp_fsf_req_complete(fsf_req);
if (likely(sbale->flags & SBAL_FLAGS_LAST_ENTRY))
diff --git a/drivers/s390/scsi/zfcp_fsf.h b/drivers/s390/scsi/zfcp_fsf.h
index 519083fd6e8..db8c85382dc 100644
--- a/drivers/s390/scsi/zfcp_fsf.h
+++ b/drivers/s390/scsi/zfcp_fsf.h
@@ -80,11 +80,15 @@
#define FSF_REQUEST_SIZE_TOO_LARGE 0x00000061
#define FSF_RESPONSE_SIZE_TOO_LARGE 0x00000062
#define FSF_SBAL_MISMATCH 0x00000063
+#define FSF_INCONSISTENT_PROT_DATA 0x00000070
+#define FSF_INVALID_PROT_PARM 0x00000071
+#define FSF_BLOCK_GUARD_CHECK_FAILURE 0x00000081
+#define FSF_APP_TAG_CHECK_FAILURE 0x00000082
+#define FSF_REF_TAG_CHECK_FAILURE 0x00000083
#define FSF_ADAPTER_STATUS_AVAILABLE 0x000000AD
#define FSF_UNKNOWN_COMMAND 0x000000E2
#define FSF_UNKNOWN_OP_SUBTYPE 0x000000E3
#define FSF_INVALID_COMMAND_OPTION 0x000000E5
-/* #define FSF_ERROR 0x000000FF */
#define FSF_PROT_STATUS_QUAL_SIZE 16
#define FSF_STATUS_QUALIFIER_SIZE 16
@@ -147,18 +151,17 @@
#define FSF_DATADIR_WRITE 0x00000001
#define FSF_DATADIR_READ 0x00000002
#define FSF_DATADIR_CMND 0x00000004
+#define FSF_DATADIR_DIF_WRITE_INSERT 0x00000009
+#define FSF_DATADIR_DIF_READ_STRIP 0x0000000a
+#define FSF_DATADIR_DIF_WRITE_CONVERT 0x0000000b
+#define FSF_DATADIR_DIF_READ_CONVERT 0X0000000c
+
+/* data protection control flags */
+#define FSF_APP_TAG_CHECK_ENABLE 0x10
/* fc service class */
#define FSF_CLASS_3 0x00000003
-/* SBAL chaining */
-#define ZFCP_FSF_MAX_SBALS_PER_REQ 36
-
-/* max. number of (data buffer) SBALEs in largest SBAL chain
- * request ID + QTCB in SBALE 0 + 1 of first SBAL in chain */
-#define ZFCP_FSF_MAX_SBALES_PER_REQ \
- (ZFCP_FSF_MAX_SBALS_PER_REQ * ZFCP_QDIO_MAX_SBALES_PER_SBAL - 2)
-
/* logging space behind QTCB */
#define FSF_QTCB_LOG_SIZE 1024
@@ -170,6 +173,8 @@
#define FSF_FEATURE_ELS_CT_CHAINED_SBALS 0x00000020
#define FSF_FEATURE_UPDATE_ALERT 0x00000100
#define FSF_FEATURE_MEASUREMENT_DATA 0x00000200
+#define FSF_FEATURE_DIF_PROT_TYPE1 0x00010000
+#define FSF_FEATURE_DIX_PROT_TCPIP 0x00020000
/* host connection features */
#define FSF_FEATURE_NPIV_MODE 0x00000001
@@ -324,9 +329,14 @@ struct fsf_qtcb_header {
struct fsf_qtcb_bottom_io {
u32 data_direction;
u32 service_class;
- u8 res1[8];
+ u8 res1;
+ u8 data_prot_flags;
+ u16 app_tag_value;
+ u32 ref_tag_value;
u32 fcp_cmnd_length;
- u8 res2[12];
+ u32 data_block_length;
+ u32 prot_data_length;
+ u8 res2[4];
u8 fcp_cmnd[FSF_FCP_CMND_SIZE];
u8 fcp_rsp[FSF_FCP_RSP_SIZE];
u8 res3[64];
@@ -352,6 +362,8 @@ struct fsf_qtcb_bottom_support {
u8 els[256];
} __attribute__ ((packed));
+#define ZFCP_FSF_TIMER_INT_MASK 0x3FFF
+
struct fsf_qtcb_bottom_config {
u32 lic_version;
u32 feature_selection;
diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c
index 6fa5e045317..b2635759721 100644
--- a/drivers/s390/scsi/zfcp_qdio.c
+++ b/drivers/s390/scsi/zfcp_qdio.c
@@ -30,12 +30,15 @@ static int zfcp_qdio_buffers_enqueue(struct qdio_buffer **sbal)
return 0;
}
-static void zfcp_qdio_handler_error(struct zfcp_qdio *qdio, char *id)
+static void zfcp_qdio_handler_error(struct zfcp_qdio *qdio, char *id,
+ unsigned int qdio_err)
{
struct zfcp_adapter *adapter = qdio->adapter;
dev_warn(&adapter->ccw_device->dev, "A QDIO problem occurred\n");
+ if (qdio_err & QDIO_ERROR_SLSB_STATE)
+ zfcp_qdio_siosl(adapter);
zfcp_erp_adapter_reopen(adapter,
ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED |
ZFCP_STATUS_COMMON_ERP_FAILED, id, NULL);
@@ -55,72 +58,47 @@ static void zfcp_qdio_zero_sbals(struct qdio_buffer *sbal[], int first, int cnt)
static inline void zfcp_qdio_account(struct zfcp_qdio *qdio)
{
unsigned long long now, span;
- int free, used;
+ int used;
spin_lock(&qdio->stat_lock);
now = get_clock_monotonic();
span = (now - qdio->req_q_time) >> 12;
- free = atomic_read(&qdio->req_q.count);
- used = QDIO_MAX_BUFFERS_PER_Q - free;
+ used = QDIO_MAX_BUFFERS_PER_Q - atomic_read(&qdio->req_q_free);
qdio->req_q_util += used * span;
qdio->req_q_time = now;
spin_unlock(&qdio->stat_lock);
}
static void zfcp_qdio_int_req(struct ccw_device *cdev, unsigned int qdio_err,
- int queue_no, int first, int count,
+ int queue_no, int idx, int count,
unsigned long parm)
{
struct zfcp_qdio *qdio = (struct zfcp_qdio *) parm;
- struct zfcp_qdio_queue *queue = &qdio->req_q;
if (unlikely(qdio_err)) {
- zfcp_dbf_hba_qdio(qdio->adapter->dbf, qdio_err, first,
- count);
- zfcp_qdio_handler_error(qdio, "qdireq1");
+ zfcp_dbf_hba_qdio(qdio->adapter->dbf, qdio_err, idx, count);
+ zfcp_qdio_handler_error(qdio, "qdireq1", qdio_err);
return;
}
/* cleanup all SBALs being program-owned now */
- zfcp_qdio_zero_sbals(queue->sbal, first, count);
+ zfcp_qdio_zero_sbals(qdio->req_q, idx, count);
zfcp_qdio_account(qdio);
- atomic_add(count, &queue->count);
+ atomic_add(count, &qdio->req_q_free);
wake_up(&qdio->req_q_wq);
}
-static void zfcp_qdio_resp_put_back(struct zfcp_qdio *qdio, int processed)
-{
- struct zfcp_qdio_queue *queue = &qdio->resp_q;
- struct ccw_device *cdev = qdio->adapter->ccw_device;
- u8 count, start = queue->first;
- unsigned int retval;
-
- count = atomic_read(&queue->count) + processed;
-
- retval = do_QDIO(cdev, QDIO_FLAG_SYNC_INPUT, 0, start, count);
-
- if (unlikely(retval)) {
- atomic_set(&queue->count, count);
- zfcp_erp_adapter_reopen(qdio->adapter, 0, "qdrpb_1", NULL);
- } else {
- queue->first += count;
- queue->first %= QDIO_MAX_BUFFERS_PER_Q;
- atomic_set(&queue->count, 0);
- }
-}
-
static void zfcp_qdio_int_resp(struct ccw_device *cdev, unsigned int qdio_err,
- int queue_no, int first, int count,
+ int queue_no, int idx, int count,
unsigned long parm)
{
struct zfcp_qdio *qdio = (struct zfcp_qdio *) parm;
int sbal_idx, sbal_no;
if (unlikely(qdio_err)) {
- zfcp_dbf_hba_qdio(qdio->adapter->dbf, qdio_err, first,
- count);
- zfcp_qdio_handler_error(qdio, "qdires1");
+ zfcp_dbf_hba_qdio(qdio->adapter->dbf, qdio_err, idx, count);
+ zfcp_qdio_handler_error(qdio, "qdires1", qdio_err);
return;
}
@@ -129,25 +107,16 @@ static void zfcp_qdio_int_resp(struct ccw_device *cdev, unsigned int qdio_err,
* returned by QDIO layer
*/
for (sbal_no = 0; sbal_no < count; sbal_no++) {
- sbal_idx = (first + sbal_no) % QDIO_MAX_BUFFERS_PER_Q;
+ sbal_idx = (idx + sbal_no) % QDIO_MAX_BUFFERS_PER_Q;
/* go through all SBALEs of SBAL */
zfcp_fsf_reqid_check(qdio, sbal_idx);
}
/*
- * put range of SBALs back to response queue
- * (including SBALs which have already been free before)
+ * put SBALs back to response queue
*/
- zfcp_qdio_resp_put_back(qdio, count);
-}
-
-static void zfcp_qdio_sbal_limit(struct zfcp_qdio *qdio,
- struct zfcp_qdio_req *q_req, int max_sbals)
-{
- int count = atomic_read(&qdio->req_q.count);
- count = min(count, max_sbals);
- q_req->sbal_limit = (q_req->sbal_first + count - 1)
- % QDIO_MAX_BUFFERS_PER_Q;
+ if (do_QDIO(cdev, QDIO_FLAG_SYNC_INPUT, 0, idx, count))
+ zfcp_erp_adapter_reopen(qdio->adapter, 0, "qdires2", NULL);
}
static struct qdio_buffer_element *
@@ -173,6 +142,7 @@ zfcp_qdio_sbal_chain(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req)
/* keep this requests number of SBALs up-to-date */
q_req->sbal_number++;
+ BUG_ON(q_req->sbal_number > ZFCP_QDIO_MAX_SBALS_PER_REQ);
/* start at first SBALE of new SBAL */
q_req->sbale_curr = 0;
@@ -193,17 +163,6 @@ zfcp_qdio_sbale_next(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req)
return zfcp_qdio_sbale_curr(qdio, q_req);
}
-static void zfcp_qdio_undo_sbals(struct zfcp_qdio *qdio,
- struct zfcp_qdio_req *q_req)
-{
- struct qdio_buffer **sbal = qdio->req_q.sbal;
- int first = q_req->sbal_first;
- int last = q_req->sbal_last;
- int count = (last - first + QDIO_MAX_BUFFERS_PER_Q) %
- QDIO_MAX_BUFFERS_PER_Q + 1;
- zfcp_qdio_zero_sbals(sbal, first, count);
-}
-
/**
* zfcp_qdio_sbals_from_sg - fill SBALs from scatter-gather list
* @qdio: pointer to struct zfcp_qdio
@@ -213,14 +172,11 @@ static void zfcp_qdio_undo_sbals(struct zfcp_qdio *qdio,
* Returns: number of bytes, or error (negativ)
*/
int zfcp_qdio_sbals_from_sg(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req,
- struct scatterlist *sg, int max_sbals)
+ struct scatterlist *sg)
{
struct qdio_buffer_element *sbale;
int bytes = 0;
- /* figure out last allowed SBAL */
- zfcp_qdio_sbal_limit(qdio, q_req, max_sbals);
-
/* set storage-block type for this request */
sbale = zfcp_qdio_sbale_req(qdio, q_req);
sbale->flags |= q_req->sbtype;
@@ -229,7 +185,8 @@ int zfcp_qdio_sbals_from_sg(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req,
sbale = zfcp_qdio_sbale_next(qdio, q_req);
if (!sbale) {
atomic_inc(&qdio->req_q_full);
- zfcp_qdio_undo_sbals(qdio, q_req);
+ zfcp_qdio_zero_sbals(qdio->req_q, q_req->sbal_first,
+ q_req->sbal_number);
return -EINVAL;
}
@@ -239,19 +196,13 @@ int zfcp_qdio_sbals_from_sg(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req,
bytes += sg->length;
}
- /* assume that no other SBALEs are to follow in the same SBAL */
- sbale = zfcp_qdio_sbale_curr(qdio, q_req);
- sbale->flags |= SBAL_FLAGS_LAST_ENTRY;
-
return bytes;
}
static int zfcp_qdio_sbal_check(struct zfcp_qdio *qdio)
{
- struct zfcp_qdio_queue *req_q = &qdio->req_q;
-
spin_lock_bh(&qdio->req_q_lock);
- if (atomic_read(&req_q->count) ||
+ if (atomic_read(&qdio->req_q_free) ||
!(atomic_read(&qdio->adapter->status) & ZFCP_STATUS_ADAPTER_QDIOUP))
return 1;
spin_unlock_bh(&qdio->req_q_lock);
@@ -300,25 +251,25 @@ int zfcp_qdio_sbal_get(struct zfcp_qdio *qdio)
*/
int zfcp_qdio_send(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req)
{
- struct zfcp_qdio_queue *req_q = &qdio->req_q;
- int first = q_req->sbal_first;
- int count = q_req->sbal_number;
int retval;
- unsigned int qdio_flags = QDIO_FLAG_SYNC_OUTPUT;
+ u8 sbal_number = q_req->sbal_number;
zfcp_qdio_account(qdio);
- retval = do_QDIO(qdio->adapter->ccw_device, qdio_flags, 0, first,
- count);
+ retval = do_QDIO(qdio->adapter->ccw_device, QDIO_FLAG_SYNC_OUTPUT, 0,
+ q_req->sbal_first, sbal_number);
+
if (unlikely(retval)) {
- zfcp_qdio_zero_sbals(req_q->sbal, first, count);
+ zfcp_qdio_zero_sbals(qdio->req_q, q_req->sbal_first,
+ sbal_number);
return retval;
}
/* account for transferred buffers */
- atomic_sub(count, &req_q->count);
- req_q->first += count;
- req_q->first %= QDIO_MAX_BUFFERS_PER_Q;
+ atomic_sub(sbal_number, &qdio->req_q_free);
+ qdio->req_q_idx += sbal_number;
+ qdio->req_q_idx %= QDIO_MAX_BUFFERS_PER_Q;
+
return 0;
}
@@ -331,6 +282,7 @@ static void zfcp_qdio_setup_init_data(struct qdio_initialize *id,
id->q_format = QDIO_ZFCP_QFMT;
memcpy(id->adapter_name, dev_name(&id->cdev->dev), 8);
ASCEBC(id->adapter_name, 8);
+ id->qib_rflags = QIB_RFLAGS_ENABLE_DATA_DIV;
id->qib_param_field_format = 0;
id->qib_param_field = NULL;
id->input_slib_elements = NULL;
@@ -340,10 +292,10 @@ static void zfcp_qdio_setup_init_data(struct qdio_initialize *id,
id->input_handler = zfcp_qdio_int_resp;
id->output_handler = zfcp_qdio_int_req;
id->int_parm = (unsigned long) qdio;
- id->input_sbal_addr_array = (void **) (qdio->resp_q.sbal);
- id->output_sbal_addr_array = (void **) (qdio->req_q.sbal);
-
+ id->input_sbal_addr_array = (void **) (qdio->res_q);
+ id->output_sbal_addr_array = (void **) (qdio->req_q);
}
+
/**
* zfcp_qdio_allocate - allocate queue memory and initialize QDIO data
* @adapter: pointer to struct zfcp_adapter
@@ -354,8 +306,8 @@ static int zfcp_qdio_allocate(struct zfcp_qdio *qdio)
{
struct qdio_initialize init_data;
- if (zfcp_qdio_buffers_enqueue(qdio->req_q.sbal) ||
- zfcp_qdio_buffers_enqueue(qdio->resp_q.sbal))
+ if (zfcp_qdio_buffers_enqueue(qdio->req_q) ||
+ zfcp_qdio_buffers_enqueue(qdio->res_q))
return -ENOMEM;
zfcp_qdio_setup_init_data(&init_data, qdio);
@@ -369,34 +321,30 @@ static int zfcp_qdio_allocate(struct zfcp_qdio *qdio)
*/
void zfcp_qdio_close(struct zfcp_qdio *qdio)
{
- struct zfcp_qdio_queue *req_q;
- int first, count;
+ struct zfcp_adapter *adapter = qdio->adapter;
+ int idx, count;
- if (!(atomic_read(&qdio->adapter->status) & ZFCP_STATUS_ADAPTER_QDIOUP))
+ if (!(atomic_read(&adapter->status) & ZFCP_STATUS_ADAPTER_QDIOUP))
return;
/* clear QDIOUP flag, thus do_QDIO is not called during qdio_shutdown */
- req_q = &qdio->req_q;
spin_lock_bh(&qdio->req_q_lock);
- atomic_clear_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &qdio->adapter->status);
+ atomic_clear_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status);
spin_unlock_bh(&qdio->req_q_lock);
wake_up(&qdio->req_q_wq);
- qdio_shutdown(qdio->adapter->ccw_device,
- QDIO_FLAG_CLEANUP_USING_CLEAR);
+ qdio_shutdown(adapter->ccw_device, QDIO_FLAG_CLEANUP_USING_CLEAR);
/* cleanup used outbound sbals */
- count = atomic_read(&req_q->count);
+ count = atomic_read(&qdio->req_q_free);
if (count < QDIO_MAX_BUFFERS_PER_Q) {
- first = (req_q->first + count) % QDIO_MAX_BUFFERS_PER_Q;
+ idx = (qdio->req_q_idx + count) % QDIO_MAX_BUFFERS_PER_Q;
count = QDIO_MAX_BUFFERS_PER_Q - count;
- zfcp_qdio_zero_sbals(req_q->sbal, first, count);
+ zfcp_qdio_zero_sbals(qdio->req_q, idx, count);
}
- req_q->first = 0;
- atomic_set(&req_q->count, 0);
- qdio->resp_q.first = 0;
- atomic_set(&qdio->resp_q.count, 0);
+ qdio->req_q_idx = 0;
+ atomic_set(&qdio->req_q_free, 0);
}
/**
@@ -408,34 +356,45 @@ int zfcp_qdio_open(struct zfcp_qdio *qdio)
{
struct qdio_buffer_element *sbale;
struct qdio_initialize init_data;
- struct ccw_device *cdev = qdio->adapter->ccw_device;
+ struct zfcp_adapter *adapter = qdio->adapter;
+ struct ccw_device *cdev = adapter->ccw_device;
+ struct qdio_ssqd_desc ssqd;
int cc;
- if (atomic_read(&qdio->adapter->status) & ZFCP_STATUS_ADAPTER_QDIOUP)
+ if (atomic_read(&adapter->status) & ZFCP_STATUS_ADAPTER_QDIOUP)
return -EIO;
+ atomic_clear_mask(ZFCP_STATUS_ADAPTER_SIOSL_ISSUED,
+ &qdio->adapter->status);
+
zfcp_qdio_setup_init_data(&init_data, qdio);
if (qdio_establish(&init_data))
goto failed_establish;
+ if (qdio_get_ssqd_desc(init_data.cdev, &ssqd))
+ goto failed_qdio;
+
+ if (ssqd.qdioac2 & CHSC_AC2_DATA_DIV_ENABLED)
+ atomic_set_mask(ZFCP_STATUS_ADAPTER_DATA_DIV_ENABLED,
+ &qdio->adapter->status);
+
if (qdio_activate(cdev))
goto failed_qdio;
for (cc = 0; cc < QDIO_MAX_BUFFERS_PER_Q; cc++) {
- sbale = &(qdio->resp_q.sbal[cc]->element[0]);
+ sbale = &(qdio->res_q[cc]->element[0]);
sbale->length = 0;
sbale->flags = SBAL_FLAGS_LAST_ENTRY;
sbale->addr = NULL;
}
- if (do_QDIO(cdev, QDIO_FLAG_SYNC_INPUT, 0, 0,
- QDIO_MAX_BUFFERS_PER_Q))
+ if (do_QDIO(cdev, QDIO_FLAG_SYNC_INPUT, 0, 0, QDIO_MAX_BUFFERS_PER_Q))
goto failed_qdio;
/* set index of first avalable SBALS / number of available SBALS */
- qdio->req_q.first = 0;
- atomic_set(&qdio->req_q.count, QDIO_MAX_BUFFERS_PER_Q);
+ qdio->req_q_idx = 0;
+ atomic_set(&qdio->req_q_free, QDIO_MAX_BUFFERS_PER_Q);
return 0;
@@ -449,7 +408,6 @@ failed_establish:
void zfcp_qdio_destroy(struct zfcp_qdio *qdio)
{
- struct qdio_buffer **sbal_req, **sbal_resp;
int p;
if (!qdio)
@@ -458,12 +416,9 @@ void zfcp_qdio_destroy(struct zfcp_qdio *qdio)
if (qdio->adapter->ccw_device)
qdio_free(qdio->adapter->ccw_device);
- sbal_req = qdio->req_q.sbal;
- sbal_resp = qdio->resp_q.sbal;
-
for (p = 0; p < QDIO_MAX_BUFFERS_PER_Q; p += QBUFF_PER_PAGE) {
- free_page((unsigned long) sbal_req[p]);
- free_page((unsigned long) sbal_resp[p]);
+ free_page((unsigned long) qdio->req_q[p]);
+ free_page((unsigned long) qdio->res_q[p]);
}
kfree(qdio);
@@ -491,3 +446,26 @@ int zfcp_qdio_setup(struct zfcp_adapter *adapter)
return 0;
}
+/**
+ * zfcp_qdio_siosl - Trigger logging in FCP channel
+ * @adapter: The zfcp_adapter where to trigger logging
+ *
+ * Call the cio siosl function to trigger hardware logging. This
+ * wrapper function sets a flag to ensure hardware logging is only
+ * triggered once before going through qdio shutdown.
+ *
+ * The triggers are always run from qdio tasklet context, so no
+ * additional synchronization is necessary.
+ */
+void zfcp_qdio_siosl(struct zfcp_adapter *adapter)
+{
+ int rc;
+
+ if (atomic_read(&adapter->status) & ZFCP_STATUS_ADAPTER_SIOSL_ISSUED)
+ return;
+
+ rc = ccw_device_siosl(adapter->ccw_device);
+ if (!rc)
+ atomic_set_mask(ZFCP_STATUS_ADAPTER_SIOSL_ISSUED,
+ &adapter->status);
+}
diff --git a/drivers/s390/scsi/zfcp_qdio.h b/drivers/s390/scsi/zfcp_qdio.h
index 138fba577b4..2297d8d3e94 100644
--- a/drivers/s390/scsi/zfcp_qdio.h
+++ b/drivers/s390/scsi/zfcp_qdio.h
@@ -19,22 +19,20 @@
/* index of last SBALE (with respect to DMQ bug workaround) */
#define ZFCP_QDIO_LAST_SBALE_PER_SBAL (ZFCP_QDIO_MAX_SBALES_PER_SBAL - 1)
-/**
- * struct zfcp_qdio_queue - qdio queue buffer, zfcp index and free count
- * @sbal: qdio buffers
- * @first: index of next free buffer in queue
- * @count: number of free buffers in queue
- */
-struct zfcp_qdio_queue {
- struct qdio_buffer *sbal[QDIO_MAX_BUFFERS_PER_Q];
- u8 first;
- atomic_t count;
-};
+/* Max SBALS for chaining */
+#define ZFCP_QDIO_MAX_SBALS_PER_REQ 36
+
+/* max. number of (data buffer) SBALEs in largest SBAL chain
+ * request ID + QTCB in SBALE 0 + 1 of first SBAL in chain */
+#define ZFCP_QDIO_MAX_SBALES_PER_REQ \
+ (ZFCP_QDIO_MAX_SBALS_PER_REQ * ZFCP_QDIO_MAX_SBALES_PER_SBAL - 2)
/**
* struct zfcp_qdio - basic qdio data structure
- * @resp_q: response queue
+ * @res_q: response queue
* @req_q: request queue
+ * @req_q_idx: index of next free buffer
+ * @req_q_free: number of free buffers in queue
* @stat_lock: lock to protect req_q_util and req_q_time
* @req_q_lock: lock to serialize access to request queue
* @req_q_time: time of last fill level change
@@ -44,8 +42,10 @@ struct zfcp_qdio_queue {
* @adapter: adapter used in conjunction with this qdio structure
*/
struct zfcp_qdio {
- struct zfcp_qdio_queue resp_q;
- struct zfcp_qdio_queue req_q;
+ struct qdio_buffer *res_q[QDIO_MAX_BUFFERS_PER_Q];
+ struct qdio_buffer *req_q[QDIO_MAX_BUFFERS_PER_Q];
+ u8 req_q_idx;
+ atomic_t req_q_free;
spinlock_t stat_lock;
spinlock_t req_q_lock;
unsigned long long req_q_time;
@@ -65,7 +65,6 @@ struct zfcp_qdio {
* @sbale_curr: current sbale at creation of this request
* @sbal_response: sbal used in interrupt
* @qdio_outb_usage: usage of outbound queue
- * @qdio_inb_usage: usage of inbound queue
*/
struct zfcp_qdio_req {
u32 sbtype;
@@ -76,22 +75,9 @@ struct zfcp_qdio_req {
u8 sbale_curr;
u8 sbal_response;
u16 qdio_outb_usage;
- u16 qdio_inb_usage;
};
/**
- * zfcp_qdio_sbale - return pointer to sbale in qdio queue
- * @q: queue where to find sbal
- * @sbal_idx: sbal index in queue
- * @sbale_idx: sbale index in sbal
- */
-static inline struct qdio_buffer_element *
-zfcp_qdio_sbale(struct zfcp_qdio_queue *q, int sbal_idx, int sbale_idx)
-{
- return &q->sbal[sbal_idx]->element[sbale_idx];
-}
-
-/**
* zfcp_qdio_sbale_req - return pointer to sbale on req_q for a request
* @qdio: pointer to struct zfcp_qdio
* @q_rec: pointer to struct zfcp_qdio_req
@@ -100,7 +86,7 @@ zfcp_qdio_sbale(struct zfcp_qdio_queue *q, int sbal_idx, int sbale_idx)
static inline struct qdio_buffer_element *
zfcp_qdio_sbale_req(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req)
{
- return zfcp_qdio_sbale(&qdio->req_q, q_req->sbal_last, 0);
+ return &qdio->req_q[q_req->sbal_last]->element[0];
}
/**
@@ -112,8 +98,7 @@ zfcp_qdio_sbale_req(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req)
static inline struct qdio_buffer_element *
zfcp_qdio_sbale_curr(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req)
{
- return zfcp_qdio_sbale(&qdio->req_q, q_req->sbal_last,
- q_req->sbale_curr);
+ return &qdio->req_q[q_req->sbal_last]->element[q_req->sbale_curr];
}
/**
@@ -134,21 +119,25 @@ void zfcp_qdio_req_init(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req,
unsigned long req_id, u32 sbtype, void *data, u32 len)
{
struct qdio_buffer_element *sbale;
+ int count = min(atomic_read(&qdio->req_q_free),
+ ZFCP_QDIO_MAX_SBALS_PER_REQ);
- q_req->sbal_first = q_req->sbal_last = qdio->req_q.first;
+ q_req->sbal_first = q_req->sbal_last = qdio->req_q_idx;
q_req->sbal_number = 1;
q_req->sbtype = sbtype;
+ q_req->sbale_curr = 1;
+ q_req->sbal_limit = (q_req->sbal_first + count - 1)
+ % QDIO_MAX_BUFFERS_PER_Q;
sbale = zfcp_qdio_sbale_req(qdio, q_req);
sbale->addr = (void *) req_id;
- sbale->flags |= SBAL_FLAGS0_COMMAND;
- sbale->flags |= sbtype;
+ sbale->flags = SBAL_FLAGS0_COMMAND | sbtype;
- q_req->sbale_curr = 1;
+ if (unlikely(!data))
+ return;
sbale++;
sbale->addr = data;
- if (likely(data))
- sbale->length = len;
+ sbale->length = len;
}
/**
@@ -210,4 +199,36 @@ void zfcp_qdio_skip_to_last_sbale(struct zfcp_qdio_req *q_req)
q_req->sbale_curr = ZFCP_QDIO_LAST_SBALE_PER_SBAL;
}
+/**
+ * zfcp_qdio_sbal_limit - set the sbal limit for a request in q_req
+ * @qdio: pointer to struct zfcp_qdio
+ * @q_req: The current zfcp_qdio_req
+ * @max_sbals: maximum number of SBALs allowed
+ */
+static inline
+void zfcp_qdio_sbal_limit(struct zfcp_qdio *qdio,
+ struct zfcp_qdio_req *q_req, int max_sbals)
+{
+ int count = min(atomic_read(&qdio->req_q_free), max_sbals);
+
+ q_req->sbal_limit = (q_req->sbal_first + count - 1) %
+ QDIO_MAX_BUFFERS_PER_Q;
+}
+
+/**
+ * zfcp_qdio_set_data_div - set data division count
+ * @qdio: pointer to struct zfcp_qdio
+ * @q_req: The current zfcp_qdio_req
+ * @count: The data division count
+ */
+static inline
+void zfcp_qdio_set_data_div(struct zfcp_qdio *qdio,
+ struct zfcp_qdio_req *q_req, u32 count)
+{
+ struct qdio_buffer_element *sbale;
+
+ sbale = &qdio->req_q[q_req->sbal_first]->element[0];
+ sbale->length = count;
+}
+
#endif /* ZFCP_QDIO_H */
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
index be5d2c60453..cb000c9833b 100644
--- a/drivers/s390/scsi/zfcp_scsi.c
+++ b/drivers/s390/scsi/zfcp_scsi.c
@@ -12,6 +12,7 @@
#include <linux/types.h>
#include <linux/slab.h>
#include <scsi/fc/fc_fcp.h>
+#include <scsi/scsi_eh.h>
#include <asm/atomic.h>
#include "zfcp_ext.h"
#include "zfcp_dbf.h"
@@ -22,6 +23,13 @@ static unsigned int default_depth = 32;
module_param_named(queue_depth, default_depth, uint, 0600);
MODULE_PARM_DESC(queue_depth, "Default queue depth for new SCSI devices");
+static bool enable_dif;
+
+#ifdef CONFIG_ZFCP_DIF
+module_param_named(dif, enable_dif, bool, 0600);
+MODULE_PARM_DESC(dif, "Enable DIF/DIX data integrity support");
+#endif
+
static int zfcp_scsi_change_queue_depth(struct scsi_device *sdev, int depth,
int reason)
{
@@ -506,8 +514,10 @@ static void zfcp_set_rport_dev_loss_tmo(struct fc_rport *rport, u32 timeout)
* @rport: The FC rport where to teminate I/O
*
* Abort all pending SCSI commands for a port by closing the
- * port. Using a reopen avoiding a conflict with a shutdown
- * overwriting a reopen.
+ * port. Using a reopen avoids a conflict with a shutdown
+ * overwriting a reopen. The "forced" ensures that a disappeared port
+ * is not opened again as valid due to the cached plogi data in
+ * non-NPIV mode.
*/
static void zfcp_scsi_terminate_rport_io(struct fc_rport *rport)
{
@@ -519,11 +529,25 @@ static void zfcp_scsi_terminate_rport_io(struct fc_rport *rport)
port = zfcp_get_port_by_wwpn(adapter, rport->port_name);
if (port) {
- zfcp_erp_port_reopen(port, 0, "sctrpi1", NULL);
+ zfcp_erp_port_forced_reopen(port, 0, "sctrpi1", NULL);
put_device(&port->dev);
}
}
+static void zfcp_scsi_queue_unit_register(struct zfcp_port *port)
+{
+ struct zfcp_unit *unit;
+
+ read_lock_irq(&port->unit_list_lock);
+ list_for_each_entry(unit, &port->unit_list, list) {
+ get_device(&unit->dev);
+ if (scsi_queue_work(port->adapter->scsi_host,
+ &unit->scsi_work) <= 0)
+ put_device(&unit->dev);
+ }
+ read_unlock_irq(&port->unit_list_lock);
+}
+
static void zfcp_scsi_rport_register(struct zfcp_port *port)
{
struct fc_rport_identifiers ids;
@@ -548,6 +572,9 @@ static void zfcp_scsi_rport_register(struct zfcp_port *port)
rport->maxframe_size = port->maxframe_size;
rport->supported_classes = port->supported_classes;
port->rport = rport;
+ port->starget_id = rport->scsi_target_id;
+
+ zfcp_scsi_queue_unit_register(port);
}
static void zfcp_scsi_rport_block(struct zfcp_port *port)
@@ -610,24 +637,74 @@ void zfcp_scsi_rport_work(struct work_struct *work)
put_device(&port->dev);
}
-
-void zfcp_scsi_scan(struct work_struct *work)
+/**
+ * zfcp_scsi_scan - Register LUN with SCSI midlayer
+ * @unit: The LUN/unit to register
+ */
+void zfcp_scsi_scan(struct zfcp_unit *unit)
{
- struct zfcp_unit *unit = container_of(work, struct zfcp_unit,
- scsi_work);
- struct fc_rport *rport;
-
- flush_work(&unit->port->rport_work);
- rport = unit->port->rport;
+ struct fc_rport *rport = unit->port->rport;
if (rport && rport->port_state == FC_PORTSTATE_ONLINE)
scsi_scan_target(&rport->dev, 0, rport->scsi_target_id,
scsilun_to_int((struct scsi_lun *)
&unit->fcp_lun), 0);
+}
+void zfcp_scsi_scan_work(struct work_struct *work)
+{
+ struct zfcp_unit *unit = container_of(work, struct zfcp_unit,
+ scsi_work);
+
+ zfcp_scsi_scan(unit);
put_device(&unit->dev);
}
+/**
+ * zfcp_scsi_set_prot - Configure DIF/DIX support in scsi_host
+ * @adapter: The adapter where to configure DIF/DIX for the SCSI host
+ */
+void zfcp_scsi_set_prot(struct zfcp_adapter *adapter)
+{
+ unsigned int mask = 0;
+ unsigned int data_div;
+ struct Scsi_Host *shost = adapter->scsi_host;
+
+ data_div = atomic_read(&adapter->status) &
+ ZFCP_STATUS_ADAPTER_DATA_DIV_ENABLED;
+
+ if (enable_dif &&
+ adapter->adapter_features & FSF_FEATURE_DIF_PROT_TYPE1)
+ mask |= SHOST_DIF_TYPE1_PROTECTION;
+
+ if (enable_dif && data_div &&
+ adapter->adapter_features & FSF_FEATURE_DIX_PROT_TCPIP) {
+ mask |= SHOST_DIX_TYPE1_PROTECTION;
+ scsi_host_set_guard(shost, SHOST_DIX_GUARD_IP);
+ shost->sg_tablesize = ZFCP_QDIO_MAX_SBALES_PER_REQ / 2;
+ shost->max_sectors = ZFCP_QDIO_MAX_SBALES_PER_REQ * 8 / 2;
+ }
+
+ scsi_host_set_prot(shost, mask);
+}
+
+/**
+ * zfcp_scsi_dif_sense_error - Report DIF/DIX error as driver sense error
+ * @scmd: The SCSI command to report the error for
+ * @ascq: The ASCQ to put in the sense buffer
+ *
+ * See the error handling in sd_done for the sense codes used here.
+ * Set DID_SOFT_ERROR to retry the request, if possible.
+ */
+void zfcp_scsi_dif_sense_error(struct scsi_cmnd *scmd, int ascq)
+{
+ scsi_build_sense_buffer(1, scmd->sense_buffer,
+ ILLEGAL_REQUEST, 0x10, ascq);
+ set_driver_byte(scmd, DRIVER_SENSE);
+ scmd->result |= SAM_STAT_CHECK_CONDITION;
+ set_host_byte(scmd, DID_SOFT_ERROR);
+}
+
struct fc_function_template zfcp_transport_functions = {
.show_starget_port_id = 1,
.show_starget_port_name = 1,
@@ -677,11 +754,11 @@ struct zfcp_data zfcp_data = {
.eh_host_reset_handler = zfcp_scsi_eh_host_reset_handler,
.can_queue = 4096,
.this_id = -1,
- .sg_tablesize = ZFCP_FSF_MAX_SBALES_PER_REQ,
+ .sg_tablesize = ZFCP_QDIO_MAX_SBALES_PER_REQ,
.cmd_per_lun = 1,
.use_clustering = 1,
.sdev_attrs = zfcp_sysfs_sdev_attrs,
- .max_sectors = (ZFCP_FSF_MAX_SBALES_PER_REQ * 8),
+ .max_sectors = (ZFCP_QDIO_MAX_SBALES_PER_REQ * 8),
.dma_boundary = ZFCP_QDIO_SBALE_LEN - 1,
.shost_attrs = zfcp_sysfs_shost_attrs,
},
diff --git a/drivers/s390/scsi/zfcp_sysfs.c b/drivers/s390/scsi/zfcp_sysfs.c
index f5f60698dc4..b4561c86e23 100644
--- a/drivers/s390/scsi/zfcp_sysfs.c
+++ b/drivers/s390/scsi/zfcp_sysfs.c
@@ -275,7 +275,7 @@ static ssize_t zfcp_sysfs_unit_add_store(struct device *dev,
zfcp_erp_unit_reopen(unit, 0, "syuas_1", NULL);
zfcp_erp_wait(unit->port->adapter);
- flush_work(&unit->scsi_work);
+ zfcp_scsi_scan(unit);
out:
put_device(&port->dev);
return retval ? retval : (ssize_t) count;
@@ -290,6 +290,7 @@ static ssize_t zfcp_sysfs_unit_remove_store(struct device *dev,
struct zfcp_unit *unit;
u64 fcp_lun;
int retval = -EINVAL;
+ struct scsi_device *sdev;
if (!(port && get_device(&port->dev)))
return -EBUSY;
@@ -303,8 +304,13 @@ static ssize_t zfcp_sysfs_unit_remove_store(struct device *dev,
else
retval = 0;
- /* wait for possible timeout during SCSI probe */
- flush_work(&unit->scsi_work);
+ sdev = scsi_device_lookup(port->adapter->scsi_host, 0,
+ port->starget_id,
+ scsilun_to_int((struct scsi_lun *)&fcp_lun));
+ if (sdev) {
+ scsi_remove_device(sdev);
+ scsi_device_put(sdev);
+ }
write_lock_irq(&port->unit_list_lock);
list_del(&unit->list);
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index 75f2336807c..158284f0573 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -1847,6 +1847,10 @@ config ZFCP
called zfcp. If you want to compile it as a module, say M here
and read <file:Documentation/kbuild/modules.txt>.
+config ZFCP_DIF
+ tristate "T10 DIF/DIX support for the zfcp driver (EXPERIMENTAL)"
+ depends on ZFCP && EXPERIMENTAL
+
config SCSI_PMCRAID
tristate "PMC SIERRA Linux MaxRAID adapter support"
depends on PCI && SCSI
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
index 1c7ac49be64..2a3fca2eca6 100644
--- a/drivers/scsi/Makefile
+++ b/drivers/scsi/Makefile
@@ -163,6 +163,7 @@ scsi_mod-$(CONFIG_SCSI_NETLINK) += scsi_netlink.o
scsi_mod-$(CONFIG_SYSCTL) += scsi_sysctl.o
scsi_mod-$(CONFIG_SCSI_PROC_FS) += scsi_proc.o
scsi_mod-y += scsi_trace.o
+scsi_mod-$(CONFIG_PM_OPS) += scsi_pm.o
scsi_tgt-y += scsi_tgt_lib.o scsi_tgt_if.o
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index 33898b61fdb..cad6f9abaeb 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -1091,6 +1091,7 @@ static int __devinit aac_probe_one(struct pci_dev *pdev,
struct list_head *insert = &aac_devices;
int error = -ENODEV;
int unique_id = 0;
+ u64 dmamask;
list_for_each_entry(aac, &aac_devices, entry) {
if (aac->id > unique_id)
@@ -1104,17 +1105,18 @@ static int __devinit aac_probe_one(struct pci_dev *pdev,
goto out;
error = -ENODEV;
- if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) ||
- pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)))
- goto out_disable_pdev;
/*
* If the quirk31 bit is set, the adapter needs adapter
* to driver communication memory to be allocated below 2gig
*/
if (aac_drivers[index].quirks & AAC_QUIRK_31BIT)
- if (pci_set_dma_mask(pdev, DMA_BIT_MASK(31)) ||
- pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(31)))
- goto out_disable_pdev;
+ dmamask = DMA_BIT_MASK(31);
+ else
+ dmamask = DMA_BIT_MASK(32);
+
+ if (pci_set_dma_mask(pdev, dmamask) ||
+ pci_set_consistent_dma_mask(pdev, dmamask))
+ goto out_disable_pdev;
pci_set_master(pdev);
diff --git a/drivers/scsi/aic7xxx/aic7770.c b/drivers/scsi/aic7xxx/aic7770.c
index 6d86a9be538..5000bd69c13 100644
--- a/drivers/scsi/aic7xxx/aic7770.c
+++ b/drivers/scsi/aic7xxx/aic7770.c
@@ -170,7 +170,7 @@ aic7770_config(struct ahc_softc *ahc, struct aic7770_identity *entry, u_int io)
case 15:
break;
default:
- printf("aic7770_config: invalid irq setting %d\n", intdef);
+ printk("aic7770_config: invalid irq setting %d\n", intdef);
return (ENXIO);
}
@@ -221,7 +221,7 @@ aic7770_config(struct ahc_softc *ahc, struct aic7770_identity *entry, u_int io)
break;
}
if (have_seeprom == 0) {
- free(ahc->seep_config, M_DEVBUF);
+ kfree(ahc->seep_config);
ahc->seep_config = NULL;
}
@@ -293,7 +293,7 @@ aha2840_load_seeprom(struct ahc_softc *ahc)
sc = ahc->seep_config;
if (bootverbose)
- printf("%s: Reading SEEPROM...", ahc_name(ahc));
+ printk("%s: Reading SEEPROM...", ahc_name(ahc));
have_seeprom = ahc_read_seeprom(&sd, (uint16_t *)sc,
/*start_addr*/0, sizeof(*sc)/2);
@@ -301,16 +301,16 @@ aha2840_load_seeprom(struct ahc_softc *ahc)
if (ahc_verify_cksum(sc) == 0) {
if(bootverbose)
- printf ("checksum error\n");
+ printk ("checksum error\n");
have_seeprom = 0;
} else if (bootverbose) {
- printf("done.\n");
+ printk("done.\n");
}
}
if (!have_seeprom) {
if (bootverbose)
- printf("%s: No SEEPROM available\n", ahc_name(ahc));
+ printk("%s: No SEEPROM available\n", ahc_name(ahc));
ahc->flags |= AHC_USEDEFAULTS;
} else {
/*
diff --git a/drivers/scsi/aic7xxx/aic7770_osm.c b/drivers/scsi/aic7xxx/aic7770_osm.c
index f220e5e436a..0cb8ef64b5c 100644
--- a/drivers/scsi/aic7xxx/aic7770_osm.c
+++ b/drivers/scsi/aic7xxx/aic7770_osm.c
@@ -85,7 +85,7 @@ aic7770_probe(struct device *dev)
int error;
sprintf(buf, "ahc_eisa:%d", eisaBase >> 12);
- name = malloc(strlen(buf) + 1, M_DEVBUF, M_NOWAIT);
+ name = kmalloc(strlen(buf) + 1, GFP_ATOMIC);
if (name == NULL)
return (ENOMEM);
strcpy(name, buf);
diff --git a/drivers/scsi/aic7xxx/aic79xx_core.c b/drivers/scsi/aic7xxx/aic79xx_core.c
index 78971db5b60..3233bf56443 100644
--- a/drivers/scsi/aic7xxx/aic79xx_core.c
+++ b/drivers/scsi/aic7xxx/aic79xx_core.c
@@ -289,7 +289,7 @@ ahd_set_modes(struct ahd_softc *ahd, ahd_mode src, ahd_mode dst)
|| ahd->dst_mode == AHD_MODE_UNKNOWN)
panic("Setting mode prior to saving it.\n");
if ((ahd_debug & AHD_SHOW_MODEPTR) != 0)
- printf("%s: Setting mode 0x%x\n", ahd_name(ahd),
+ printk("%s: Setting mode 0x%x\n", ahd_name(ahd),
ahd_build_mode_state(ahd, src, dst));
#endif
ahd_outb(ahd, MODE_PTR, ahd_build_mode_state(ahd, src, dst));
@@ -307,7 +307,7 @@ ahd_update_modes(struct ahd_softc *ahd)
mode_ptr = ahd_inb(ahd, MODE_PTR);
#ifdef AHD_DEBUG
if ((ahd_debug & AHD_SHOW_MODEPTR) != 0)
- printf("Reading mode 0x%x\n", mode_ptr);
+ printk("Reading mode 0x%x\n", mode_ptr);
#endif
ahd_extract_mode_state(ahd, mode_ptr, &src, &dst);
ahd_known_modes(ahd, src, dst);
@@ -877,7 +877,7 @@ ahd_queue_scb(struct ahd_softc *ahd, struct scb *scb)
uint64_t host_dataptr;
host_dataptr = ahd_le64toh(scb->hscb->dataptr);
- printf("%s: Queueing SCB %d:0x%x bus addr 0x%x - 0x%x%x/0x%x\n",
+ printk("%s: Queueing SCB %d:0x%x bus addr 0x%x - 0x%x%x/0x%x\n",
ahd_name(ahd),
SCB_GET_TAG(scb), scb->hscb->scsiid,
ahd_le32toh(scb->hscb->hscb_busaddr),
@@ -1174,7 +1174,7 @@ ahd_clear_fifo(struct ahd_softc *ahd, u_int fifo)
#ifdef AHD_DEBUG
if ((ahd_debug & AHD_SHOW_FIFOS) != 0)
- printf("%s: Clearing FIFO %d\n", ahd_name(ahd), fifo);
+ printk("%s: Clearing FIFO %d\n", ahd_name(ahd), fifo);
#endif
saved_modes = ahd_save_modes(ahd);
ahd_set_modes(ahd, fifo, fifo);
@@ -1215,7 +1215,7 @@ ahd_flush_qoutfifo(struct ahd_softc *ahd)
scbid = ahd_inw(ahd, GSFIFO);
scb = ahd_lookup_scb(ahd, scbid);
if (scb == NULL) {
- printf("%s: Warning - GSFIFO SCB %d invalid\n",
+ printk("%s: Warning - GSFIFO SCB %d invalid\n",
ahd_name(ahd), scbid);
continue;
}
@@ -1339,7 +1339,7 @@ rescan_fifos:
next_scbid = ahd_inw_scbram(ahd, SCB_NEXT_COMPLETE);
scb = ahd_lookup_scb(ahd, scbid);
if (scb == NULL) {
- printf("%s: Warning - DMA-up and complete "
+ printk("%s: Warning - DMA-up and complete "
"SCB %d invalid\n", ahd_name(ahd), scbid);
continue;
}
@@ -1360,7 +1360,7 @@ rescan_fifos:
next_scbid = ahd_inw_scbram(ahd, SCB_NEXT_COMPLETE);
scb = ahd_lookup_scb(ahd, scbid);
if (scb == NULL) {
- printf("%s: Warning - Complete Qfrz SCB %d invalid\n",
+ printk("%s: Warning - Complete Qfrz SCB %d invalid\n",
ahd_name(ahd), scbid);
continue;
}
@@ -1377,7 +1377,7 @@ rescan_fifos:
next_scbid = ahd_inw_scbram(ahd, SCB_NEXT_COMPLETE);
scb = ahd_lookup_scb(ahd, scbid);
if (scb == NULL) {
- printf("%s: Warning - Complete SCB %d invalid\n",
+ printk("%s: Warning - Complete SCB %d invalid\n",
ahd_name(ahd), scbid);
continue;
}
@@ -1682,7 +1682,7 @@ ahd_run_qoutfifo(struct ahd_softc *ahd)
scb_index = ahd_le16toh(completion->tag);
scb = ahd_lookup_scb(ahd, scb_index);
if (scb == NULL) {
- printf("%s: WARNING no command for scb %d "
+ printk("%s: WARNING no command for scb %d "
"(cmdcmplt)\nQOUTPOS = %d\n",
ahd_name(ahd), scb_index,
ahd->qoutfifonext);
@@ -1714,7 +1714,7 @@ ahd_handle_hwerrint(struct ahd_softc *ahd)
error = ahd_inb(ahd, ERROR);
for (i = 0; i < num_errors; i++) {
if ((error & ahd_hard_errors[i].errno) != 0)
- printf("%s: hwerrint, %s\n",
+ printk("%s: hwerrint, %s\n",
ahd_name(ahd), ahd_hard_errors[i].errmesg);
}
@@ -1747,7 +1747,7 @@ ahd_dump_sglist(struct scb *scb)
addr = ahd_le64toh(sg_list[i].addr);
len = ahd_le32toh(sg_list[i].len);
- printf("sg[%d] - Addr 0x%x%x : Length %d%s\n",
+ printk("sg[%d] - Addr 0x%x%x : Length %d%s\n",
i,
(uint32_t)((addr >> 32) & 0xFFFFFFFF),
(uint32_t)(addr & 0xFFFFFFFF),
@@ -1763,7 +1763,7 @@ ahd_dump_sglist(struct scb *scb)
uint32_t len;
len = ahd_le32toh(sg_list[i].len);
- printf("sg[%d] - Addr 0x%x%x : Length %d%s\n",
+ printk("sg[%d] - Addr 0x%x%x : Length %d%s\n",
i,
(len & AHD_SG_HIGH_ADDR_MASK) >> 24,
ahd_le32toh(sg_list[i].addr),
@@ -1802,7 +1802,7 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat)
ahd_update_modes(ahd);
#ifdef AHD_DEBUG
if ((ahd_debug & AHD_SHOW_MISC) != 0)
- printf("%s: Handle Seqint Called for code %d\n",
+ printk("%s: Handle Seqint Called for code %d\n",
ahd_name(ahd), seqintcode);
#endif
switch (seqintcode) {
@@ -1836,18 +1836,18 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat)
*/
#ifdef AHD_DEBUG
if ((ahd_debug & AHD_SHOW_RECOVERY) != 0)
- printf("%s: Assuming LQIPHASE_NLQ with "
+ printk("%s: Assuming LQIPHASE_NLQ with "
"P0 assertion\n", ahd_name(ahd));
#endif
}
#ifdef AHD_DEBUG
if ((ahd_debug & AHD_SHOW_RECOVERY) != 0)
- printf("%s: Entering NONPACK\n", ahd_name(ahd));
+ printk("%s: Entering NONPACK\n", ahd_name(ahd));
#endif
break;
}
case INVALID_SEQINT:
- printf("%s: Invalid Sequencer interrupt occurred, "
+ printk("%s: Invalid Sequencer interrupt occurred, "
"resetting channel.\n",
ahd_name(ahd));
#ifdef AHD_DEBUG
@@ -1866,8 +1866,8 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat)
if (scb != NULL)
ahd_print_path(ahd, scb);
else
- printf("%s: ", ahd_name(ahd));
- printf("SCB %d Packetized Status Overrun", scbid);
+ printk("%s: ", ahd_name(ahd));
+ printk("SCB %d Packetized Status Overrun", scbid);
ahd_dump_card_state(ahd);
ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE);
break;
@@ -1881,7 +1881,7 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat)
scb = ahd_lookup_scb(ahd, scbid);
if (scb == NULL) {
ahd_dump_card_state(ahd);
- printf("CFG4ISTAT: Free SCB %d referenced", scbid);
+ printk("CFG4ISTAT: Free SCB %d referenced", scbid);
panic("For safety");
}
ahd_outq(ahd, HADDR, scb->sense_busaddr);
@@ -1896,7 +1896,7 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat)
u_int bus_phase;
bus_phase = ahd_inb(ahd, SCSISIGI) & PHASE_MASK;
- printf("%s: ILLEGAL_PHASE 0x%x\n",
+ printk("%s: ILLEGAL_PHASE 0x%x\n",
ahd_name(ahd), bus_phase);
switch (bus_phase) {
@@ -1908,7 +1908,7 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat)
case P_STATUS:
case P_MESGIN:
ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE);
- printf("%s: Issued Bus Reset.\n", ahd_name(ahd));
+ printk("%s: Issued Bus Reset.\n", ahd_name(ahd));
break;
case P_COMMAND:
{
@@ -1933,7 +1933,7 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat)
scbid = ahd_get_scbptr(ahd);
scb = ahd_lookup_scb(ahd, scbid);
if (scb == NULL) {
- printf("Invalid phase with no valid SCB. "
+ printk("Invalid phase with no valid SCB. "
"Resetting bus.\n");
ahd_reset_channel(ahd, 'A',
/*Initiate Reset*/TRUE);
@@ -1997,7 +1997,7 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat)
#ifdef AHD_DEBUG
if ((ahd_debug & AHD_SHOW_RECOVERY) != 0) {
ahd_print_path(ahd, scb);
- printf("Unexpected command phase from "
+ printk("Unexpected command phase from "
"packetized target\n");
}
#endif
@@ -2013,7 +2013,7 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat)
#ifdef AHD_DEBUG
if ((ahd_debug & AHD_SHOW_RECOVERY) != 0) {
- printf("%s: CFG4OVERRUN mode = %x\n", ahd_name(ahd),
+ printk("%s: CFG4OVERRUN mode = %x\n", ahd_name(ahd),
ahd_inb(ahd, MODE_PTR));
}
#endif
@@ -2049,7 +2049,7 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat)
{
#ifdef AHD_DEBUG
if ((ahd_debug & AHD_SHOW_RECOVERY) != 0) {
- printf("%s: PDATA_REINIT - DFCNTRL = 0x%x "
+ printk("%s: PDATA_REINIT - DFCNTRL = 0x%x "
"SG_CACHE_SHADOW = 0x%x\n",
ahd_name(ahd), ahd_inb(ahd, DFCNTRL),
ahd_inb(ahd, SG_CACHE_SHADOW));
@@ -2082,7 +2082,7 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat)
bus_phase = ahd_inb(ahd, SCSISIGI) & PHASE_MASK;
if (bus_phase != P_MESGIN
&& bus_phase != P_MESGOUT) {
- printf("ahd_intr: HOST_MSG_LOOP bad "
+ printk("ahd_intr: HOST_MSG_LOOP bad "
"phase 0x%x\n", bus_phase);
/*
* Probably transitioned to bus free before
@@ -2131,29 +2131,29 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat)
AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
ahd_outb(ahd, SCSISEQ0, ahd_inb(ahd, SCSISEQ0) & ~ENSELO);
- printf("%s:%c:%d: no active SCB for reconnecting "
+ printk("%s:%c:%d: no active SCB for reconnecting "
"target - issuing BUS DEVICE RESET\n",
ahd_name(ahd), 'A', ahd_inb(ahd, SELID) >> 4);
- printf("SAVED_SCSIID == 0x%x, SAVED_LUN == 0x%x, "
+ printk("SAVED_SCSIID == 0x%x, SAVED_LUN == 0x%x, "
"REG0 == 0x%x ACCUM = 0x%x\n",
ahd_inb(ahd, SAVED_SCSIID), ahd_inb(ahd, SAVED_LUN),
ahd_inw(ahd, REG0), ahd_inb(ahd, ACCUM));
- printf("SEQ_FLAGS == 0x%x, SCBPTR == 0x%x, BTT == 0x%x, "
+ printk("SEQ_FLAGS == 0x%x, SCBPTR == 0x%x, BTT == 0x%x, "
"SINDEX == 0x%x\n",
ahd_inb(ahd, SEQ_FLAGS), ahd_get_scbptr(ahd),
ahd_find_busy_tcl(ahd,
BUILD_TCL(ahd_inb(ahd, SAVED_SCSIID),
ahd_inb(ahd, SAVED_LUN))),
ahd_inw(ahd, SINDEX));
- printf("SELID == 0x%x, SCB_SCSIID == 0x%x, SCB_LUN == 0x%x, "
+ printk("SELID == 0x%x, SCB_SCSIID == 0x%x, SCB_LUN == 0x%x, "
"SCB_CONTROL == 0x%x\n",
ahd_inb(ahd, SELID), ahd_inb_scbram(ahd, SCB_SCSIID),
ahd_inb_scbram(ahd, SCB_LUN),
ahd_inb_scbram(ahd, SCB_CONTROL));
- printf("SCSIBUS[0] == 0x%x, SCSISIGI == 0x%x\n",
+ printk("SCSIBUS[0] == 0x%x, SCSISIGI == 0x%x\n",
ahd_inb(ahd, SCSIBUS), ahd_inb(ahd, SCSISIGI));
- printf("SXFRCTL0 == 0x%x\n", ahd_inb(ahd, SXFRCTL0));
- printf("SEQCTL0 == 0x%x\n", ahd_inb(ahd, SEQCTL0));
+ printk("SXFRCTL0 == 0x%x\n", ahd_inb(ahd, SXFRCTL0));
+ printk("SEQCTL0 == 0x%x\n", ahd_inb(ahd, SEQCTL0));
ahd_dump_card_state(ahd);
ahd->msgout_buf[0] = MSG_BUS_DEV_RESET;
ahd->msgout_len = 1;
@@ -2181,7 +2181,7 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat)
u_int lastphase;
lastphase = ahd_inb(ahd, LASTPHASE);
- printf("%s:%c:%d: unknown scsi bus phase %x, "
+ printk("%s:%c:%d: unknown scsi bus phase %x, "
"lastphase = 0x%x. Attempting to continue\n",
ahd_name(ahd), 'A',
SCSIID_TARGET(ahd, ahd_inb(ahd, SAVED_SCSIID)),
@@ -2193,7 +2193,7 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat)
u_int lastphase;
lastphase = ahd_inb(ahd, LASTPHASE);
- printf("%s:%c:%d: Missed busfree. "
+ printk("%s:%c:%d: Missed busfree. "
"Lastphase = 0x%x, Curphase = 0x%x\n",
ahd_name(ahd), 'A',
SCSIID_TARGET(ahd, ahd_inb(ahd, SAVED_SCSIID)),
@@ -2223,11 +2223,11 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat)
lastphase = ahd_inb(ahd, LASTPHASE);
if ((ahd_debug & AHD_SHOW_RECOVERY) != 0) {
ahd_print_path(ahd, scb);
- printf("data overrun detected %s. Tag == 0x%x.\n",
+ printk("data overrun detected %s. Tag == 0x%x.\n",
ahd_lookup_phase_entry(lastphase)->phasemsg,
SCB_GET_TAG(scb));
ahd_print_path(ahd, scb);
- printf("%s seen Data Phase. Length = %ld. "
+ printk("%s seen Data Phase. Length = %ld. "
"NumSGs = %d.\n",
ahd_inb(ahd, SEQ_FLAGS) & DPHASE
? "Have" : "Haven't",
@@ -2252,7 +2252,7 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat)
u_int scbid;
ahd_fetch_devinfo(ahd, &devinfo);
- printf("%s:%c:%d:%d: Attempt to issue message failed\n",
+ printk("%s:%c:%d:%d: Attempt to issue message failed\n",
ahd_name(ahd), devinfo.channel, devinfo.target,
devinfo.lun);
scbid = ahd_get_scbptr(ahd);
@@ -2285,7 +2285,7 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat)
cam_status error;
ahd_print_path(ahd, scb);
- printf("Task Management Func 0x%x Complete\n",
+ printk("Task Management Func 0x%x Complete\n",
scb->hscb->task_management);
lun = CAM_LUN_WILDCARD;
tag = SCB_LIST_NULL;
@@ -2341,7 +2341,7 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat)
* the QINFIFO if it is still there.
*/
ahd_print_path(ahd, scb);
- printf("SCB completes before TMF\n");
+ printk("SCB completes before TMF\n");
/*
* Handle losing the race. Wait until any
* current selection completes. We will then
@@ -2366,7 +2366,7 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat)
case TRACEPOINT1:
case TRACEPOINT2:
case TRACEPOINT3:
- printf("%s: Tracepoint %d\n", ahd_name(ahd),
+ printk("%s: Tracepoint %d\n", ahd_name(ahd),
seqintcode - TRACEPOINT0);
break;
case NO_SEQINT:
@@ -2375,7 +2375,7 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat)
ahd_handle_hwerrint(ahd);
break;
default:
- printf("%s: Unexpected SEQINTCODE %d\n", ahd_name(ahd),
+ printk("%s: Unexpected SEQINTCODE %d\n", ahd_name(ahd),
seqintcode);
break;
}
@@ -2440,7 +2440,7 @@ ahd_handle_scsiint(struct ahd_softc *ahd, u_int intstat)
u_int now_lvd;
now_lvd = ahd_inb(ahd, SBLKCTL) & ENAB40;
- printf("%s: Transceiver State Has Changed to %s mode\n",
+ printk("%s: Transceiver State Has Changed to %s mode\n",
ahd_name(ahd), now_lvd ? "LVD" : "SE");
ahd_outb(ahd, CLRSINT0, CLRIOERR);
/*
@@ -2452,12 +2452,12 @@ ahd_handle_scsiint(struct ahd_softc *ahd, u_int intstat)
ahd_unpause(ahd);
} else if ((status0 & OVERRUN) != 0) {
- printf("%s: SCSI offset overrun detected. Resetting bus.\n",
+ printk("%s: SCSI offset overrun detected. Resetting bus.\n",
ahd_name(ahd));
ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE);
} else if ((status & SCSIRSTI) != 0) {
- printf("%s: Someone reset channel A\n", ahd_name(ahd));
+ printk("%s: Someone reset channel A\n", ahd_name(ahd));
ahd_reset_channel(ahd, 'A', /*Initiate Reset*/FALSE);
} else if ((status & SCSIPERR) != 0) {
@@ -2467,7 +2467,7 @@ ahd_handle_scsiint(struct ahd_softc *ahd, u_int intstat)
ahd_handle_transmission_error(ahd);
} else if (lqostat0 != 0) {
- printf("%s: lqostat0 == 0x%x!\n", ahd_name(ahd), lqostat0);
+ printk("%s: lqostat0 == 0x%x!\n", ahd_name(ahd), lqostat0);
ahd_outb(ahd, CLRLQOINT0, lqostat0);
if ((ahd->bugs & AHD_CLRLQO_AUTOCLR_BUG) != 0)
ahd_outb(ahd, CLRLQOINT1, 0);
@@ -2497,7 +2497,7 @@ ahd_handle_scsiint(struct ahd_softc *ahd, u_int intstat)
scbid = ahd_inw(ahd, WAITING_TID_HEAD);
scb = ahd_lookup_scb(ahd, scbid);
if (scb == NULL) {
- printf("%s: ahd_intr - referenced scb not "
+ printk("%s: ahd_intr - referenced scb not "
"valid during SELTO scb(0x%x)\n",
ahd_name(ahd), scbid);
ahd_dump_card_state(ahd);
@@ -2506,7 +2506,7 @@ ahd_handle_scsiint(struct ahd_softc *ahd, u_int intstat)
#ifdef AHD_DEBUG
if ((ahd_debug & AHD_SHOW_SELTO) != 0) {
ahd_print_path(ahd, scb);
- printf("Saw Selection Timeout for SCB 0x%x\n",
+ printk("Saw Selection Timeout for SCB 0x%x\n",
scbid);
}
#endif
@@ -2534,7 +2534,7 @@ ahd_handle_scsiint(struct ahd_softc *ahd, u_int intstat)
ahd_iocell_first_selection(ahd);
ahd_unpause(ahd);
} else if (status3 != 0) {
- printf("%s: SCSI Cell parity error SSTAT3 == 0x%x\n",
+ printk("%s: SCSI Cell parity error SSTAT3 == 0x%x\n",
ahd_name(ahd), status3);
ahd_outb(ahd, CLRSINT3, status3);
} else if ((lqistat1 & (LQIPHASE_LQ|LQIPHASE_NLQ)) != 0) {
@@ -2587,7 +2587,7 @@ ahd_handle_scsiint(struct ahd_softc *ahd, u_int intstat)
scbid = ahd_get_scbptr(ahd);
scb = ahd_lookup_scb(ahd, scbid);
if (scb == NULL) {
- printf("%s: Invalid SCB %d in DFF%d "
+ printk("%s: Invalid SCB %d in DFF%d "
"during unexpected busfree\n",
ahd_name(ahd), scbid, mode);
packetized = 0;
@@ -2620,7 +2620,7 @@ ahd_handle_scsiint(struct ahd_softc *ahd, u_int intstat)
#ifdef AHD_DEBUG
if ((ahd_debug & AHD_SHOW_MISC) != 0)
- printf("Saw Busfree. Busfreetime = 0x%x.\n",
+ printk("Saw Busfree. Busfreetime = 0x%x.\n",
busfreetime);
#endif
/*
@@ -2661,7 +2661,7 @@ ahd_handle_scsiint(struct ahd_softc *ahd, u_int intstat)
ahd_unpause(ahd);
}
} else {
- printf("%s: Missing case in ahd_handle_scsiint. status = %x\n",
+ printk("%s: Missing case in ahd_handle_scsiint. status = %x\n",
ahd_name(ahd), status);
ahd_dump_card_state(ahd);
ahd_clear_intstat(ahd);
@@ -2697,7 +2697,7 @@ ahd_handle_transmission_error(struct ahd_softc *ahd)
|| (lqistate == 0x29)) {
#ifdef AHD_DEBUG
if ((ahd_debug & AHD_SHOW_RECOVERY) != 0) {
- printf("%s: NLQCRC found via LQISTATE\n",
+ printk("%s: NLQCRC found via LQISTATE\n",
ahd_name(ahd));
}
#endif
@@ -2729,18 +2729,18 @@ ahd_handle_transmission_error(struct ahd_softc *ahd)
cur_col = 0;
if (silent == FALSE) {
- printf("%s: Transmission error detected\n", ahd_name(ahd));
+ printk("%s: Transmission error detected\n", ahd_name(ahd));
ahd_lqistat1_print(lqistat1, &cur_col, 50);
ahd_lastphase_print(lastphase, &cur_col, 50);
ahd_scsisigi_print(curphase, &cur_col, 50);
ahd_perrdiag_print(perrdiag, &cur_col, 50);
- printf("\n");
+ printk("\n");
ahd_dump_card_state(ahd);
}
if ((lqistat1 & (LQIOVERI_LQ|LQIOVERI_NLQ)) != 0) {
if (silent == FALSE) {
- printf("%s: Gross protocol error during incoming "
+ printk("%s: Gross protocol error during incoming "
"packet. lqistat1 == 0x%x. Resetting bus.\n",
ahd_name(ahd), lqistat1);
}
@@ -2769,7 +2769,7 @@ ahd_handle_transmission_error(struct ahd_softc *ahd)
* (SPI4R09 10.7.3.3.3)
*/
ahd_outb(ahd, LQCTL2, LQIRETRY);
- printf("LQIRetry for LQICRCI_LQ to release ACK\n");
+ printk("LQIRetry for LQICRCI_LQ to release ACK\n");
} else if ((lqistat1 & LQICRCI_NLQ) != 0) {
/*
* We detected a CRC error in a NON-LQ packet.
@@ -2817,22 +2817,22 @@ ahd_handle_transmission_error(struct ahd_softc *ahd)
* Busfree detection is enabled.
*/
if (silent == FALSE)
- printf("LQICRC_NLQ\n");
+ printk("LQICRC_NLQ\n");
if (scb == NULL) {
- printf("%s: No SCB valid for LQICRC_NLQ. "
+ printk("%s: No SCB valid for LQICRC_NLQ. "
"Resetting bus\n", ahd_name(ahd));
ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE);
return;
}
} else if ((lqistat1 & LQIBADLQI) != 0) {
- printf("Need to handle BADLQI!\n");
+ printk("Need to handle BADLQI!\n");
ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE);
return;
} else if ((perrdiag & (PARITYERR|PREVPHASE)) == PARITYERR) {
if ((curphase & ~P_DATAIN_DT) != 0) {
/* Ack the byte. So we can continue. */
if (silent == FALSE)
- printf("Acking %s to clear perror\n",
+ printk("Acking %s to clear perror\n",
ahd_lookup_phase_entry(curphase)->phasemsg);
ahd_inb(ahd, SCSIDAT);
}
@@ -2877,10 +2877,10 @@ ahd_handle_lqiphase_error(struct ahd_softc *ahd, u_int lqistat1)
if ((ahd_inb(ahd, SCSISIGO) & ATNO) != 0
&& (ahd_inb(ahd, MDFFSTAT) & DLZERO) != 0) {
if ((lqistat1 & LQIPHASE_LQ) != 0) {
- printf("LQIRETRY for LQIPHASE_LQ\n");
+ printk("LQIRETRY for LQIPHASE_LQ\n");
ahd_outb(ahd, LQCTL2, LQIRETRY);
} else if ((lqistat1 & LQIPHASE_NLQ) != 0) {
- printf("LQIRETRY for LQIPHASE_NLQ\n");
+ printk("LQIRETRY for LQIPHASE_NLQ\n");
ahd_outb(ahd, LQCTL2, LQIRETRY);
} else
panic("ahd_handle_lqiphase_error: No phase errors\n");
@@ -2888,7 +2888,7 @@ ahd_handle_lqiphase_error(struct ahd_softc *ahd, u_int lqistat1)
ahd_outb(ahd, CLRINT, CLRSCSIINT);
ahd_unpause(ahd);
} else {
- printf("Reseting Channel for LQI Phase error\n");
+ printk("Reseting Channel for LQI Phase error\n");
ahd_dump_card_state(ahd);
ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE);
}
@@ -2976,7 +2976,7 @@ ahd_handle_pkt_busfree(struct ahd_softc *ahd, u_int busfreetime)
if (scb->crc_retry_count < AHD_MAX_LQ_CRC_ERRORS) {
if (SCB_IS_SILENT(scb) == FALSE) {
ahd_print_path(ahd, scb);
- printf("Probable outgoing LQ CRC error. "
+ printk("Probable outgoing LQ CRC error. "
"Retrying command\n");
}
scb->crc_retry_count++;
@@ -2998,7 +2998,7 @@ ahd_handle_pkt_busfree(struct ahd_softc *ahd, u_int busfreetime)
ahd_outb(ahd, CLRSINT1, CLRSCSIPERR|CLRBUSFREE);
#ifdef AHD_DEBUG
if ((ahd_debug & AHD_SHOW_MASKED_ERRORS) != 0)
- printf("%s: Parity on last REQ detected "
+ printk("%s: Parity on last REQ detected "
"during busfree phase.\n",
ahd_name(ahd));
#endif
@@ -3012,7 +3012,7 @@ ahd_handle_pkt_busfree(struct ahd_softc *ahd, u_int busfreetime)
scbid = ahd_get_scbptr(ahd);
scb = ahd_lookup_scb(ahd, scbid);
ahd_print_path(ahd, scb);
- printf("Unexpected PKT busfree condition\n");
+ printk("Unexpected PKT busfree condition\n");
ahd_dump_card_state(ahd);
ahd_abort_scbs(ahd, SCB_GET_TARGET(ahd, scb), 'A',
SCB_GET_LUN(scb), SCB_GET_TAG(scb),
@@ -3021,7 +3021,7 @@ ahd_handle_pkt_busfree(struct ahd_softc *ahd, u_int busfreetime)
/* Return restarting the sequencer. */
return (1);
}
- printf("%s: Unexpected PKT busfree condition\n", ahd_name(ahd));
+ printk("%s: Unexpected PKT busfree condition\n", ahd_name(ahd));
ahd_dump_card_state(ahd);
/* Restart the sequencer. */
return (1);
@@ -3076,14 +3076,14 @@ ahd_handle_nonpkt_busfree(struct ahd_softc *ahd)
if (scb == NULL) {
ahd_print_devinfo(ahd, &devinfo);
- printf("Abort for unidentified "
+ printk("Abort for unidentified "
"connection completed.\n");
/* restart the sequencer. */
return (1);
}
sent_msg = ahd->msgout_buf[ahd->msgout_index - 1];
ahd_print_path(ahd, scb);
- printf("SCB %d - Abort%s Completed.\n",
+ printk("SCB %d - Abort%s Completed.\n",
SCB_GET_TAG(scb),
sent_msg == MSG_ABORT_TAG ? "" : " Tag");
@@ -3109,7 +3109,7 @@ ahd_handle_nonpkt_busfree(struct ahd_softc *ahd)
found = ahd_abort_scbs(ahd, target, 'A', saved_lun,
tag, ROLE_INITIATOR,
CAM_REQ_ABORTED);
- printf("found == 0x%x\n", found);
+ printk("found == 0x%x\n", found);
printerror = 0;
} else if (ahd_sent_msg(ahd, AHDMSG_1B,
MSG_BUS_DEV_RESET, TRUE)) {
@@ -3147,7 +3147,7 @@ ahd_handle_nonpkt_busfree(struct ahd_softc *ahd)
*/
#ifdef AHD_DEBUG
if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
- printf("PPR negotiation rejected busfree.\n");
+ printk("PPR negotiation rejected busfree.\n");
#endif
tinfo = ahd_fetch_transinfo(ahd, devinfo.channel,
devinfo.our_scsiid,
@@ -3191,7 +3191,7 @@ ahd_handle_nonpkt_busfree(struct ahd_softc *ahd)
*/
#ifdef AHD_DEBUG
if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
- printf("WDTR negotiation rejected busfree.\n");
+ printk("WDTR negotiation rejected busfree.\n");
#endif
ahd_set_width(ahd, &devinfo,
MSG_EXT_WDTR_BUS_8_BIT,
@@ -3216,7 +3216,7 @@ ahd_handle_nonpkt_busfree(struct ahd_softc *ahd)
*/
#ifdef AHD_DEBUG
if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
- printf("SDTR negotiation rejected busfree.\n");
+ printk("SDTR negotiation rejected busfree.\n");
#endif
ahd_set_syncrate(ahd, &devinfo,
/*period*/0, /*offset*/0,
@@ -3240,7 +3240,7 @@ ahd_handle_nonpkt_busfree(struct ahd_softc *ahd)
#ifdef AHD_DEBUG
if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
- printf("Expected IDE Busfree\n");
+ printk("Expected IDE Busfree\n");
#endif
printerror = 0;
} else if ((ahd->msg_flags & MSG_FLAG_EXPECT_QASREJ_BUSFREE)
@@ -3249,7 +3249,7 @@ ahd_handle_nonpkt_busfree(struct ahd_softc *ahd)
#ifdef AHD_DEBUG
if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
- printf("Expected QAS Reject Busfree\n");
+ printk("Expected QAS Reject Busfree\n");
#endif
printerror = 0;
}
@@ -3275,7 +3275,7 @@ ahd_handle_nonpkt_busfree(struct ahd_softc *ahd)
} else {
#ifdef AHD_DEBUG
if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
- printf("PPR Negotiation Busfree.\n");
+ printk("PPR Negotiation Busfree.\n");
#endif
ahd_done(ahd, scb);
}
@@ -3302,9 +3302,9 @@ ahd_handle_nonpkt_busfree(struct ahd_softc *ahd)
* We had not fully identified this connection,
* so we cannot abort anything.
*/
- printf("%s: ", ahd_name(ahd));
+ printk("%s: ", ahd_name(ahd));
}
- printf("Unexpected busfree %s, %d SCBs aborted, "
+ printk("Unexpected busfree %s, %d SCBs aborted, "
"PRGMCNT == 0x%x\n",
ahd_lookup_phase_entry(lastphase)->phasemsg,
aborted,
@@ -3342,7 +3342,7 @@ ahd_handle_proto_violation(struct ahd_softc *ahd)
* to match.
*/
ahd_print_devinfo(ahd, &devinfo);
- printf("Target did not send an IDENTIFY message. "
+ printk("Target did not send an IDENTIFY message. "
"LASTPHASE = 0x%x.\n", lastphase);
scb = NULL;
} else if (scb == NULL) {
@@ -3351,13 +3351,13 @@ ahd_handle_proto_violation(struct ahd_softc *ahd)
* transaction. Print an error and reset the bus.
*/
ahd_print_devinfo(ahd, &devinfo);
- printf("No SCB found during protocol violation\n");
+ printk("No SCB found during protocol violation\n");
goto proto_violation_reset;
} else {
ahd_set_transaction_status(scb, CAM_SEQUENCE_FAIL);
if ((seq_flags & NO_CDB_SENT) != 0) {
ahd_print_path(ahd, scb);
- printf("No or incomplete CDB sent to device.\n");
+ printk("No or incomplete CDB sent to device.\n");
} else if ((ahd_inb_scbram(ahd, SCB_CONTROL)
& STATUS_RCVD) == 0) {
/*
@@ -3368,10 +3368,10 @@ ahd_handle_proto_violation(struct ahd_softc *ahd)
* message.
*/
ahd_print_path(ahd, scb);
- printf("Completed command without status.\n");
+ printk("Completed command without status.\n");
} else {
ahd_print_path(ahd, scb);
- printf("Unknown protocol violation.\n");
+ printk("Unknown protocol violation.\n");
ahd_dump_card_state(ahd);
}
}
@@ -3385,7 +3385,7 @@ proto_violation_reset:
* it away with a bus reset.
*/
found = ahd_reset_channel(ahd, 'A', TRUE);
- printf("%s: Issued Channel %c Bus Reset. "
+ printk("%s: Issued Channel %c Bus Reset. "
"%d SCBs aborted\n", ahd_name(ahd), 'A', found);
} else {
/*
@@ -3407,7 +3407,7 @@ proto_violation_reset:
ahd_print_path(ahd, scb);
scb->flags |= SCB_ABORT;
}
- printf("Protocol violation %s. Attempting to abort.\n",
+ printk("Protocol violation %s. Attempting to abort.\n",
ahd_lookup_phase_entry(curphase)->phasemsg);
}
}
@@ -3425,7 +3425,7 @@ ahd_force_renegotiation(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
#ifdef AHD_DEBUG
if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) {
ahd_print_devinfo(ahd, devinfo);
- printf("Forcing renegotiation\n");
+ printk("Forcing renegotiation\n");
}
#endif
targ_info = ahd_fetch_transinfo(ahd,
@@ -3486,7 +3486,7 @@ ahd_clear_critical_section(struct ahd_softc *ahd)
break;
if (steps > AHD_MAX_STEPS) {
- printf("%s: Infinite loop in critical section\n"
+ printk("%s: Infinite loop in critical section\n"
"%s: First Instruction 0x%x now 0x%x\n",
ahd_name(ahd), ahd_name(ahd), first_instr,
seqaddr);
@@ -3497,7 +3497,7 @@ ahd_clear_critical_section(struct ahd_softc *ahd)
steps++;
#ifdef AHD_DEBUG
if ((ahd_debug & AHD_SHOW_MISC) != 0)
- printf("%s: Single stepping at 0x%x\n", ahd_name(ahd),
+ printk("%s: Single stepping at 0x%x\n", ahd_name(ahd),
seqaddr);
#endif
if (stepping == FALSE) {
@@ -3601,16 +3601,16 @@ ahd_print_scb(struct scb *scb)
int i;
hscb = scb->hscb;
- printf("scb:%p control:0x%x scsiid:0x%x lun:%d cdb_len:%d\n",
+ printk("scb:%p control:0x%x scsiid:0x%x lun:%d cdb_len:%d\n",
(void *)scb,
hscb->control,
hscb->scsiid,
hscb->lun,
hscb->cdb_len);
- printf("Shared Data: ");
+ printk("Shared Data: ");
for (i = 0; i < sizeof(hscb->shared_data.idata.cdb); i++)
- printf("%#02x", hscb->shared_data.idata.cdb[i]);
- printf(" dataptr:%#x%x datacnt:%#x sgptr:%#x tag:%#x\n",
+ printk("%#02x", hscb->shared_data.idata.cdb[i]);
+ printk(" dataptr:%#x%x datacnt:%#x sgptr:%#x tag:%#x\n",
(uint32_t)((ahd_le64toh(hscb->dataptr) >> 32) & 0xFFFFFFFF),
(uint32_t)(ahd_le64toh(hscb->dataptr) & 0xFFFFFFFF),
ahd_le32toh(hscb->datacnt),
@@ -3637,7 +3637,7 @@ ahd_alloc_tstate(struct ahd_softc *ahd, u_int scsi_id, char channel)
&& ahd->enabled_targets[scsi_id] != master_tstate)
panic("%s: ahd_alloc_tstate - Target already allocated",
ahd_name(ahd));
- tstate = malloc(sizeof(*tstate), M_DEVBUF, M_NOWAIT);
+ tstate = kmalloc(sizeof(*tstate), GFP_ATOMIC);
if (tstate == NULL)
return (NULL);
@@ -3682,7 +3682,7 @@ ahd_free_tstate(struct ahd_softc *ahd, u_int scsi_id, char channel, int force)
tstate = ahd->enabled_targets[scsi_id];
if (tstate != NULL)
- free(tstate, M_DEVBUF);
+ kfree(tstate);
ahd->enabled_targets[scsi_id] = NULL;
}
#endif
@@ -3942,37 +3942,37 @@ ahd_set_syncrate(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
if (offset != 0) {
int options;
- printf("%s: target %d synchronous with "
+ printk("%s: target %d synchronous with "
"period = 0x%x, offset = 0x%x",
ahd_name(ahd), devinfo->target,
period, offset);
options = 0;
if ((ppr_options & MSG_EXT_PPR_RD_STRM) != 0) {
- printf("(RDSTRM");
+ printk("(RDSTRM");
options++;
}
if ((ppr_options & MSG_EXT_PPR_DT_REQ) != 0) {
- printf("%s", options ? "|DT" : "(DT");
+ printk("%s", options ? "|DT" : "(DT");
options++;
}
if ((ppr_options & MSG_EXT_PPR_IU_REQ) != 0) {
- printf("%s", options ? "|IU" : "(IU");
+ printk("%s", options ? "|IU" : "(IU");
options++;
}
if ((ppr_options & MSG_EXT_PPR_RTI) != 0) {
- printf("%s", options ? "|RTI" : "(RTI");
+ printk("%s", options ? "|RTI" : "(RTI");
options++;
}
if ((ppr_options & MSG_EXT_PPR_QAS_REQ) != 0) {
- printf("%s", options ? "|QAS" : "(QAS");
+ printk("%s", options ? "|QAS" : "(QAS");
options++;
}
if (options != 0)
- printf(")\n");
+ printk(")\n");
else
- printf("\n");
+ printk("\n");
} else {
- printf("%s: target %d using "
+ printk("%s: target %d using "
"asynchronous transfers%s\n",
ahd_name(ahd), devinfo->target,
(ppr_options & MSG_EXT_PPR_QAS_REQ) != 0
@@ -4000,7 +4000,7 @@ ahd_set_syncrate(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
#ifdef AHD_DEBUG
if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) {
ahd_print_devinfo(ahd, devinfo);
- printf("Expecting IU Change busfree\n");
+ printk("Expecting IU Change busfree\n");
}
#endif
ahd->msg_flags |= MSG_FLAG_EXPECT_PPR_BUSFREE
@@ -4009,7 +4009,7 @@ ahd_set_syncrate(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
if ((old_ppr & MSG_EXT_PPR_IU_REQ) != 0) {
#ifdef AHD_DEBUG
if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
- printf("PPR with IU_REQ outstanding\n");
+ printk("PPR with IU_REQ outstanding\n");
#endif
ahd->msg_flags |= MSG_FLAG_EXPECT_PPR_BUSFREE;
}
@@ -4061,7 +4061,7 @@ ahd_set_width(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
ahd_send_async(ahd, devinfo->channel, devinfo->target,
CAM_LUN_WILDCARD, AC_TRANSFER_NEG);
if (bootverbose) {
- printf("%s: target %d using %dbit transfers\n",
+ printk("%s: target %d using %dbit transfers\n",
ahd_name(ahd), devinfo->target,
8 * (0x01 << width));
}
@@ -4337,7 +4337,7 @@ ahd_fetch_devinfo(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
void
ahd_print_devinfo(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
{
- printf("%s:%c:%d:%d: ", ahd_name(ahd), 'A',
+ printk("%s:%c:%d:%d: ", ahd_name(ahd), 'A',
devinfo->target, devinfo->lun);
}
@@ -4419,11 +4419,11 @@ ahd_setup_initiator_msgout(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
ahd->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
#ifdef AHD_DEBUG
if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
- printf("Setting up for Parity Error delivery\n");
+ printk("Setting up for Parity Error delivery\n");
#endif
return;
} else if (scb == NULL) {
- printf("%s: WARNING. No pending message for "
+ printk("%s: WARNING. No pending message for "
"I_T msgin. Issuing NO-OP\n", ahd_name(ahd));
ahd->msgout_buf[ahd->msgout_index++] = MSG_NOOP;
ahd->msgout_len++;
@@ -4454,7 +4454,7 @@ ahd_setup_initiator_msgout(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
ahd->msgout_buf[ahd->msgout_index++] = MSG_BUS_DEV_RESET;
ahd->msgout_len++;
ahd_print_path(ahd, scb);
- printf("Bus Device Reset Message Sent\n");
+ printk("Bus Device Reset Message Sent\n");
/*
* Clear our selection hardware in advance of
* the busfree. We may have an entry in the waiting
@@ -4472,7 +4472,7 @@ ahd_setup_initiator_msgout(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
}
ahd->msgout_len++;
ahd_print_path(ahd, scb);
- printf("Abort%s Message Sent\n",
+ printk("Abort%s Message Sent\n",
(scb->hscb->control & TAG_ENB) != 0 ? " Tag" : "");
/*
* Clear our selection hardware in advance of
@@ -4493,9 +4493,9 @@ ahd_setup_initiator_msgout(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
*/
ahd_outb(ahd, SCSISEQ0, 0);
} else {
- printf("ahd_intr: AWAITING_MSG for an SCB that "
+ printk("ahd_intr: AWAITING_MSG for an SCB that "
"does not have a waiting message\n");
- printf("SCSIID = %x, target_mask = %x\n", scb->hscb->scsiid,
+ printk("SCSIID = %x, target_mask = %x\n", scb->hscb->scsiid,
devinfo->target_mask);
panic("SCB = %d, SCB Control = %x:%x, MSG_OUT = %x "
"SCB flags = %x", SCB_GET_TAG(scb), scb->hscb->control,
@@ -4577,7 +4577,7 @@ ahd_build_transfer_msg(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
if (bootverbose) {
ahd_print_devinfo(ahd, devinfo);
- printf("Ensuring async\n");
+ printk("Ensuring async\n");
}
}
/* Target initiated PPR is not allowed in the SCSI spec */
@@ -4624,7 +4624,7 @@ ahd_construct_sdtr(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
ahd->msgout_buf + ahd->msgout_index, period, offset);
ahd->msgout_len += 5;
if (bootverbose) {
- printf("(%s:%c:%d:%d): Sending SDTR period %x, offset %x\n",
+ printk("(%s:%c:%d:%d): Sending SDTR period %x, offset %x\n",
ahd_name(ahd), devinfo->channel, devinfo->target,
devinfo->lun, period, offset);
}
@@ -4642,7 +4642,7 @@ ahd_construct_wdtr(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
ahd->msgout_buf + ahd->msgout_index, bus_width);
ahd->msgout_len += 4;
if (bootverbose) {
- printf("(%s:%c:%d:%d): Sending WDTR %x\n",
+ printk("(%s:%c:%d:%d): Sending WDTR %x\n",
ahd_name(ahd), devinfo->channel, devinfo->target,
devinfo->lun, bus_width);
}
@@ -4671,7 +4671,7 @@ ahd_construct_ppr(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
bus_width, ppr_options);
ahd->msgout_len += 8;
if (bootverbose) {
- printf("(%s:%c:%d:%d): Sending PPR bus_width %x, period %x, "
+ printk("(%s:%c:%d:%d): Sending PPR bus_width %x, period %x, "
"offset %x, ppr_options %x\n", ahd_name(ahd),
devinfo->channel, devinfo->target, devinfo->lun,
bus_width, period, offset, ppr_options);
@@ -4721,7 +4721,7 @@ ahd_handle_message_phase(struct ahd_softc *ahd)
bus_phase = ahd_inb(ahd, LASTPHASE);
if ((ahd_inb(ahd, LQISTAT2) & LQIPHASE_OUTPKT) != 0) {
- printf("LQIRETRY for LQIPHASE_OUTPKT\n");
+ printk("LQIRETRY for LQIPHASE_OUTPKT\n");
ahd_outb(ahd, LQCTL2, LQIRETRY);
}
reswitch:
@@ -4738,14 +4738,14 @@ reswitch:
#ifdef AHD_DEBUG
if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) {
ahd_print_devinfo(ahd, &devinfo);
- printf("INITIATOR_MSG_OUT");
+ printk("INITIATOR_MSG_OUT");
}
#endif
phasemis = bus_phase != P_MESGOUT;
if (phasemis) {
#ifdef AHD_DEBUG
if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) {
- printf(" PHASEMIS %s\n",
+ printk(" PHASEMIS %s\n",
ahd_lookup_phase_entry(bus_phase)
->phasemsg);
}
@@ -4772,7 +4772,7 @@ reswitch:
ahd_outb(ahd, CLRSINT1, CLRREQINIT);
#ifdef AHD_DEBUG
if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
- printf(" byte 0x%x\n", ahd->send_msg_perror);
+ printk(" byte 0x%x\n", ahd->send_msg_perror);
#endif
/*
* If we are notifying the target of a CRC error
@@ -4813,7 +4813,7 @@ reswitch:
ahd_outb(ahd, CLRSINT1, CLRREQINIT);
#ifdef AHD_DEBUG
if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
- printf(" byte 0x%x\n",
+ printk(" byte 0x%x\n",
ahd->msgout_buf[ahd->msgout_index]);
#endif
ahd_outb(ahd, RETURN_2, ahd->msgout_buf[ahd->msgout_index++]);
@@ -4828,14 +4828,14 @@ reswitch:
#ifdef AHD_DEBUG
if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) {
ahd_print_devinfo(ahd, &devinfo);
- printf("INITIATOR_MSG_IN");
+ printk("INITIATOR_MSG_IN");
}
#endif
phasemis = bus_phase != P_MESGIN;
if (phasemis) {
#ifdef AHD_DEBUG
if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) {
- printf(" PHASEMIS %s\n",
+ printk(" PHASEMIS %s\n",
ahd_lookup_phase_entry(bus_phase)
->phasemsg);
}
@@ -4856,7 +4856,7 @@ reswitch:
ahd->msgin_buf[ahd->msgin_index] = ahd_inb(ahd, SCSIBUS);
#ifdef AHD_DEBUG
if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
- printf(" byte 0x%x\n",
+ printk(" byte 0x%x\n",
ahd->msgin_buf[ahd->msgin_index]);
#endif
@@ -4878,7 +4878,7 @@ reswitch:
#ifdef AHD_DEBUG
if ((ahd_debug & AHD_SHOW_MESSAGES) != 0) {
ahd_print_devinfo(ahd, &devinfo);
- printf("Asserting ATN for response\n");
+ printk("Asserting ATN for response\n");
}
#endif
ahd_assert_atn(ahd);
@@ -5026,7 +5026,7 @@ reswitch:
if (end_session) {
if ((ahd->msg_flags & MSG_FLAG_PACKETIZED) != 0) {
- printf("%s: Returning to Idle Loop\n",
+ printk("%s: Returning to Idle Loop\n",
ahd_name(ahd));
ahd_clear_msg_state(ahd);
@@ -5178,7 +5178,7 @@ ahd_parse_msg(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
ahd_validate_offset(ahd, tinfo, period, &offset,
tinfo->curr.width, devinfo->role);
if (bootverbose) {
- printf("(%s:%c:%d:%d): Received "
+ printk("(%s:%c:%d:%d): Received "
"SDTR period %x, offset %x\n\t"
"Filtered to period %x, offset %x\n",
ahd_name(ahd), devinfo->channel,
@@ -5208,7 +5208,7 @@ ahd_parse_msg(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
*/
if (bootverbose
&& devinfo->role == ROLE_INITIATOR) {
- printf("(%s:%c:%d:%d): Target "
+ printk("(%s:%c:%d:%d): Target "
"Initiated SDTR\n",
ahd_name(ahd), devinfo->channel,
devinfo->target, devinfo->lun);
@@ -5250,7 +5250,7 @@ ahd_parse_msg(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
ahd_validate_width(ahd, tinfo, &bus_width,
devinfo->role);
if (bootverbose) {
- printf("(%s:%c:%d:%d): Received WDTR "
+ printk("(%s:%c:%d:%d): Received WDTR "
"%x filtered to %x\n",
ahd_name(ahd), devinfo->channel,
devinfo->target, devinfo->lun,
@@ -5266,7 +5266,7 @@ ahd_parse_msg(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
*/
if (saved_width > bus_width) {
reject = TRUE;
- printf("(%s:%c:%d:%d): requested %dBit "
+ printk("(%s:%c:%d:%d): requested %dBit "
"transfers. Rejecting...\n",
ahd_name(ahd), devinfo->channel,
devinfo->target, devinfo->lun,
@@ -5279,7 +5279,7 @@ ahd_parse_msg(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
*/
if (bootverbose
&& devinfo->role == ROLE_INITIATOR) {
- printf("(%s:%c:%d:%d): Target "
+ printk("(%s:%c:%d:%d): Target "
"Initiated WDTR\n",
ahd_name(ahd), devinfo->channel,
devinfo->target, devinfo->lun);
@@ -5391,12 +5391,12 @@ ahd_parse_msg(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
}
} else {
if (devinfo->role != ROLE_TARGET)
- printf("(%s:%c:%d:%d): Target "
+ printk("(%s:%c:%d:%d): Target "
"Initiated PPR\n",
ahd_name(ahd), devinfo->channel,
devinfo->target, devinfo->lun);
else
- printf("(%s:%c:%d:%d): Initiator "
+ printk("(%s:%c:%d:%d): Initiator "
"Initiated PPR\n",
ahd_name(ahd), devinfo->channel,
devinfo->target, devinfo->lun);
@@ -5408,7 +5408,7 @@ ahd_parse_msg(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
response = TRUE;
}
if (bootverbose) {
- printf("(%s:%c:%d:%d): Received PPR width %x, "
+ printk("(%s:%c:%d:%d): Received PPR width %x, "
"period %x, offset %x,options %x\n"
"\tFiltered to width %x, period %x, "
"offset %x, options %x\n",
@@ -5484,7 +5484,7 @@ ahd_parse_msg(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
case MSG_QAS_REQUEST:
#ifdef AHD_DEBUG
if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
- printf("%s: QAS request. SCSISIGI == 0x%x\n",
+ printk("%s: QAS request. SCSISIGI == 0x%x\n",
ahd_name(ahd), ahd_inb(ahd, SCSISIGI));
#endif
ahd->msg_flags |= MSG_FLAG_EXPECT_QASREJ_BUSFREE;
@@ -5549,7 +5549,7 @@ ahd_handle_msg_reject(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
* off these options.
*/
if (bootverbose) {
- printf("(%s:%c:%d:%d): PPR Rejected. "
+ printk("(%s:%c:%d:%d): PPR Rejected. "
"Trying simple U160 PPR\n",
ahd_name(ahd), devinfo->channel,
devinfo->target, devinfo->lun);
@@ -5564,7 +5564,7 @@ ahd_handle_msg_reject(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
* Attempt to negotiate SPI-2 style.
*/
if (bootverbose) {
- printf("(%s:%c:%d:%d): PPR Rejected. "
+ printk("(%s:%c:%d:%d): PPR Rejected. "
"Trying WDTR/SDTR\n",
ahd_name(ahd), devinfo->channel,
devinfo->target, devinfo->lun);
@@ -5581,7 +5581,7 @@ ahd_handle_msg_reject(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
} else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_WDTR, /*full*/FALSE)) {
/* note 8bit xfers */
- printf("(%s:%c:%d:%d): refuses WIDE negotiation. Using "
+ printk("(%s:%c:%d:%d): refuses WIDE negotiation. Using "
"8bit transfers\n", ahd_name(ahd),
devinfo->channel, devinfo->target, devinfo->lun);
ahd_set_width(ahd, devinfo, MSG_EXT_WDTR_BUS_8_BIT,
@@ -5609,7 +5609,7 @@ ahd_handle_msg_reject(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
/*offset*/0, /*ppr_options*/0,
AHD_TRANS_ACTIVE|AHD_TRANS_GOAL,
/*paused*/TRUE);
- printf("(%s:%c:%d:%d): refuses synchronous negotiation. "
+ printk("(%s:%c:%d:%d): refuses synchronous negotiation. "
"Using asynchronous transfers\n",
ahd_name(ahd), devinfo->channel,
devinfo->target, devinfo->lun);
@@ -5620,13 +5620,13 @@ ahd_handle_msg_reject(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
tag_type = (scb->hscb->control & MSG_SIMPLE_TASK);
if (tag_type == MSG_SIMPLE_TASK) {
- printf("(%s:%c:%d:%d): refuses tagged commands. "
+ printk("(%s:%c:%d:%d): refuses tagged commands. "
"Performing non-tagged I/O\n", ahd_name(ahd),
devinfo->channel, devinfo->target, devinfo->lun);
ahd_set_tags(ahd, scb->io_ctx, devinfo, AHD_QUEUE_NONE);
mask = ~0x23;
} else {
- printf("(%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",
ahd_name(ahd), devinfo->channel, devinfo->target,
devinfo->lun, tag_type == MSG_ORDERED_TASK
@@ -5677,7 +5677,7 @@ ahd_handle_msg_reject(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
/*
* Otherwise, we ignore it.
*/
- printf("%s:%c:%d: Message reject for %x -- ignored\n",
+ printk("%s:%c:%d: Message reject for %x -- ignored\n",
ahd_name(ahd), devinfo->channel, devinfo->target,
last_msg);
}
@@ -5864,7 +5864,7 @@ ahd_reinitialize_dataptrs(struct ahd_softc *ahd)
ahd_delay(100);
if (wait == 0) {
ahd_print_path(ahd, scb);
- printf("ahd_reinitialize_dataptrs: Forcing FIFO free.\n");
+ printk("ahd_reinitialize_dataptrs: Forcing FIFO free.\n");
ahd_outb(ahd, DFFSXFRCTL, RSTCHN|CLRSHCNT);
}
saved_modes = ahd_save_modes(ahd);
@@ -5978,7 +5978,7 @@ ahd_handle_devreset(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
CAM_LUN_WILDCARD, AC_SENT_BDR);
if (message != NULL && bootverbose)
- printf("%s: %s on %c:%d. %d SCBs aborted\n", ahd_name(ahd),
+ printk("%s: %s on %c:%d. %d SCBs aborted\n", ahd_name(ahd),
message, devinfo->channel, devinfo->target, found);
}
@@ -6074,23 +6074,22 @@ ahd_alloc(void *platform_arg, char *name)
struct ahd_softc *ahd;
#ifndef __FreeBSD__
- ahd = malloc(sizeof(*ahd), M_DEVBUF, M_NOWAIT);
+ ahd = kmalloc(sizeof(*ahd), GFP_ATOMIC);
if (!ahd) {
- printf("aic7xxx: cannot malloc softc!\n");
- free(name, M_DEVBUF);
+ printk("aic7xxx: cannot malloc softc!\n");
+ kfree(name);
return NULL;
}
#else
ahd = device_get_softc((device_t)platform_arg);
#endif
memset(ahd, 0, sizeof(*ahd));
- ahd->seep_config = malloc(sizeof(*ahd->seep_config),
- M_DEVBUF, M_NOWAIT);
+ ahd->seep_config = kmalloc(sizeof(*ahd->seep_config), GFP_ATOMIC);
if (ahd->seep_config == NULL) {
#ifndef __FreeBSD__
- free(ahd, M_DEVBUF);
+ kfree(ahd);
#endif
- free(name, M_DEVBUF);
+ kfree(name);
return (NULL);
}
LIST_INIT(&ahd->pending_scbs);
@@ -6120,7 +6119,7 @@ ahd_alloc(void *platform_arg, char *name)
}
#ifdef AHD_DEBUG
if ((ahd_debug & AHD_SHOW_MEMORY) != 0) {
- printf("%s: scb size = 0x%x, hscb size = 0x%x\n",
+ printk("%s: scb size = 0x%x, hscb size = 0x%x\n",
ahd_name(ahd), (u_int)sizeof(struct scb),
(u_int)sizeof(struct hardware_scb));
}
@@ -6147,7 +6146,7 @@ void
ahd_set_name(struct ahd_softc *ahd, char *name)
{
if (ahd->name != NULL)
- free(ahd->name, M_DEVBUF);
+ kfree(ahd->name);
ahd->name = name;
}
@@ -6201,27 +6200,27 @@ ahd_free(struct ahd_softc *ahd)
lstate = tstate->enabled_luns[j];
if (lstate != NULL) {
xpt_free_path(lstate->path);
- free(lstate, M_DEVBUF);
+ kfree(lstate);
}
}
#endif
- free(tstate, M_DEVBUF);
+ kfree(tstate);
}
}
#ifdef AHD_TARGET_MODE
if (ahd->black_hole != NULL) {
xpt_free_path(ahd->black_hole->path);
- free(ahd->black_hole, M_DEVBUF);
+ kfree(ahd->black_hole);
}
#endif
if (ahd->name != NULL)
- free(ahd->name, M_DEVBUF);
+ kfree(ahd->name);
if (ahd->seep_config != NULL)
- free(ahd->seep_config, M_DEVBUF);
+ kfree(ahd->seep_config);
if (ahd->saved_stack != NULL)
- free(ahd->saved_stack, M_DEVBUF);
+ kfree(ahd->saved_stack);
#ifndef __FreeBSD__
- free(ahd, M_DEVBUF);
+ kfree(ahd);
#endif
return;
}
@@ -6300,7 +6299,7 @@ ahd_reset(struct ahd_softc *ahd, int reinit)
} while (--wait && !(ahd_inb(ahd, HCNTRL) & CHIPRSTACK));
if (wait == 0) {
- printf("%s: WARNING - Failed chip reset! "
+ printk("%s: WARNING - Failed chip reset! "
"Trying to initialize anyway.\n", ahd_name(ahd));
}
ahd_outb(ahd, HCNTRL, ahd->pause);
@@ -6422,7 +6421,7 @@ ahd_init_scbdata(struct ahd_softc *ahd)
/* Determine the number of hardware SCBs and initialize them */
scb_data->maxhscbs = ahd_probe_scbs(ahd);
if (scb_data->maxhscbs == 0) {
- printf("%s: No SCB space found\n", ahd_name(ahd));
+ printk("%s: No SCB space found\n", ahd_name(ahd));
return (ENXIO);
}
@@ -6465,7 +6464,7 @@ ahd_init_scbdata(struct ahd_softc *ahd)
}
#ifdef AHD_DEBUG
if ((ahd_debug & AHD_SHOW_MEMORY) != 0)
- printf("%s: ahd_sglist_allocsize = 0x%x\n", ahd_name(ahd),
+ printk("%s: ahd_sglist_allocsize = 0x%x\n", ahd_name(ahd),
ahd_sglist_allocsize(ahd));
#endif
@@ -6489,7 +6488,7 @@ ahd_init_scbdata(struct ahd_softc *ahd)
ahd_alloc_scbs(ahd);
if (scb_data->numscbs == 0) {
- printf("%s: ahd_init_scbdata - "
+ printk("%s: ahd_init_scbdata - "
"Unable to allocate initial scbs\n",
ahd_name(ahd));
goto error_exit;
@@ -6564,7 +6563,7 @@ ahd_fini_scbdata(struct ahd_softc *ahd)
sns_map->dmamap);
ahd_dmamem_free(ahd, scb_data->sense_dmat,
sns_map->vaddr, sns_map->dmamap);
- free(sns_map, M_DEVBUF);
+ kfree(sns_map);
}
ahd_dma_tag_destroy(ahd, scb_data->sense_dmat);
/* FALLTHROUGH */
@@ -6579,7 +6578,7 @@ ahd_fini_scbdata(struct ahd_softc *ahd)
sg_map->dmamap);
ahd_dmamem_free(ahd, scb_data->sg_dmat,
sg_map->vaddr, sg_map->dmamap);
- free(sg_map, M_DEVBUF);
+ kfree(sg_map);
}
ahd_dma_tag_destroy(ahd, scb_data->sg_dmat);
/* FALLTHROUGH */
@@ -6594,7 +6593,7 @@ ahd_fini_scbdata(struct ahd_softc *ahd)
hscb_map->dmamap);
ahd_dmamem_free(ahd, scb_data->hscb_dmat,
hscb_map->vaddr, hscb_map->dmamap);
- free(hscb_map, M_DEVBUF);
+ kfree(hscb_map);
}
ahd_dma_tag_destroy(ahd, scb_data->hscb_dmat);
/* FALLTHROUGH */
@@ -6624,7 +6623,7 @@ ahd_setup_iocell_workaround(struct ahd_softc *ahd)
ahd_outb(ahd, SIMODE0, ahd_inb(ahd, SIMODE0) | (ENSELDO|ENSELDI));
#ifdef AHD_DEBUG
if ((ahd_debug & AHD_SHOW_MISC) != 0)
- printf("%s: Setting up iocell workaround\n", ahd_name(ahd));
+ printk("%s: Setting up iocell workaround\n", ahd_name(ahd));
#endif
ahd_restore_modes(ahd, saved_modes);
ahd->flags &= ~AHD_HAD_FIRST_SEL;
@@ -6644,14 +6643,14 @@ ahd_iocell_first_selection(struct ahd_softc *ahd)
ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
#ifdef AHD_DEBUG
if ((ahd_debug & AHD_SHOW_MISC) != 0)
- printf("%s: iocell first selection\n", ahd_name(ahd));
+ printk("%s: iocell first selection\n", ahd_name(ahd));
#endif
if ((sblkctl & ENAB40) != 0) {
ahd_outb(ahd, DSPDATACTL,
ahd_inb(ahd, DSPDATACTL) & ~BYPASSENAB);
#ifdef AHD_DEBUG
if ((ahd_debug & AHD_SHOW_MISC) != 0)
- printf("%s: BYPASS now disabled\n", ahd_name(ahd));
+ printk("%s: BYPASS now disabled\n", ahd_name(ahd));
#endif
}
ahd_outb(ahd, SIMODE0, ahd_inb(ahd, SIMODE0) & ~(ENSELDO|ENSELDI));
@@ -6833,7 +6832,7 @@ ahd_alloc_scbs(struct ahd_softc *ahd)
hscb = &((struct hardware_scb *)hscb_map->vaddr)[offset];
hscb_busaddr = hscb_map->physaddr + (offset * sizeof(*hscb));
} else {
- hscb_map = malloc(sizeof(*hscb_map), M_DEVBUF, M_NOWAIT);
+ hscb_map = kmalloc(sizeof(*hscb_map), GFP_ATOMIC);
if (hscb_map == NULL)
return;
@@ -6842,7 +6841,7 @@ ahd_alloc_scbs(struct ahd_softc *ahd)
if (ahd_dmamem_alloc(ahd, scb_data->hscb_dmat,
(void **)&hscb_map->vaddr,
BUS_DMA_NOWAIT, &hscb_map->dmamap) != 0) {
- free(hscb_map, M_DEVBUF);
+ kfree(hscb_map);
return;
}
@@ -6866,7 +6865,7 @@ ahd_alloc_scbs(struct ahd_softc *ahd)
segs = sg_map->vaddr + offset;
sg_busaddr = sg_map->physaddr + offset;
} else {
- sg_map = malloc(sizeof(*sg_map), M_DEVBUF, M_NOWAIT);
+ sg_map = kmalloc(sizeof(*sg_map), GFP_ATOMIC);
if (sg_map == NULL)
return;
@@ -6875,7 +6874,7 @@ ahd_alloc_scbs(struct ahd_softc *ahd)
if (ahd_dmamem_alloc(ahd, scb_data->sg_dmat,
(void **)&sg_map->vaddr,
BUS_DMA_NOWAIT, &sg_map->dmamap) != 0) {
- free(sg_map, M_DEVBUF);
+ kfree(sg_map);
return;
}
@@ -6891,7 +6890,7 @@ ahd_alloc_scbs(struct ahd_softc *ahd)
ahd_sglist_allocsize(ahd) / ahd_sglist_size(ahd);
#ifdef AHD_DEBUG
if (ahd_debug & AHD_SHOW_MEMORY)
- printf("Mapped SG data\n");
+ printk("Mapped SG data\n");
#endif
}
@@ -6903,7 +6902,7 @@ ahd_alloc_scbs(struct ahd_softc *ahd)
sense_data = sense_map->vaddr + offset;
sense_busaddr = sense_map->physaddr + offset;
} else {
- sense_map = malloc(sizeof(*sense_map), M_DEVBUF, M_NOWAIT);
+ sense_map = kmalloc(sizeof(*sense_map), GFP_ATOMIC);
if (sense_map == NULL)
return;
@@ -6912,7 +6911,7 @@ ahd_alloc_scbs(struct ahd_softc *ahd)
if (ahd_dmamem_alloc(ahd, scb_data->sense_dmat,
(void **)&sense_map->vaddr,
BUS_DMA_NOWAIT, &sense_map->dmamap) != 0) {
- free(sense_map, M_DEVBUF);
+ kfree(sense_map);
return;
}
@@ -6927,7 +6926,7 @@ ahd_alloc_scbs(struct ahd_softc *ahd)
scb_data->sense_left = PAGE_SIZE / AHD_SENSE_BUFSIZE;
#ifdef AHD_DEBUG
if (ahd_debug & AHD_SHOW_MEMORY)
- printf("Mapped sense data\n");
+ printk("Mapped sense data\n");
#endif
}
@@ -6941,15 +6940,13 @@ ahd_alloc_scbs(struct ahd_softc *ahd)
int error;
#endif
- next_scb = (struct scb *)malloc(sizeof(*next_scb),
- M_DEVBUF, M_NOWAIT);
+ next_scb = kmalloc(sizeof(*next_scb), GFP_ATOMIC);
if (next_scb == NULL)
break;
- pdata = (struct scb_platform_data *)malloc(sizeof(*pdata),
- M_DEVBUF, M_NOWAIT);
+ pdata = kmalloc(sizeof(*pdata), GFP_ATOMIC);
if (pdata == NULL) {
- free(next_scb, M_DEVBUF);
+ kfree(next_scb);
break;
}
next_scb->platform_data = pdata;
@@ -6979,8 +6976,8 @@ ahd_alloc_scbs(struct ahd_softc *ahd)
error = ahd_dmamap_create(ahd, ahd->buffer_dmat, /*flags*/0,
&next_scb->dmamap);
if (error != 0) {
- free(next_scb, M_DEVBUF);
- free(pdata, M_DEVBUF);
+ kfree(next_scb);
+ kfree(pdata);
break;
}
#endif
@@ -7077,8 +7074,7 @@ ahd_init(struct ahd_softc *ahd)
AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
ahd->stack_size = ahd_probe_stack_size(ahd);
- ahd->saved_stack = malloc(ahd->stack_size * sizeof(uint16_t),
- M_DEVBUF, M_NOWAIT);
+ ahd->saved_stack = kmalloc(ahd->stack_size * sizeof(uint16_t), GFP_ATOMIC);
if (ahd->saved_stack == NULL)
return (ENOMEM);
@@ -7224,20 +7220,20 @@ ahd_init(struct ahd_softc *ahd)
error = ahd_write_flexport(ahd, FLXADDR_ROMSTAT_CURSENSECTL,
CURSENSE_ENB);
if (error != 0) {
- printf("%s: current sensing timeout 1\n", ahd_name(ahd));
+ printk("%s: current sensing timeout 1\n", ahd_name(ahd));
goto init_done;
}
for (i = 20, fstat = FLX_FSTAT_BUSY;
(fstat & FLX_FSTAT_BUSY) != 0 && i; i--) {
error = ahd_read_flexport(ahd, FLXADDR_FLEXSTAT, &fstat);
if (error != 0) {
- printf("%s: current sensing timeout 2\n",
+ printk("%s: current sensing timeout 2\n",
ahd_name(ahd));
goto init_done;
}
}
if (i == 0) {
- printf("%s: Timedout during current-sensing test\n",
+ printk("%s: Timedout during current-sensing test\n",
ahd_name(ahd));
goto init_done;
}
@@ -7245,7 +7241,7 @@ ahd_init(struct ahd_softc *ahd)
/* Latch Current Sensing status. */
error = ahd_read_flexport(ahd, FLXADDR_CURRENT_STAT, &current_sensing);
if (error != 0) {
- printf("%s: current sensing timeout 3\n", ahd_name(ahd));
+ printk("%s: current sensing timeout 3\n", ahd_name(ahd));
goto init_done;
}
@@ -7254,7 +7250,7 @@ ahd_init(struct ahd_softc *ahd)
#ifdef AHD_DEBUG
if ((ahd_debug & AHD_SHOW_TERMCTL) != 0) {
- printf("%s: current_sensing == 0x%x\n",
+ printk("%s: current_sensing == 0x%x\n",
ahd_name(ahd), current_sensing);
}
#endif
@@ -7271,13 +7267,13 @@ ahd_init(struct ahd_softc *ahd)
case FLX_CSTAT_OKAY:
if (warn_user == 0 && bootverbose == 0)
break;
- printf("%s: %s Channel %s\n", ahd_name(ahd),
+ printk("%s: %s Channel %s\n", ahd_name(ahd),
channel_strings[i], termstat_strings[term_stat]);
break;
}
}
if (warn_user) {
- printf("%s: WARNING. Termination is not configured correctly.\n"
+ printk("%s: WARNING. Termination is not configured correctly.\n"
"%s: WARNING. SCSI bus operations may FAIL.\n",
ahd_name(ahd), ahd_name(ahd));
}
@@ -7393,7 +7389,7 @@ ahd_chip_init(struct ahd_softc *ahd)
}
#ifdef AHD_DEBUG
if ((ahd_debug & AHD_SHOW_MISC) != 0)
- printf("%s: WRTBIASCTL now 0x%x\n", ahd_name(ahd),
+ printk("%s: WRTBIASCTL now 0x%x\n", ahd_name(ahd),
WRTBIASCTL_HP_DEFAULT);
#endif
}
@@ -7622,9 +7618,9 @@ ahd_chip_init(struct ahd_softc *ahd)
ahd_outb(ahd, NEGCONOPTS, negodat3);
negodat3 = ahd_inb(ahd, NEGCONOPTS);
if (!(negodat3 & ENSLOWCRC))
- printf("aic79xx: failed to set the SLOWCRC bit\n");
+ printk("aic79xx: failed to set the SLOWCRC bit\n");
else
- printf("aic79xx: SLOWCRC bit set\n");
+ printk("aic79xx: SLOWCRC bit set\n");
}
}
@@ -7646,7 +7642,7 @@ ahd_default_config(struct ahd_softc *ahd)
* data for any target mode initiator.
*/
if (ahd_alloc_tstate(ahd, ahd->our_id, 'A') == NULL) {
- printf("%s: unable to allocate ahd_tmode_tstate. "
+ printk("%s: unable to allocate ahd_tmode_tstate. "
"Failing attach\n", ahd_name(ahd));
return (ENOMEM);
}
@@ -7725,7 +7721,7 @@ ahd_parse_cfgdata(struct ahd_softc *ahd, struct seeprom_config *sc)
* data for any target mode initiator.
*/
if (ahd_alloc_tstate(ahd, ahd->our_id, 'A') == NULL) {
- printf("%s: unable to allocate ahd_tmode_tstate. "
+ printk("%s: unable to allocate ahd_tmode_tstate. "
"Failing attach\n", ahd_name(ahd));
return (ENOMEM);
}
@@ -7795,7 +7791,7 @@ ahd_parse_cfgdata(struct ahd_softc *ahd, struct seeprom_config *sc)
user_tinfo->width = MSG_EXT_WDTR_BUS_8_BIT;
#ifdef AHD_DEBUG
if ((ahd_debug & AHD_SHOW_MISC) != 0)
- printf("(%d): %x:%x:%x:%x\n", targ, user_tinfo->width,
+ printk("(%d): %x:%x:%x:%x\n", targ, user_tinfo->width,
user_tinfo->period, user_tinfo->offset,
user_tinfo->ppr_options);
#endif
@@ -7951,7 +7947,7 @@ ahd_pause_and_flushwork(struct ahd_softc *ahd)
|| (ahd_inb(ahd, SSTAT0) & (SELDO|SELINGO)) != 0));
if (maxloops == 0) {
- printf("Infinite interrupt loop, INTSTAT = %x",
+ printk("Infinite interrupt loop, INTSTAT = %x",
ahd_inb(ahd, INTSTAT));
}
ahd->qfreeze_cnt++;
@@ -8241,7 +8237,7 @@ ahd_search_qinfifo(struct ahd_softc *ahd, int target, char channel,
prev_scb = NULL;
if (action == SEARCH_PRINT) {
- printf("qinstart = %d qinfifonext = %d\nQINFIFO:",
+ printk("qinstart = %d qinfifonext = %d\nQINFIFO:",
qinstart, ahd->qinfifonext);
}
@@ -8256,7 +8252,7 @@ ahd_search_qinfifo(struct ahd_softc *ahd, int target, char channel,
while (qinpos != qintail) {
scb = ahd_lookup_scb(ahd, ahd->qinfifo[qinpos]);
if (scb == NULL) {
- printf("qinpos = %d, SCB index = %d\n",
+ printk("qinpos = %d, SCB index = %d\n",
qinpos, ahd->qinfifo[qinpos]);
panic("Loop 1\n");
}
@@ -8269,13 +8265,13 @@ ahd_search_qinfifo(struct ahd_softc *ahd, int target, char channel,
switch (action) {
case SEARCH_COMPLETE:
if ((scb->flags & SCB_ACTIVE) == 0)
- printf("Inactive SCB in qinfifo\n");
+ printk("Inactive SCB in qinfifo\n");
ahd_done_with_status(ahd, scb, status);
/* FALLTHROUGH */
case SEARCH_REMOVE:
break;
case SEARCH_PRINT:
- printf(" 0x%x", ahd->qinfifo[qinpos]);
+ printk(" 0x%x", ahd->qinfifo[qinpos]);
/* FALLTHROUGH */
case SEARCH_COUNT:
ahd_qinfifo_requeue(ahd, prev_scb, scb);
@@ -8292,7 +8288,7 @@ ahd_search_qinfifo(struct ahd_softc *ahd, int target, char channel,
ahd_set_hnscb_qoff(ahd, ahd->qinfifonext);
if (action == SEARCH_PRINT)
- printf("\nWAITING_TID_QUEUES:\n");
+ printk("\nWAITING_TID_QUEUES:\n");
/*
* Search waiting for selection lists. We traverse the
@@ -8320,7 +8316,7 @@ ahd_search_qinfifo(struct ahd_softc *ahd, int target, char channel,
panic("TID LIST LOOP");
if (scbid >= ahd->scb_data.numscbs) {
- printf("%s: Waiting TID List inconsistency. "
+ printk("%s: Waiting TID List inconsistency. "
"SCB index == 0x%x, yet numscbs == 0x%x.",
ahd_name(ahd), scbid, ahd->scb_data.numscbs);
ahd_dump_card_state(ahd);
@@ -8328,7 +8324,7 @@ ahd_search_qinfifo(struct ahd_softc *ahd, int target, char channel,
}
scb = ahd_lookup_scb(ahd, scbid);
if (scb == NULL) {
- printf("%s: SCB = 0x%x Not Active!\n",
+ printk("%s: SCB = 0x%x Not Active!\n",
ahd_name(ahd), scbid);
panic("Waiting TID List traversal\n");
}
@@ -8344,7 +8340,7 @@ ahd_search_qinfifo(struct ahd_softc *ahd, int target, char channel,
* We found a list of scbs that needs to be searched.
*/
if (action == SEARCH_PRINT)
- printf(" %d ( ", SCB_GET_TARGET(ahd, scb));
+ printk(" %d ( ", SCB_GET_TARGET(ahd, scb));
tid_head = scbid;
found += ahd_search_scb_list(ahd, target, channel,
lun, tag, role, status,
@@ -8365,14 +8361,14 @@ ahd_search_qinfifo(struct ahd_softc *ahd, int target, char channel,
switch (action) {
case SEARCH_COMPLETE:
if ((mk_msg_scb->flags & SCB_ACTIVE) == 0)
- printf("Inactive SCB pending MK_MSG\n");
+ printk("Inactive SCB pending MK_MSG\n");
ahd_done_with_status(ahd, mk_msg_scb, status);
/* FALLTHROUGH */
case SEARCH_REMOVE:
{
u_int tail_offset;
- printf("Removing MK_MSG scb\n");
+ printk("Removing MK_MSG scb\n");
/*
* Reset our tail to the tail of the
@@ -8390,7 +8386,7 @@ ahd_search_qinfifo(struct ahd_softc *ahd, int target, char channel,
break;
}
case SEARCH_PRINT:
- printf(" 0x%x", SCB_GET_TAG(scb));
+ printk(" 0x%x", SCB_GET_TAG(scb));
/* FALLTHROUGH */
case SEARCH_COUNT:
break;
@@ -8407,7 +8403,7 @@ ahd_search_qinfifo(struct ahd_softc *ahd, int target, char channel,
* queue with a pending MK_MESSAGE scb, we
* must queue the MK_MESSAGE scb.
*/
- printf("Queueing mk_msg_scb\n");
+ printk("Queueing mk_msg_scb\n");
tid_head = ahd_inw(ahd, MK_MESSAGE_SCB);
seq_flags2 &= ~PENDING_MK_MESSAGE;
ahd_outb(ahd, SEQ_FLAGS2, seq_flags2);
@@ -8418,7 +8414,7 @@ ahd_search_qinfifo(struct ahd_softc *ahd, int target, char channel,
if (!SCBID_IS_NULL(tid_head))
tid_prev = tid_head;
if (action == SEARCH_PRINT)
- printf(")\n");
+ printk(")\n");
}
/* Restore saved state. */
@@ -8446,7 +8442,7 @@ ahd_search_scb_list(struct ahd_softc *ahd, int target, char channel,
*list_tail = SCB_LIST_NULL;
for (scbid = next; !SCBID_IS_NULL(scbid); scbid = next) {
if (scbid >= ahd->scb_data.numscbs) {
- printf("%s:SCB List inconsistency. "
+ printk("%s:SCB List inconsistency. "
"SCB == 0x%x, yet numscbs == 0x%x.",
ahd_name(ahd), scbid, ahd->scb_data.numscbs);
ahd_dump_card_state(ahd);
@@ -8454,7 +8450,7 @@ ahd_search_scb_list(struct ahd_softc *ahd, int target, char channel,
}
scb = ahd_lookup_scb(ahd, scbid);
if (scb == NULL) {
- printf("%s: SCB = %d Not Active!\n",
+ printk("%s: SCB = %d Not Active!\n",
ahd_name(ahd), scbid);
panic("Waiting List traversal\n");
}
@@ -8470,7 +8466,7 @@ ahd_search_scb_list(struct ahd_softc *ahd, int target, char channel,
switch (action) {
case SEARCH_COMPLETE:
if ((scb->flags & SCB_ACTIVE) == 0)
- printf("Inactive SCB in Waiting List\n");
+ printk("Inactive SCB in Waiting List\n");
ahd_done_with_status(ahd, scb, status);
/* FALLTHROUGH */
case SEARCH_REMOVE:
@@ -8480,7 +8476,7 @@ ahd_search_scb_list(struct ahd_softc *ahd, int target, char channel,
*list_head = next;
break;
case SEARCH_PRINT:
- printf("0x%x ", scbid);
+ printk("0x%x ", scbid);
case SEARCH_COUNT:
prev = scbid;
break;
@@ -8668,7 +8664,7 @@ ahd_abort_scbs(struct ahd_softc *ahd, int target, char channel,
if (ahd_get_transaction_status(scbp) != CAM_REQ_CMP)
ahd_freeze_scb(scbp);
if ((scbp->flags & SCB_ACTIVE) == 0)
- printf("Inactive SCB on pending list\n");
+ printk("Inactive SCB on pending list\n");
ahd_done(ahd, scbp);
found++;
}
@@ -8725,7 +8721,7 @@ ahd_reset_channel(struct ahd_softc *ahd, char channel, int initiate_reset)
* Check if the last bus reset is cleared
*/
if (ahd->flags & AHD_BUS_RESET_ACTIVE) {
- printf("%s: bus reset still active\n",
+ printk("%s: bus reset still active\n",
ahd_name(ahd));
return 0;
}
@@ -8900,7 +8896,7 @@ ahd_stat_timer(void *arg)
ahd_enable_coalescing(ahd, enint_coal);
#ifdef AHD_DEBUG
if ((ahd_debug & AHD_SHOW_INT_COALESCING) != 0)
- printf("%s: Interrupt coalescing "
+ printk("%s: Interrupt coalescing "
"now %sabled. Cmds %d\n",
ahd_name(ahd),
(enint_coal & ENINT_COALESCE) ? "en" : "dis",
@@ -8975,9 +8971,9 @@ ahd_handle_scsi_status(struct ahd_softc *ahd, struct scb *scb)
#ifdef AHD_DEBUG
if ((ahd_debug & AHD_SHOW_SENSE) != 0) {
ahd_print_path(ahd, scb);
- printf("SCB 0x%x Received PKT Status of 0x%x\n",
+ printk("SCB 0x%x Received PKT Status of 0x%x\n",
SCB_GET_TAG(scb), siu->status);
- printf("\tflags = 0x%x, sense len = 0x%x, "
+ printk("\tflags = 0x%x, sense len = 0x%x, "
"pktfail = 0x%x\n",
siu->flags, scsi_4btoul(siu->sense_length),
scsi_4btoul(siu->pkt_failures_length));
@@ -8986,27 +8982,27 @@ ahd_handle_scsi_status(struct ahd_softc *ahd, struct scb *scb)
if ((siu->flags & SIU_RSPVALID) != 0) {
ahd_print_path(ahd, scb);
if (scsi_4btoul(siu->pkt_failures_length) < 4) {
- printf("Unable to parse pkt_failures\n");
+ printk("Unable to parse pkt_failures\n");
} else {
switch (SIU_PKTFAIL_CODE(siu)) {
case SIU_PFC_NONE:
- printf("No packet failure found\n");
+ printk("No packet failure found\n");
break;
case SIU_PFC_CIU_FIELDS_INVALID:
- printf("Invalid Command IU Field\n");
+ printk("Invalid Command IU Field\n");
break;
case SIU_PFC_TMF_NOT_SUPPORTED:
- printf("TMF not supportd\n");
+ printk("TMF not supportd\n");
break;
case SIU_PFC_TMF_FAILED:
- printf("TMF failed\n");
+ printk("TMF failed\n");
break;
case SIU_PFC_INVALID_TYPE_CODE:
- printf("Invalid L_Q Type code\n");
+ printk("Invalid L_Q Type code\n");
break;
case SIU_PFC_ILLEGAL_REQUEST:
- printf("Illegal request\n");
+ printk("Illegal request\n");
default:
break;
}
@@ -9019,7 +9015,7 @@ ahd_handle_scsi_status(struct ahd_softc *ahd, struct scb *scb)
scb->flags |= SCB_PKT_SENSE;
#ifdef AHD_DEBUG
if ((ahd_debug & AHD_SHOW_SENSE) != 0)
- printf("Sense data available\n");
+ printk("Sense data available\n");
#endif
}
ahd_done(ahd, scb);
@@ -9037,7 +9033,7 @@ ahd_handle_scsi_status(struct ahd_softc *ahd, struct scb *scb)
#ifdef AHD_DEBUG
if (ahd_debug & AHD_SHOW_SENSE) {
ahd_print_path(ahd, scb);
- printf("SCB %d: requests Check Status\n",
+ printk("SCB %d: requests Check Status\n",
SCB_GET_TAG(scb));
}
#endif
@@ -9065,7 +9061,7 @@ ahd_handle_scsi_status(struct ahd_softc *ahd, struct scb *scb)
#ifdef AHD_DEBUG
if (ahd_debug & AHD_SHOW_SENSE) {
ahd_print_path(ahd, scb);
- printf("Sending Sense\n");
+ printk("Sending Sense\n");
}
#endif
scb->sg_count = 0;
@@ -9117,7 +9113,7 @@ ahd_handle_scsi_status(struct ahd_softc *ahd, struct scb *scb)
break;
}
case SCSI_STATUS_OK:
- printf("%s: Interrupted for staus of 0???\n",
+ printk("%s: Interrupted for staus of 0???\n",
ahd_name(ahd));
/* FALLTHROUGH */
default:
@@ -9192,7 +9188,7 @@ ahd_calc_residual(struct ahd_softc *ahd, struct scb *scb)
return;
} else if ((resid_sgptr & SG_OVERRUN_RESID) != 0) {
ahd_print_path(ahd, scb);
- printf("data overrun detected Tag == 0x%x.\n",
+ printk("data overrun detected Tag == 0x%x.\n",
SCB_GET_TAG(scb));
ahd_freeze_devq(ahd, scb);
ahd_set_transaction_status(scb, CAM_DATA_RUN_ERR);
@@ -9232,7 +9228,7 @@ ahd_calc_residual(struct ahd_softc *ahd, struct scb *scb)
#ifdef AHD_DEBUG
if ((ahd_debug & AHD_SHOW_MISC) != 0) {
ahd_print_path(ahd, scb);
- printf("Handled %sResidual of %d bytes\n",
+ printk("Handled %sResidual of %d bytes\n",
(scb->flags & SCB_SENSE) ? "Sense " : "", resid);
}
#endif
@@ -9272,7 +9268,7 @@ ahd_queue_lstate_event(struct ahd_softc *ahd, struct ahd_tmode_lstate *lstate,
if (pending == AHD_TMODE_EVENT_BUFFER_SIZE) {
xpt_print_path(lstate->path);
- printf("immediate event %x:%x lost\n",
+ printk("immediate event %x:%x lost\n",
lstate->event_buffer[lstate->event_r_idx].event_type,
lstate->event_buffer[lstate->event_r_idx].event_arg);
lstate->event_r_idx++;
@@ -9344,7 +9340,7 @@ ahd_dumpseq(struct ahd_softc* ahd)
uint8_t ins_bytes[4];
ahd_insb(ahd, SEQRAM, ins_bytes, 4);
- printf("0x%08x\n", ins_bytes[0] << 24
+ printk("0x%08x\n", ins_bytes[0] << 24
| ins_bytes[1] << 16
| ins_bytes[2] << 8
| ins_bytes[3]);
@@ -9372,7 +9368,7 @@ ahd_loadseq(struct ahd_softc *ahd)
uint8_t download_consts[DOWNLOAD_CONST_COUNT];
if (bootverbose)
- printf("%s: Downloading Sequencer Program...",
+ printk("%s: Downloading Sequencer Program...",
ahd_name(ahd));
#if DOWNLOAD_CONST_COUNT != 8
@@ -9498,7 +9494,7 @@ ahd_loadseq(struct ahd_softc *ahd)
if (cs_count != 0) {
cs_count *= sizeof(struct cs);
- ahd->critical_sections = malloc(cs_count, M_DEVBUF, M_NOWAIT);
+ ahd->critical_sections = kmalloc(cs_count, GFP_ATOMIC);
if (ahd->critical_sections == NULL)
panic("ahd_loadseq: Could not malloc");
memcpy(ahd->critical_sections, cs_table, cs_count);
@@ -9506,8 +9502,8 @@ ahd_loadseq(struct ahd_softc *ahd)
ahd_outb(ahd, SEQCTL0, PERRORDIS|FAILDIS|FASTMODE);
if (bootverbose) {
- printf(" %d instructions downloaded\n", downloaded);
- printf("%s: Features 0x%x, Bugs 0x%x, Flags 0x%x\n",
+ printk(" %d instructions downloaded\n", downloaded);
+ printk("%s: Features 0x%x, Bugs 0x%x, Flags 0x%x\n",
ahd_name(ahd), ahd->features, ahd->bugs, ahd->flags);
}
}
@@ -9690,12 +9686,12 @@ ahd_print_register(const ahd_reg_parse_entry_t *table, u_int num_entries,
u_int printed_mask;
if (cur_column != NULL && *cur_column >= wrap_point) {
- printf("\n");
+ printk("\n");
*cur_column = 0;
}
- printed = printf("%s[0x%x]", name, value);
+ printed = printk("%s[0x%x]", name, value);
if (table == NULL) {
- printed += printf(" ");
+ printed += printk(" ");
*cur_column += printed;
return (printed);
}
@@ -9710,7 +9706,7 @@ ahd_print_register(const ahd_reg_parse_entry_t *table, u_int num_entries,
== table[entry].mask))
continue;
- printed += printf("%s%s",
+ printed += printk("%s%s",
printed_mask == 0 ? ":(" : "|",
table[entry].name);
printed_mask |= table[entry].mask;
@@ -9721,9 +9717,9 @@ ahd_print_register(const ahd_reg_parse_entry_t *table, u_int num_entries,
break;
}
if (printed_mask != 0)
- printed += printf(") ");
+ printed += printk(") ");
else
- printed += printf(" ");
+ printed += printk(" ");
if (cur_column != NULL)
*cur_column += printed;
return (printed);
@@ -9749,17 +9745,17 @@ ahd_dump_card_state(struct ahd_softc *ahd)
}
saved_modes = ahd_save_modes(ahd);
ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
- printf(">>>>>>>>>>>>>>>>>> Dump Card State Begins <<<<<<<<<<<<<<<<<\n"
+ printk(">>>>>>>>>>>>>>>>>> Dump Card State Begins <<<<<<<<<<<<<<<<<\n"
"%s: Dumping Card State at program address 0x%x Mode 0x%x\n",
ahd_name(ahd),
ahd_inw(ahd, CURADDR),
ahd_build_mode_state(ahd, ahd->saved_src_mode,
ahd->saved_dst_mode));
if (paused)
- printf("Card was paused\n");
+ printk("Card was paused\n");
if (ahd_check_cmdcmpltqueues(ahd))
- printf("Completions are pending\n");
+ printk("Completions are pending\n");
/*
* Mode independent registers.
@@ -9801,8 +9797,8 @@ ahd_dump_card_state(struct ahd_softc *ahd)
ahd_lqostat0_print(ahd_inb(ahd, LQOSTAT0), &cur_col, 50);
ahd_lqostat1_print(ahd_inb(ahd, LQOSTAT1), &cur_col, 50);
ahd_lqostat2_print(ahd_inb(ahd, LQOSTAT2), &cur_col, 50);
- printf("\n");
- printf("\nSCB Count = %d CMDS_PENDING = %d LASTSCB 0x%x "
+ printk("\n");
+ printk("\nSCB Count = %d CMDS_PENDING = %d LASTSCB 0x%x "
"CURRSCB 0x%x NEXTSCB 0x%x\n",
ahd->scb_data.numscbs, ahd_inw(ahd, CMDS_PENDING),
ahd_inw(ahd, LASTSCB), ahd_inw(ahd, CURRSCB),
@@ -9813,12 +9809,12 @@ ahd_dump_card_state(struct ahd_softc *ahd)
CAM_LUN_WILDCARD, SCB_LIST_NULL,
ROLE_UNKNOWN, /*status*/0, SEARCH_PRINT);
saved_scb_index = ahd_get_scbptr(ahd);
- printf("Pending list:");
+ printk("Pending list:");
i = 0;
LIST_FOREACH(scb, &ahd->pending_scbs, pending_links) {
if (i++ > AHD_SCB_MAX)
break;
- cur_col = printf("\n%3d FIFO_USE[0x%x] ", SCB_GET_TAG(scb),
+ cur_col = printk("\n%3d FIFO_USE[0x%x] ", SCB_GET_TAG(scb),
ahd_inb_scbram(ahd, SCB_FIFO_USE_COUNT));
ahd_set_scbptr(ahd, SCB_GET_TAG(scb));
ahd_scb_control_print(ahd_inb_scbram(ahd, SCB_CONTROL),
@@ -9826,16 +9822,16 @@ ahd_dump_card_state(struct ahd_softc *ahd)
ahd_scb_scsiid_print(ahd_inb_scbram(ahd, SCB_SCSIID),
&cur_col, 60);
}
- printf("\nTotal %d\n", i);
+ printk("\nTotal %d\n", i);
- printf("Kernel Free SCB list: ");
+ printk("Kernel Free SCB list: ");
i = 0;
TAILQ_FOREACH(scb, &ahd->scb_data.free_scbs, links.tqe) {
struct scb *list_scb;
list_scb = scb;
do {
- printf("%d ", SCB_GET_TAG(list_scb));
+ printk("%d ", SCB_GET_TAG(list_scb));
list_scb = LIST_NEXT(list_scb, collision_links);
} while (list_scb && i++ < AHD_SCB_MAX);
}
@@ -9843,49 +9839,49 @@ ahd_dump_card_state(struct ahd_softc *ahd)
LIST_FOREACH(scb, &ahd->scb_data.any_dev_free_scb_list, links.le) {
if (i++ > AHD_SCB_MAX)
break;
- printf("%d ", SCB_GET_TAG(scb));
+ printk("%d ", SCB_GET_TAG(scb));
}
- printf("\n");
+ printk("\n");
- printf("Sequencer Complete DMA-inprog list: ");
+ printk("Sequencer Complete DMA-inprog list: ");
scb_index = ahd_inw(ahd, COMPLETE_SCB_DMAINPROG_HEAD);
i = 0;
while (!SCBID_IS_NULL(scb_index) && i++ < AHD_SCB_MAX) {
ahd_set_scbptr(ahd, scb_index);
- printf("%d ", scb_index);
+ printk("%d ", scb_index);
scb_index = ahd_inw_scbram(ahd, SCB_NEXT_COMPLETE);
}
- printf("\n");
+ printk("\n");
- printf("Sequencer Complete list: ");
+ printk("Sequencer Complete list: ");
scb_index = ahd_inw(ahd, COMPLETE_SCB_HEAD);
i = 0;
while (!SCBID_IS_NULL(scb_index) && i++ < AHD_SCB_MAX) {
ahd_set_scbptr(ahd, scb_index);
- printf("%d ", scb_index);
+ printk("%d ", scb_index);
scb_index = ahd_inw_scbram(ahd, SCB_NEXT_COMPLETE);
}
- printf("\n");
+ printk("\n");
- printf("Sequencer DMA-Up and Complete list: ");
+ printk("Sequencer DMA-Up and Complete list: ");
scb_index = ahd_inw(ahd, COMPLETE_DMA_SCB_HEAD);
i = 0;
while (!SCBID_IS_NULL(scb_index) && i++ < AHD_SCB_MAX) {
ahd_set_scbptr(ahd, scb_index);
- printf("%d ", scb_index);
+ printk("%d ", scb_index);
scb_index = ahd_inw_scbram(ahd, SCB_NEXT_COMPLETE);
}
- printf("\n");
- printf("Sequencer On QFreeze and Complete list: ");
+ printk("\n");
+ printk("Sequencer On QFreeze and Complete list: ");
scb_index = ahd_inw(ahd, COMPLETE_ON_QFREEZE_HEAD);
i = 0;
while (!SCBID_IS_NULL(scb_index) && i++ < AHD_SCB_MAX) {
ahd_set_scbptr(ahd, scb_index);
- printf("%d ", scb_index);
+ printk("%d ", scb_index);
scb_index = ahd_inw_scbram(ahd, SCB_NEXT_COMPLETE);
}
- printf("\n");
+ printk("\n");
ahd_set_scbptr(ahd, saved_scb_index);
dffstat = ahd_inb(ahd, DFFSTAT);
for (i = 0; i < 2; i++) {
@@ -9896,7 +9892,7 @@ ahd_dump_card_state(struct ahd_softc *ahd)
ahd_set_modes(ahd, AHD_MODE_DFF0 + i, AHD_MODE_DFF0 + i);
fifo_scbptr = ahd_get_scbptr(ahd);
- printf("\n\n%s: FIFO%d %s, LONGJMP == 0x%x, SCB 0x%x\n",
+ printk("\n\n%s: FIFO%d %s, LONGJMP == 0x%x, SCB 0x%x\n",
ahd_name(ahd), i,
(dffstat & (FIFO0FREE << i)) ? "Free" : "Active",
ahd_inw(ahd, LONGJMP_ADDR), fifo_scbptr);
@@ -9912,20 +9908,20 @@ ahd_dump_card_state(struct ahd_softc *ahd)
ahd_soffcnt_print(ahd_inb(ahd, SOFFCNT), &cur_col, 50);
ahd_mdffstat_print(ahd_inb(ahd, MDFFSTAT), &cur_col, 50);
if (cur_col > 50) {
- printf("\n");
+ printk("\n");
cur_col = 0;
}
- cur_col += printf("SHADDR = 0x%x%x, SHCNT = 0x%x ",
+ cur_col += printk("SHADDR = 0x%x%x, SHCNT = 0x%x ",
ahd_inl(ahd, SHADDR+4),
ahd_inl(ahd, SHADDR),
(ahd_inb(ahd, SHCNT)
| (ahd_inb(ahd, SHCNT + 1) << 8)
| (ahd_inb(ahd, SHCNT + 2) << 16)));
if (cur_col > 50) {
- printf("\n");
+ printk("\n");
cur_col = 0;
}
- cur_col += printf("HADDR = 0x%x%x, HCNT = 0x%x ",
+ cur_col += printk("HADDR = 0x%x%x, HCNT = 0x%x ",
ahd_inl(ahd, HADDR+4),
ahd_inl(ahd, HADDR),
(ahd_inb(ahd, HCNT)
@@ -9940,52 +9936,52 @@ ahd_dump_card_state(struct ahd_softc *ahd)
}
#endif
}
- printf("\nLQIN: ");
+ printk("\nLQIN: ");
for (i = 0; i < 20; i++)
- printf("0x%x ", ahd_inb(ahd, LQIN + i));
- printf("\n");
+ printk("0x%x ", ahd_inb(ahd, LQIN + i));
+ printk("\n");
ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
- printf("%s: LQISTATE = 0x%x, LQOSTATE = 0x%x, OPTIONMODE = 0x%x\n",
+ printk("%s: LQISTATE = 0x%x, LQOSTATE = 0x%x, OPTIONMODE = 0x%x\n",
ahd_name(ahd), ahd_inb(ahd, LQISTATE), ahd_inb(ahd, LQOSTATE),
ahd_inb(ahd, OPTIONMODE));
- printf("%s: OS_SPACE_CNT = 0x%x MAXCMDCNT = 0x%x\n",
+ printk("%s: OS_SPACE_CNT = 0x%x MAXCMDCNT = 0x%x\n",
ahd_name(ahd), ahd_inb(ahd, OS_SPACE_CNT),
ahd_inb(ahd, MAXCMDCNT));
- printf("%s: SAVED_SCSIID = 0x%x SAVED_LUN = 0x%x\n",
+ printk("%s: SAVED_SCSIID = 0x%x SAVED_LUN = 0x%x\n",
ahd_name(ahd), ahd_inb(ahd, SAVED_SCSIID),
ahd_inb(ahd, SAVED_LUN));
ahd_simode0_print(ahd_inb(ahd, SIMODE0), &cur_col, 50);
- printf("\n");
+ printk("\n");
ahd_set_modes(ahd, AHD_MODE_CCHAN, AHD_MODE_CCHAN);
cur_col = 0;
ahd_ccscbctl_print(ahd_inb(ahd, CCSCBCTL), &cur_col, 50);
- printf("\n");
+ printk("\n");
ahd_set_modes(ahd, ahd->saved_src_mode, ahd->saved_dst_mode);
- printf("%s: REG0 == 0x%x, SINDEX = 0x%x, DINDEX = 0x%x\n",
+ printk("%s: REG0 == 0x%x, SINDEX = 0x%x, DINDEX = 0x%x\n",
ahd_name(ahd), ahd_inw(ahd, REG0), ahd_inw(ahd, SINDEX),
ahd_inw(ahd, DINDEX));
- printf("%s: SCBPTR == 0x%x, SCB_NEXT == 0x%x, SCB_NEXT2 == 0x%x\n",
+ printk("%s: SCBPTR == 0x%x, SCB_NEXT == 0x%x, SCB_NEXT2 == 0x%x\n",
ahd_name(ahd), ahd_get_scbptr(ahd),
ahd_inw_scbram(ahd, SCB_NEXT),
ahd_inw_scbram(ahd, SCB_NEXT2));
- printf("CDB %x %x %x %x %x %x\n",
+ printk("CDB %x %x %x %x %x %x\n",
ahd_inb_scbram(ahd, SCB_CDB_STORE),
ahd_inb_scbram(ahd, SCB_CDB_STORE+1),
ahd_inb_scbram(ahd, SCB_CDB_STORE+2),
ahd_inb_scbram(ahd, SCB_CDB_STORE+3),
ahd_inb_scbram(ahd, SCB_CDB_STORE+4),
ahd_inb_scbram(ahd, SCB_CDB_STORE+5));
- printf("STACK:");
+ printk("STACK:");
for (i = 0; i < ahd->stack_size; i++) {
ahd->saved_stack[i] =
ahd_inb(ahd, STACK)|(ahd_inb(ahd, STACK) << 8);
- printf(" 0x%x", ahd->saved_stack[i]);
+ printk(" 0x%x", ahd->saved_stack[i]);
}
for (i = ahd->stack_size-1; i >= 0; i--) {
ahd_outb(ahd, STACK, ahd->saved_stack[i] & 0xFF);
ahd_outb(ahd, STACK, (ahd->saved_stack[i] >> 8) & 0xFF);
}
- printf("\n<<<<<<<<<<<<<<<<< Dump Card State Ends >>>>>>>>>>>>>>>>>>\n");
+ printk("\n<<<<<<<<<<<<<<<<< Dump Card State Ends >>>>>>>>>>>>>>>>>>\n");
ahd_restore_modes(ahd, saved_modes);
if (paused == 0)
ahd_unpause(ahd);
@@ -10004,8 +10000,8 @@ ahd_dump_scbs(struct ahd_softc *ahd)
saved_scb_index = ahd_get_scbptr(ahd);
for (i = 0; i < AHD_SCB_MAX; i++) {
ahd_set_scbptr(ahd, i);
- printf("%3d", i);
- printf("(CTRL 0x%x ID 0x%x N 0x%x N2 0x%x SG 0x%x, RSG 0x%x)\n",
+ printk("%3d", i);
+ printk("(CTRL 0x%x ID 0x%x N 0x%x N2 0x%x SG 0x%x, RSG 0x%x)\n",
ahd_inb_scbram(ahd, SCB_CONTROL),
ahd_inb_scbram(ahd, SCB_SCSIID),
ahd_inw_scbram(ahd, SCB_NEXT),
@@ -10013,7 +10009,7 @@ ahd_dump_scbs(struct ahd_softc *ahd)
ahd_inl_scbram(ahd, SCB_SGPTR),
ahd_inl_scbram(ahd, SCB_RESIDUAL_SGPTR));
}
- printf("\n");
+ printk("\n");
ahd_set_scbptr(ahd, saved_scb_index);
ahd_restore_modes(ahd, saved_modes);
}
@@ -10383,7 +10379,7 @@ ahd_handle_en_lun(struct ahd_softc *ahd, struct cam_sim *sim, union ccb *ccb)
&& ccb->ccb_h.target_id != CAM_TARGET_WILDCARD) {
u_long s;
- printf("Configuring Target Mode\n");
+ printk("Configuring Target Mode\n");
ahd_lock(ahd, &s);
if (LIST_FIRST(&ahd->pending_scbs) != NULL) {
ccb->ccb_h.status = CAM_BUSY;
@@ -10412,7 +10408,7 @@ ahd_handle_en_lun(struct ahd_softc *ahd, struct cam_sim *sim, union ccb *ccb)
/* Are we already enabled?? */
if (lstate != NULL) {
xpt_print_path(ccb->ccb_h.path);
- printf("Lun already enabled\n");
+ printk("Lun already enabled\n");
ccb->ccb_h.status = CAM_LUN_ALRDY_ENA;
return;
}
@@ -10424,7 +10420,7 @@ ahd_handle_en_lun(struct ahd_softc *ahd, struct cam_sim *sim, union ccb *ccb)
* specific commands.
*/
ccb->ccb_h.status = CAM_REQ_INVALID;
- printf("Non-zero Group Codes\n");
+ printk("Non-zero Group Codes\n");
return;
}
@@ -10436,15 +10432,15 @@ ahd_handle_en_lun(struct ahd_softc *ahd, struct cam_sim *sim, union ccb *ccb)
tstate = ahd_alloc_tstate(ahd, target, channel);
if (tstate == NULL) {
xpt_print_path(ccb->ccb_h.path);
- printf("Couldn't allocate tstate\n");
+ printk("Couldn't allocate tstate\n");
ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
return;
}
}
- lstate = malloc(sizeof(*lstate), M_DEVBUF, M_NOWAIT);
+ lstate = kmalloc(sizeof(*lstate), GFP_ATOMIC);
if (lstate == NULL) {
xpt_print_path(ccb->ccb_h.path);
- printf("Couldn't allocate lstate\n");
+ printk("Couldn't allocate lstate\n");
ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
return;
}
@@ -10454,9 +10450,9 @@ ahd_handle_en_lun(struct ahd_softc *ahd, struct cam_sim *sim, union ccb *ccb)
xpt_path_target_id(ccb->ccb_h.path),
xpt_path_lun_id(ccb->ccb_h.path));
if (status != CAM_REQ_CMP) {
- free(lstate, M_DEVBUF);
+ kfree(lstate);
xpt_print_path(ccb->ccb_h.path);
- printf("Couldn't allocate path\n");
+ printk("Couldn't allocate path\n");
ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
return;
}
@@ -10524,7 +10520,7 @@ ahd_handle_en_lun(struct ahd_softc *ahd, struct cam_sim *sim, union ccb *ccb)
ahd_unlock(ahd, &s);
ccb->ccb_h.status = CAM_REQ_CMP;
xpt_print_path(ccb->ccb_h.path);
- printf("Lun now enabled for target mode\n");
+ printk("Lun now enabled for target mode\n");
} else {
struct scb *scb;
int i, empty;
@@ -10543,7 +10539,7 @@ ahd_handle_en_lun(struct ahd_softc *ahd, struct cam_sim *sim, union ccb *ccb)
ccbh = &scb->io_ctx->ccb_h;
if (ccbh->func_code == XPT_CONT_TARGET_IO
&& !xpt_path_comp(ccbh->path, ccb->ccb_h.path)){
- printf("CTIO pending\n");
+ printk("CTIO pending\n");
ccb->ccb_h.status = CAM_REQ_INVALID;
ahd_unlock(ahd, &s);
return;
@@ -10551,12 +10547,12 @@ ahd_handle_en_lun(struct ahd_softc *ahd, struct cam_sim *sim, union ccb *ccb)
}
if (SLIST_FIRST(&lstate->accept_tios) != NULL) {
- printf("ATIOs pending\n");
+ printk("ATIOs pending\n");
ccb->ccb_h.status = CAM_REQ_INVALID;
}
if (SLIST_FIRST(&lstate->immed_notifies) != NULL) {
- printf("INOTs pending\n");
+ printk("INOTs pending\n");
ccb->ccb_h.status = CAM_REQ_INVALID;
}
@@ -10566,9 +10562,9 @@ ahd_handle_en_lun(struct ahd_softc *ahd, struct cam_sim *sim, union ccb *ccb)
}
xpt_print_path(ccb->ccb_h.path);
- printf("Target mode disabled\n");
+ printk("Target mode disabled\n");
xpt_free_path(lstate->path);
- free(lstate, M_DEVBUF);
+ kfree(lstate);
ahd_pause(ahd);
/* Can we clean up the target too? */
@@ -10615,7 +10611,7 @@ ahd_handle_en_lun(struct ahd_softc *ahd, struct cam_sim *sim, union ccb *ccb)
ahd_outb(ahd, SCSISEQ1, scsiseq1);
if ((ahd->features & AHD_MULTIROLE) == 0) {
- printf("Configuring Initiator Mode\n");
+ printk("Configuring Initiator Mode\n");
ahd->flags &= ~AHD_TARGETROLE;
ahd->flags |= AHD_INITIATORROLE;
ahd_pause(ahd);
@@ -10749,7 +10745,7 @@ ahd_handle_target_cmd(struct ahd_softc *ahd, struct target_cmd *cmd)
ahd->flags &= ~AHD_TQINFIFO_BLOCKED;
#ifdef AHD_DEBUG
if ((ahd_debug & AHD_SHOW_TQIN) != 0)
- printf("Incoming command from %d for %d:%d%s\n",
+ printk("Incoming command from %d for %d:%d%s\n",
initiator, target, lun,
lstate == ahd->black_hole ? "(Black Holed)" : "");
#endif
@@ -10796,7 +10792,7 @@ ahd_handle_target_cmd(struct ahd_softc *ahd, struct target_cmd *cmd)
default:
/* Only copy the opcode. */
atio->cdb_len = 1;
- printf("Reserved or VU command code type encountered\n");
+ printk("Reserved or VU command code type encountered\n");
break;
}
@@ -10813,7 +10809,7 @@ ahd_handle_target_cmd(struct ahd_softc *ahd, struct target_cmd *cmd)
*/
#ifdef AHD_DEBUG
if ((ahd_debug & AHD_SHOW_TQIN) != 0)
- printf("Received Immediate Command %d:%d:%d - %p\n",
+ printk("Received Immediate Command %d:%d:%d - %p\n",
initiator, target, lun, ahd->pending_device);
#endif
ahd->pending_device = lstate;
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c
index 4c41332a354..88ad8482ef5 100644
--- a/drivers/scsi/aic7xxx/aic79xx_osm.c
+++ b/drivers/scsi/aic7xxx/aic79xx_osm.c
@@ -674,7 +674,7 @@ ahd_linux_slave_alloc(struct scsi_device *sdev)
struct ahd_linux_device *dev;
if (bootverbose)
- printf("%s: Slave Alloc %d\n", ahd_name(ahd), sdev->id);
+ printk("%s: Slave Alloc %d\n", ahd_name(ahd), sdev->id);
dev = scsi_transport_device_data(sdev);
memset(dev, 0, sizeof(*dev));
@@ -798,10 +798,10 @@ ahd_linux_dev_reset(struct scsi_cmnd *cmd)
scmd_printk(KERN_INFO, cmd,
"Attempting to queue a TARGET RESET message:");
- printf("CDB:");
+ printk("CDB:");
for (cdb_byte = 0; cdb_byte < cmd->cmd_len; cdb_byte++)
- printf(" 0x%x", cmd->cmnd[cdb_byte]);
- printf("\n");
+ printk(" 0x%x", cmd->cmnd[cdb_byte]);
+ printk("\n");
/*
* Determine if we currently own this command.
@@ -857,16 +857,16 @@ ahd_linux_dev_reset(struct scsi_cmnd *cmd)
ahd->platform_data->eh_done = &done;
ahd_unlock(ahd, &flags);
- printf("%s: Device reset code sleeping\n", ahd_name(ahd));
+ printk("%s: Device reset code sleeping\n", ahd_name(ahd));
if (!wait_for_completion_timeout(&done, 5 * HZ)) {
ahd_lock(ahd, &flags);
ahd->platform_data->eh_done = NULL;
ahd_unlock(ahd, &flags);
- printf("%s: Device reset timer expired (active %d)\n",
+ printk("%s: Device reset timer expired (active %d)\n",
ahd_name(ahd), dev->active);
retval = FAILED;
}
- printf("%s: Device reset returning 0x%x\n", ahd_name(ahd), retval);
+ printk("%s: Device reset returning 0x%x\n", ahd_name(ahd), retval);
return (retval);
}
@@ -884,7 +884,7 @@ ahd_linux_bus_reset(struct scsi_cmnd *cmd)
ahd = *(struct ahd_softc **)cmd->device->host->hostdata;
#ifdef AHD_DEBUG
if ((ahd_debug & AHD_SHOW_RECOVERY) != 0)
- printf("%s: Bus reset called for cmd %p\n",
+ printk("%s: Bus reset called for cmd %p\n",
ahd_name(ahd), cmd);
#endif
ahd_lock(ahd, &flags);
@@ -894,7 +894,7 @@ ahd_linux_bus_reset(struct scsi_cmnd *cmd)
ahd_unlock(ahd, &flags);
if (bootverbose)
- printf("%s: SCSI bus reset delivered. "
+ printk("%s: SCSI bus reset delivered. "
"%d SCBs aborted.\n", ahd_name(ahd), found);
return (SUCCESS);
@@ -935,7 +935,7 @@ ahd_dma_tag_create(struct ahd_softc *ahd, bus_dma_tag_t parent,
{
bus_dma_tag_t dmat;
- dmat = malloc(sizeof(*dmat), M_DEVBUF, M_NOWAIT);
+ dmat = kmalloc(sizeof(*dmat), GFP_ATOMIC);
if (dmat == NULL)
return (ENOMEM);
@@ -956,7 +956,7 @@ ahd_dma_tag_create(struct ahd_softc *ahd, bus_dma_tag_t parent,
void
ahd_dma_tag_destroy(struct ahd_softc *ahd, bus_dma_tag_t dmat)
{
- free(dmat, M_DEVBUF);
+ kfree(dmat);
}
int
@@ -1019,7 +1019,7 @@ ahd_linux_setup_iocell_info(u_long index, int instance, int targ, int32_t value)
iocell_info = (uint8_t*)&aic79xx_iocell_info[instance];
iocell_info[index] = value & 0xFFFF;
if (bootverbose)
- printf("iocell[%d:%ld] = %d\n", instance, index, value);
+ printk("iocell[%d:%ld] = %d\n", instance, index, value);
}
}
@@ -1029,7 +1029,7 @@ ahd_linux_setup_tag_info_global(char *p)
int tags, i, j;
tags = simple_strtoul(p + 1, NULL, 0) & 0xff;
- printf("Setting Global Tags= %d\n", tags);
+ printk("Setting Global Tags= %d\n", tags);
for (i = 0; i < ARRAY_SIZE(aic79xx_tag_info); i++) {
for (j = 0; j < AHD_NUM_TARGETS; j++) {
@@ -1047,7 +1047,7 @@ ahd_linux_setup_tag_info(u_long arg, int instance, int targ, int32_t value)
&& (targ < AHD_NUM_TARGETS)) {
aic79xx_tag_info[instance].tag_commands[targ] = value & 0x1FF;
if (bootverbose)
- printf("tag_info[%d:%d] = %d\n", instance, targ, value);
+ printk("tag_info[%d:%d] = %d\n", instance, targ, value);
}
}
@@ -1088,7 +1088,7 @@ ahd_parse_brace_option(char *opt_name, char *opt_arg, char *end, int depth,
if (targ == -1)
targ = 0;
} else {
- printf("Malformed Option %s\n",
+ printk("Malformed Option %s\n",
opt_name);
done = TRUE;
}
@@ -1246,7 +1246,7 @@ ahd_linux_register_host(struct ahd_softc *ahd, struct scsi_host_template *templa
ahd_set_unit(ahd, ahd_linux_unit++);
ahd_unlock(ahd, &s);
sprintf(buf, "scsi%d", host->host_no);
- new_name = malloc(strlen(buf) + 1, M_DEVBUF, M_NOWAIT);
+ new_name = kmalloc(strlen(buf) + 1, GFP_ATOMIC);
if (new_name != NULL) {
strcpy(new_name, buf);
ahd_set_name(ahd, new_name);
@@ -1322,7 +1322,7 @@ int
ahd_platform_alloc(struct ahd_softc *ahd, void *platform_arg)
{
ahd->platform_data =
- malloc(sizeof(struct ahd_platform_data), M_DEVBUF, M_NOWAIT);
+ kmalloc(sizeof(struct ahd_platform_data), GFP_ATOMIC);
if (ahd->platform_data == NULL)
return (ENOMEM);
memset(ahd->platform_data, 0, sizeof(struct ahd_platform_data));
@@ -1364,7 +1364,7 @@ ahd_platform_free(struct ahd_softc *ahd)
if (ahd->platform_data->host)
scsi_host_put(ahd->platform_data->host);
- free(ahd->platform_data, M_DEVBUF);
+ kfree(ahd->platform_data);
}
}
@@ -1502,7 +1502,7 @@ ahd_linux_user_tagdepth(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
if (ahd->unit >= ARRAY_SIZE(aic79xx_tag_info)) {
if (warned_user == 0) {
- printf(KERN_WARNING
+ printk(KERN_WARNING
"aic79xx: WARNING: Insufficient tag_info instances\n"
"aic79xx: for installed controllers. Using defaults\n"
"aic79xx: Please update the aic79xx_tag_info array in\n"
@@ -1544,7 +1544,7 @@ ahd_linux_device_queue_depth(struct scsi_device *sdev)
ahd_send_async(ahd, devinfo.channel, devinfo.target,
devinfo.lun, AC_TRANSFER_NEG);
ahd_print_devinfo(ahd, &devinfo);
- printf("Tagged Queuing enabled. Depth %d\n", tags);
+ printk("Tagged Queuing enabled. Depth %d\n", tags);
} else {
ahd_platform_set_tags(ahd, sdev, &devinfo, AHD_QUEUE_NONE);
ahd_send_async(ahd, devinfo.channel, devinfo.target,
@@ -1794,7 +1794,7 @@ ahd_done(struct ahd_softc *ahd, struct scb *scb)
struct ahd_linux_device *dev;
if ((scb->flags & SCB_ACTIVE) == 0) {
- printf("SCB %d done'd twice\n", SCB_GET_TAG(scb));
+ printk("SCB %d done'd twice\n", SCB_GET_TAG(scb));
ahd_dump_card_state(ahd);
panic("Stopping for safety");
}
@@ -1825,7 +1825,7 @@ ahd_done(struct ahd_softc *ahd, struct scb *scb)
#ifdef AHD_DEBUG
if ((ahd_debug & AHD_SHOW_MISC) != 0) {
ahd_print_path(ahd, scb);
- printf("Set CAM_UNCOR_PARITY\n");
+ printk("Set CAM_UNCOR_PARITY\n");
}
#endif
ahd_set_transaction_status(scb, CAM_UNCOR_PARITY);
@@ -1843,12 +1843,12 @@ ahd_done(struct ahd_softc *ahd, struct scb *scb)
u_int i;
ahd_print_path(ahd, scb);
- printf("CDB:");
+ printk("CDB:");
for (i = 0; i < scb->io_ctx->cmd_len; i++)
- printf(" 0x%x", scb->io_ctx->cmnd[i]);
- printf("\n");
+ printk(" 0x%x", scb->io_ctx->cmnd[i]);
+ printk("\n");
ahd_print_path(ahd, scb);
- printf("Saw underflow (%ld of %ld bytes). "
+ printk("Saw underflow (%ld of %ld bytes). "
"Treated as error\n",
ahd_get_residual(scb),
ahd_get_transfer_length(scb));
@@ -1881,7 +1881,7 @@ ahd_done(struct ahd_softc *ahd, struct scb *scb)
dev->commands_since_idle_or_otag = 0;
if ((scb->flags & SCB_RECOVERY_SCB) != 0) {
- printf("Recovery SCB completes\n");
+ printk("Recovery SCB completes\n");
if (ahd_get_transaction_status(scb) == CAM_BDR_SENT
|| ahd_get_transaction_status(scb) == CAM_REQ_ABORTED)
ahd_set_transaction_status(scb, CAM_CMD_TIMEOUT);
@@ -1963,14 +1963,14 @@ ahd_linux_handle_scsi_status(struct ahd_softc *ahd,
if (ahd_debug & AHD_SHOW_SENSE) {
int i;
- printf("Copied %d bytes of sense data at %d:",
+ printk("Copied %d bytes of sense data at %d:",
sense_size, sense_offset);
for (i = 0; i < sense_size; i++) {
if ((i & 0xF) == 0)
- printf("\n");
- printf("0x%x ", cmd->sense_buffer[i]);
+ printk("\n");
+ printk("0x%x ", cmd->sense_buffer[i]);
}
- printf("\n");
+ printk("\n");
}
#endif
}
@@ -1995,7 +1995,7 @@ ahd_linux_handle_scsi_status(struct ahd_softc *ahd,
#ifdef AHD_DEBUG
if ((ahd_debug & AHD_SHOW_QFULL) != 0) {
ahd_print_path(ahd, scb);
- printf("Dropping tag count to %d\n",
+ printk("Dropping tag count to %d\n",
dev->active);
}
#endif
@@ -2014,7 +2014,7 @@ ahd_linux_handle_scsi_status(struct ahd_softc *ahd,
== AHD_LOCK_TAGS_COUNT) {
dev->maxtags = dev->active;
ahd_print_path(ahd, scb);
- printf("Locking max tag count at %d\n",
+ printk("Locking max tag count at %d\n",
dev->active);
}
} else {
@@ -2138,7 +2138,7 @@ ahd_linux_queue_cmd_complete(struct ahd_softc *ahd, struct scsi_cmnd *cmd)
}
if (do_fallback) {
- printf("%s: device overrun (status %x) on %d:%d:%d\n",
+ printk("%s: device overrun (status %x) on %d:%d:%d\n",
ahd_name(ahd), status, cmd->device->channel,
cmd->device->id, cmd->device->lun);
}
@@ -2187,10 +2187,10 @@ ahd_linux_queue_abort_cmd(struct scsi_cmnd *cmd)
scmd_printk(KERN_INFO, cmd,
"Attempting to queue an ABORT message:");
- printf("CDB:");
+ printk("CDB:");
for (cdb_byte = 0; cdb_byte < cmd->cmd_len; cdb_byte++)
- printf(" 0x%x", cmd->cmnd[cdb_byte]);
- printf("\n");
+ printk(" 0x%x", cmd->cmnd[cdb_byte]);
+ printk("\n");
ahd_lock(ahd, &flags);
@@ -2249,7 +2249,7 @@ ahd_linux_queue_abort_cmd(struct scsi_cmnd *cmd)
goto no_cmd;
}
- printf("%s: At time of recovery, card was %spaused\n",
+ printk("%s: At time of recovery, card was %spaused\n",
ahd_name(ahd), was_paused ? "" : "not ");
ahd_dump_card_state(ahd);
@@ -2260,7 +2260,7 @@ ahd_linux_queue_abort_cmd(struct scsi_cmnd *cmd)
pending_scb->hscb->tag,
ROLE_INITIATOR, CAM_REQ_ABORTED,
SEARCH_COMPLETE) > 0) {
- printf("%s:%d:%d:%d: Cmd aborted from QINFIFO\n",
+ printk("%s:%d:%d:%d: Cmd aborted from QINFIFO\n",
ahd_name(ahd), cmd->device->channel,
cmd->device->id, cmd->device->lun);
retval = SUCCESS;
@@ -2355,7 +2355,7 @@ ahd_linux_queue_abort_cmd(struct scsi_cmnd *cmd)
ahd_qinfifo_requeue_tail(ahd, pending_scb);
ahd_set_scbptr(ahd, saved_scbptr);
ahd_print_path(ahd, pending_scb);
- printf("Device is disconnected, re-queuing SCB\n");
+ printk("Device is disconnected, re-queuing SCB\n");
wait = TRUE;
} else {
scmd_printk(KERN_INFO, cmd, "Unable to deliver message\n");
@@ -2380,21 +2380,21 @@ done:
ahd->platform_data->eh_done = &done;
ahd_unlock(ahd, &flags);
- printf("%s: Recovery code sleeping\n", ahd_name(ahd));
+ printk("%s: Recovery code sleeping\n", ahd_name(ahd));
if (!wait_for_completion_timeout(&done, 5 * HZ)) {
ahd_lock(ahd, &flags);
ahd->platform_data->eh_done = NULL;
ahd_unlock(ahd, &flags);
- printf("%s: Timer Expired (active %d)\n",
+ printk("%s: Timer Expired (active %d)\n",
ahd_name(ahd), dev->active);
retval = FAILED;
}
- printf("Recovery code awake\n");
+ printk("Recovery code awake\n");
} else
ahd_unlock(ahd, &flags);
if (retval != SUCCESS)
- printf("%s: Command abort returning 0x%x\n",
+ printk("%s: Command abort returning 0x%x\n",
ahd_name(ahd), retval);
return retval;
@@ -2431,7 +2431,7 @@ static void ahd_linux_set_period(struct scsi_target *starget, int period)
#ifdef AHD_DEBUG
if ((ahd_debug & AHD_SHOW_DV) != 0)
- printf("%s: set period to %d\n", ahd_name(ahd), period);
+ printk("%s: set period to %d\n", ahd_name(ahd), period);
#endif
if (offset == 0)
offset = MAX_OFFSET;
@@ -2484,7 +2484,7 @@ static void ahd_linux_set_offset(struct scsi_target *starget, int offset)
#ifdef AHD_DEBUG
if ((ahd_debug & AHD_SHOW_DV) != 0)
- printf("%s: set offset to %d\n", ahd_name(ahd), offset);
+ printk("%s: set offset to %d\n", ahd_name(ahd), offset);
#endif
ahd_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
@@ -2520,7 +2520,7 @@ static void ahd_linux_set_dt(struct scsi_target *starget, int dt)
#ifdef AHD_DEBUG
if ((ahd_debug & AHD_SHOW_DV) != 0)
- printf("%s: %s DT\n", ahd_name(ahd),
+ printk("%s: %s DT\n", ahd_name(ahd),
dt ? "enabling" : "disabling");
#endif
if (dt && spi_max_width(starget)) {
@@ -2562,7 +2562,7 @@ static void ahd_linux_set_qas(struct scsi_target *starget, int qas)
#ifdef AHD_DEBUG
if ((ahd_debug & AHD_SHOW_DV) != 0)
- printf("%s: %s QAS\n", ahd_name(ahd),
+ printk("%s: %s QAS\n", ahd_name(ahd),
qas ? "enabling" : "disabling");
#endif
@@ -2601,7 +2601,7 @@ static void ahd_linux_set_iu(struct scsi_target *starget, int iu)
#ifdef AHD_DEBUG
if ((ahd_debug & AHD_SHOW_DV) != 0)
- printf("%s: %s IU\n", ahd_name(ahd),
+ printk("%s: %s IU\n", ahd_name(ahd),
iu ? "enabling" : "disabling");
#endif
@@ -2641,7 +2641,7 @@ static void ahd_linux_set_rd_strm(struct scsi_target *starget, int rdstrm)
#ifdef AHD_DEBUG
if ((ahd_debug & AHD_SHOW_DV) != 0)
- printf("%s: %s Read Streaming\n", ahd_name(ahd),
+ printk("%s: %s Read Streaming\n", ahd_name(ahd),
rdstrm ? "enabling" : "disabling");
#endif
@@ -2677,7 +2677,7 @@ static void ahd_linux_set_wr_flow(struct scsi_target *starget, int wrflow)
#ifdef AHD_DEBUG
if ((ahd_debug & AHD_SHOW_DV) != 0)
- printf("%s: %s Write Flow Control\n", ahd_name(ahd),
+ printk("%s: %s Write Flow Control\n", ahd_name(ahd),
wrflow ? "enabling" : "disabling");
#endif
@@ -2714,14 +2714,14 @@ static void ahd_linux_set_rti(struct scsi_target *starget, int rti)
if ((ahd->features & AHD_RTI) == 0) {
#ifdef AHD_DEBUG
if ((ahd_debug & AHD_SHOW_DV) != 0)
- printf("%s: RTI not available\n", ahd_name(ahd));
+ printk("%s: RTI not available\n", ahd_name(ahd));
#endif
return;
}
#ifdef AHD_DEBUG
if ((ahd_debug & AHD_SHOW_DV) != 0)
- printf("%s: %s RTI\n", ahd_name(ahd),
+ printk("%s: %s RTI\n", ahd_name(ahd),
rti ? "enabling" : "disabling");
#endif
@@ -2757,7 +2757,7 @@ static void ahd_linux_set_pcomp_en(struct scsi_target *starget, int pcomp)
#ifdef AHD_DEBUG
if ((ahd_debug & AHD_SHOW_DV) != 0)
- printf("%s: %s Precompensation\n", ahd_name(ahd),
+ printk("%s: %s Precompensation\n", ahd_name(ahd),
pcomp ? "Enable" : "Disable");
#endif
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.h b/drivers/scsi/aic7xxx/aic79xx_osm.h
index 55c1fe07969..28e43498cdf 100644
--- a/drivers/scsi/aic7xxx/aic79xx_osm.h
+++ b/drivers/scsi/aic7xxx/aic79xx_osm.h
@@ -363,13 +363,6 @@ struct ahd_platform_data {
resource_size_t mem_busaddr; /* Mem Base Addr */
};
-/************************** OS Utility Wrappers *******************************/
-#define printf printk
-#define M_NOWAIT GFP_ATOMIC
-#define M_WAITOK 0
-#define malloc(size, type, flags) kmalloc(size, flags)
-#define free(ptr, type) kfree(ptr)
-
void ahd_delay(long);
/***************************** Low Level I/O **********************************/
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm_pci.c b/drivers/scsi/aic7xxx/aic79xx_osm_pci.c
index 8f686122d54..3c85873b14b 100644
--- a/drivers/scsi/aic7xxx/aic79xx_osm_pci.c
+++ b/drivers/scsi/aic7xxx/aic79xx_osm_pci.c
@@ -178,7 +178,7 @@ ahd_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
ahd_get_pci_bus(pci),
ahd_get_pci_slot(pci),
ahd_get_pci_function(pci));
- name = malloc(strlen(buf) + 1, M_DEVBUF, M_NOWAIT);
+ name = kmalloc(strlen(buf) + 1, GFP_ATOMIC);
if (name == NULL)
return (-ENOMEM);
strcpy(name, buf);
@@ -333,7 +333,7 @@ ahd_pci_map_registers(struct ahd_softc *ahd)
if (ahd_pci_test_register_access(ahd) != 0) {
- printf("aic79xx: PCI Device %d:%d:%d "
+ printk("aic79xx: PCI Device %d:%d:%d "
"failed memory mapped test. Using PIO.\n",
ahd_get_pci_bus(ahd->dev_softc),
ahd_get_pci_slot(ahd->dev_softc),
@@ -346,7 +346,7 @@ ahd_pci_map_registers(struct ahd_softc *ahd)
} else
command |= PCIM_CMD_MEMEN;
} else if (bootverbose) {
- printf("aic79xx: PCI%d:%d:%d MEM region 0x%llx "
+ printk("aic79xx: PCI%d:%d:%d MEM region 0x%llx "
"unavailable. Cannot memory map device.\n",
ahd_get_pci_bus(ahd->dev_softc),
ahd_get_pci_slot(ahd->dev_softc),
@@ -365,7 +365,7 @@ ahd_pci_map_registers(struct ahd_softc *ahd)
ahd->bshs[1].ioport = (u_long)base2;
command |= PCIM_CMD_PORTEN;
} else {
- printf("aic79xx: PCI%d:%d:%d IO regions 0x%llx and "
+ printk("aic79xx: PCI%d:%d:%d IO regions 0x%llx and "
"0x%llx unavailable. Cannot map device.\n",
ahd_get_pci_bus(ahd->dev_softc),
ahd_get_pci_slot(ahd->dev_softc),
diff --git a/drivers/scsi/aic7xxx/aic79xx_pci.c b/drivers/scsi/aic7xxx/aic79xx_pci.c
index 90a04a37b4f..14b5f8d0e7f 100644
--- a/drivers/scsi/aic7xxx/aic79xx_pci.c
+++ b/drivers/scsi/aic7xxx/aic79xx_pci.c
@@ -338,7 +338,7 @@ ahd_pci_config(struct ahd_softc *ahd, const struct ahd_pci_identity *entry)
*/
if ((ahd->flags & (AHD_39BIT_ADDRESSING|AHD_64BIT_ADDRESSING)) != 0) {
if (bootverbose)
- printf("%s: Enabling 39Bit Addressing\n",
+ printk("%s: Enabling 39Bit Addressing\n",
ahd_name(ahd));
devconfig = ahd_pci_read_config(ahd->dev_softc,
DEVCONFIG, /*bytes*/4);
@@ -528,7 +528,7 @@ ahd_check_extport(struct ahd_softc *ahd)
* Fetch VPD for this function and parse it.
*/
if (bootverbose)
- printf("%s: Reading VPD from SEEPROM...",
+ printk("%s: Reading VPD from SEEPROM...",
ahd_name(ahd));
/* Address is always in units of 16bit words */
@@ -541,12 +541,12 @@ ahd_check_extport(struct ahd_softc *ahd)
if (error == 0)
error = ahd_parse_vpddata(ahd, &vpd);
if (bootverbose)
- printf("%s: VPD parsing %s\n",
+ printk("%s: VPD parsing %s\n",
ahd_name(ahd),
error == 0 ? "successful" : "failed");
if (bootverbose)
- printf("%s: Reading SEEPROM...", ahd_name(ahd));
+ printk("%s: Reading SEEPROM...", ahd_name(ahd));
/* Address is always in units of 16bit words */
start_addr = (sizeof(*sc) / 2) * (ahd->channel - 'A');
@@ -556,16 +556,16 @@ ahd_check_extport(struct ahd_softc *ahd)
/*bytestream*/FALSE);
if (error != 0) {
- printf("Unable to read SEEPROM\n");
+ printk("Unable to read SEEPROM\n");
have_seeprom = 0;
} else {
have_seeprom = ahd_verify_cksum(sc);
if (bootverbose) {
if (have_seeprom == 0)
- printf ("checksum error\n");
+ printk ("checksum error\n");
else
- printf ("done.\n");
+ printk ("done.\n");
}
}
ahd_release_seeprom(ahd);
@@ -615,21 +615,21 @@ ahd_check_extport(struct ahd_softc *ahd)
uint16_t *sc_data;
int i;
- printf("%s: Seeprom Contents:", ahd_name(ahd));
+ printk("%s: Seeprom Contents:", ahd_name(ahd));
sc_data = (uint16_t *)sc;
for (i = 0; i < (sizeof(*sc)); i += 2)
- printf("\n\t0x%.4x", sc_data[i]);
- printf("\n");
+ printk("\n\t0x%.4x", sc_data[i]);
+ printk("\n");
}
#endif
if (!have_seeprom) {
if (bootverbose)
- printf("%s: No SEEPROM available.\n", ahd_name(ahd));
+ printk("%s: No SEEPROM available.\n", ahd_name(ahd));
ahd->flags |= AHD_USEDEFAULTS;
error = ahd_default_config(ahd);
adapter_control = CFAUTOTERM|CFSEAUTOTERM;
- free(ahd->seep_config, M_DEVBUF);
+ kfree(ahd->seep_config);
ahd->seep_config = NULL;
} else {
error = ahd_parse_cfgdata(ahd, sc);
@@ -656,7 +656,7 @@ ahd_configure_termination(struct ahd_softc *ahd, u_int adapter_control)
if ((ahd->flags & AHD_STPWLEVEL_A) != 0)
devconfig |= STPWLEVEL;
if (bootverbose)
- printf("%s: STPWLEVEL is %s\n",
+ printk("%s: STPWLEVEL is %s\n",
ahd_name(ahd), (devconfig & STPWLEVEL) ? "on" : "off");
ahd_pci_write_config(ahd->dev_softc, DEVCONFIG, devconfig, /*bytes*/4);
@@ -671,7 +671,7 @@ ahd_configure_termination(struct ahd_softc *ahd, u_int adapter_control)
error = ahd_read_flexport(ahd, FLXADDR_TERMCTL, &termctl);
if ((adapter_control & CFAUTOTERM) == 0) {
if (bootverbose)
- printf("%s: Manual Primary Termination\n",
+ printk("%s: Manual Primary Termination\n",
ahd_name(ahd));
termctl &= ~(FLX_TERMCTL_ENPRILOW|FLX_TERMCTL_ENPRIHIGH);
if ((adapter_control & CFSTERM) != 0)
@@ -679,14 +679,14 @@ ahd_configure_termination(struct ahd_softc *ahd, u_int adapter_control)
if ((adapter_control & CFWSTERM) != 0)
termctl |= FLX_TERMCTL_ENPRIHIGH;
} else if (error != 0) {
- printf("%s: Primary Auto-Term Sensing failed! "
+ printk("%s: Primary Auto-Term Sensing failed! "
"Using Defaults.\n", ahd_name(ahd));
termctl = FLX_TERMCTL_ENPRILOW|FLX_TERMCTL_ENPRIHIGH;
}
if ((adapter_control & CFSEAUTOTERM) == 0) {
if (bootverbose)
- printf("%s: Manual Secondary Termination\n",
+ printk("%s: Manual Secondary Termination\n",
ahd_name(ahd));
termctl &= ~(FLX_TERMCTL_ENSECLOW|FLX_TERMCTL_ENSECHIGH);
if ((adapter_control & CFSELOWTERM) != 0)
@@ -694,7 +694,7 @@ ahd_configure_termination(struct ahd_softc *ahd, u_int adapter_control)
if ((adapter_control & CFSEHIGHTERM) != 0)
termctl |= FLX_TERMCTL_ENSECHIGH;
} else if (error != 0) {
- printf("%s: Secondary Auto-Term Sensing failed! "
+ printk("%s: Secondary Auto-Term Sensing failed! "
"Using Defaults.\n", ahd_name(ahd));
termctl |= FLX_TERMCTL_ENSECLOW|FLX_TERMCTL_ENSECHIGH;
}
@@ -714,22 +714,22 @@ ahd_configure_termination(struct ahd_softc *ahd, u_int adapter_control)
error = ahd_write_flexport(ahd, FLXADDR_TERMCTL, termctl);
if (error != 0) {
- printf("%s: Unable to set termination settings!\n",
+ printk("%s: Unable to set termination settings!\n",
ahd_name(ahd));
} else if (bootverbose) {
- printf("%s: Primary High byte termination %sabled\n",
+ printk("%s: Primary High byte termination %sabled\n",
ahd_name(ahd),
(termctl & FLX_TERMCTL_ENPRIHIGH) ? "En" : "Dis");
- printf("%s: Primary Low byte termination %sabled\n",
+ printk("%s: Primary Low byte termination %sabled\n",
ahd_name(ahd),
(termctl & FLX_TERMCTL_ENPRILOW) ? "En" : "Dis");
- printf("%s: Secondary High byte termination %sabled\n",
+ printk("%s: Secondary High byte termination %sabled\n",
ahd_name(ahd),
(termctl & FLX_TERMCTL_ENSECHIGH) ? "En" : "Dis");
- printf("%s: Secondary Low byte termination %sabled\n",
+ printk("%s: Secondary Low byte termination %sabled\n",
ahd_name(ahd),
(termctl & FLX_TERMCTL_ENSECLOW) ? "En" : "Dis");
}
@@ -805,7 +805,7 @@ ahd_pci_intr(struct ahd_softc *ahd)
if ((intstat & PCIINT) == 0)
return;
- printf("%s: PCI error Interrupt\n", ahd_name(ahd));
+ printk("%s: PCI error Interrupt\n", ahd_name(ahd));
saved_modes = ahd_save_modes(ahd);
ahd_dump_card_state(ahd);
ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
@@ -832,7 +832,7 @@ ahd_pci_intr(struct ahd_softc *ahd)
s = pci_status_strings[bit];
if (i == 7/*TARG*/ && bit == 3)
s = "%s: Signaled Target Abort\n";
- printf(s, ahd_name(ahd), pci_status_source[i]);
+ printk(s, ahd_name(ahd), pci_status_source[i]);
}
}
}
@@ -862,7 +862,7 @@ ahd_pci_split_intr(struct ahd_softc *ahd, u_int intstat)
*/
pcix_status = ahd_pci_read_config(ahd->dev_softc, PCIXR_STATUS,
/*bytes*/2);
- printf("%s: PCI Split Interrupt - PCI-X status = 0x%x\n",
+ printk("%s: PCI Split Interrupt - PCI-X status = 0x%x\n",
ahd_name(ahd), pcix_status);
saved_modes = ahd_save_modes(ahd);
for (i = 0; i < 4; i++) {
@@ -891,7 +891,7 @@ ahd_pci_split_intr(struct ahd_softc *ahd, u_int intstat)
static const char *s;
s = split_status_strings[bit];
- printf(s, ahd_name(ahd),
+ printk(s, ahd_name(ahd),
split_status_source[i]);
}
@@ -902,7 +902,7 @@ ahd_pci_split_intr(struct ahd_softc *ahd, u_int intstat)
static const char *s;
s = split_status_strings[bit];
- printf(s, ahd_name(ahd), "SG");
+ printk(s, ahd_name(ahd), "SG");
}
}
}
@@ -950,7 +950,7 @@ ahd_aic790X_setup(struct ahd_softc *ahd)
pci = ahd->dev_softc;
rev = ahd_pci_read_config(pci, PCIR_REVID, /*bytes*/1);
if (rev < ID_AIC7902_PCI_REV_A4) {
- printf("%s: Unable to attach to unsupported chip revision %d\n",
+ printk("%s: Unable to attach to unsupported chip revision %d\n",
ahd_name(ahd), rev);
ahd_pci_write_config(pci, PCIR_COMMAND, 0, /*bytes*/2);
return (ENXIO);
diff --git a/drivers/scsi/aic7xxx/aic79xx_proc.c b/drivers/scsi/aic7xxx/aic79xx_proc.c
index 014bed716e7..59c85d5a153 100644
--- a/drivers/scsi/aic7xxx/aic79xx_proc.c
+++ b/drivers/scsi/aic7xxx/aic79xx_proc.c
@@ -272,33 +272,32 @@ ahd_proc_write_seeprom(struct ahd_softc *ahd, char *buffer, int length)
saved_modes = ahd_save_modes(ahd);
ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
if (length != sizeof(struct seeprom_config)) {
- printf("ahd_proc_write_seeprom: incorrect buffer size\n");
+ printk("ahd_proc_write_seeprom: incorrect buffer size\n");
goto done;
}
have_seeprom = ahd_verify_cksum((struct seeprom_config*)buffer);
if (have_seeprom == 0) {
- printf("ahd_proc_write_seeprom: cksum verification failed\n");
+ printk("ahd_proc_write_seeprom: cksum verification failed\n");
goto done;
}
have_seeprom = ahd_acquire_seeprom(ahd);
if (!have_seeprom) {
- printf("ahd_proc_write_seeprom: No Serial EEPROM\n");
+ printk("ahd_proc_write_seeprom: No Serial EEPROM\n");
goto done;
} else {
u_int start_addr;
if (ahd->seep_config == NULL) {
- ahd->seep_config = malloc(sizeof(*ahd->seep_config),
- M_DEVBUF, M_NOWAIT);
+ ahd->seep_config = kmalloc(sizeof(*ahd->seep_config), GFP_ATOMIC);
if (ahd->seep_config == NULL) {
- printf("aic79xx: Unable to allocate serial "
+ printk("aic79xx: Unable to allocate serial "
"eeprom buffer. Write failing\n");
goto done;
}
}
- printf("aic79xx: Writing Serial EEPROM\n");
+ printk("aic79xx: Writing Serial EEPROM\n");
start_addr = 32 * (ahd->channel - 'A');
ahd_write_seeprom(ahd, (u_int16_t *)buffer, start_addr,
sizeof(struct seeprom_config)/2);
diff --git a/drivers/scsi/aic7xxx/aic7xxx_93cx6.c b/drivers/scsi/aic7xxx/aic7xxx_93cx6.c
index dd11999b77b..9e85a7ef9c8 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_93cx6.c
+++ b/drivers/scsi/aic7xxx/aic7xxx_93cx6.c
@@ -207,14 +207,14 @@ ahc_read_seeprom(struct seeprom_descriptor *sd, uint16_t *buf,
reset_seeprom(sd);
}
#ifdef AHC_DUMP_EEPROM
- printf("\nSerial EEPROM:\n\t");
+ printk("\nSerial EEPROM:\n\t");
for (k = 0; k < count; k = k + 1) {
if (((k % 8) == 0) && (k != 0)) {
- printf ("\n\t");
+ printk(KERN_CONT "\n\t");
}
- printf (" 0x%x", buf[k]);
+ printk(KERN_CONT " 0x%x", buf[k]);
}
- printf ("\n");
+ printk(KERN_CONT "\n");
#endif
return (1);
}
@@ -240,7 +240,7 @@ ahc_write_seeprom(struct seeprom_descriptor *sd, uint16_t *buf,
ewen = &seeprom_long_ewen;
ewds = &seeprom_long_ewds;
} else {
- printf("ahc_write_seeprom: unsupported seeprom type %d\n",
+ printk("ahc_write_seeprom: unsupported seeprom type %d\n",
sd->sd_chip);
return (0);
}
diff --git a/drivers/scsi/aic7xxx/aic7xxx_core.c b/drivers/scsi/aic7xxx/aic7xxx_core.c
index 45aa728a76b..3f5a542a779 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_core.c
+++ b/drivers/scsi/aic7xxx/aic7xxx_core.c
@@ -910,7 +910,7 @@ ahc_run_qoutfifo(struct ahc_softc *ahc)
scb = ahc_lookup_scb(ahc, scb_index);
if (scb == NULL) {
- printf("%s: WARNING no command for scb %d "
+ printk("%s: WARNING no command for scb %d "
"(cmdcmplt)\nQOUTPOS = %d\n",
ahc_name(ahc), scb_index,
(ahc->qoutfifonext - 1) & 0xFF);
@@ -964,7 +964,7 @@ ahc_handle_brkadrint(struct ahc_softc *ahc)
error = ahc_inb(ahc, ERROR);
for (i = 0; error != 1 && i < num_errors; i++)
error >>= 1;
- printf("%s: brkadrint, %s at seqaddr = 0x%x\n",
+ printk("%s: brkadrint, %s at seqaddr = 0x%x\n",
ahc_name(ahc), ahc_hard_errors[i].errmesg,
ahc_inb(ahc, SEQADDR0) |
(ahc_inb(ahc, SEQADDR1) << 8));
@@ -1021,7 +1021,7 @@ ahc_handle_seqint(struct ahc_softc *ahc, u_int intstat)
scb = ahc_lookup_scb(ahc, scb_index);
if (scb == NULL) {
ahc_print_devinfo(ahc, &devinfo);
- printf("ahc_intr - referenced scb "
+ printk("ahc_intr - referenced scb "
"not valid during seqint 0x%x scb(%d)\n",
intstat, scb_index);
ahc_dump_card_state(ahc);
@@ -1049,7 +1049,7 @@ ahc_handle_seqint(struct ahc_softc *ahc, u_int intstat)
ahc_set_scsi_status(scb, hscb->shared_data.status.scsi_status);
switch (hscb->shared_data.status.scsi_status) {
case SCSI_STATUS_OK:
- printf("%s: Interrupted for staus of 0???\n",
+ printk("%s: Interrupted for staus of 0???\n",
ahc_name(ahc));
break;
case SCSI_STATUS_CMD_TERMINATED:
@@ -1063,7 +1063,7 @@ ahc_handle_seqint(struct ahc_softc *ahc, u_int intstat)
#ifdef AHC_DEBUG
if (ahc_debug & AHC_SHOW_SENSE) {
ahc_print_path(ahc, scb);
- printf("SCB %d: requests Check Status\n",
+ printk("SCB %d: requests Check Status\n",
scb->hscb->tag);
}
#endif
@@ -1086,7 +1086,7 @@ ahc_handle_seqint(struct ahc_softc *ahc, u_int intstat)
#ifdef AHC_DEBUG
if (ahc_debug & AHC_SHOW_SENSE) {
ahc_print_path(ahc, scb);
- printf("Sending Sense\n");
+ printk("Sending Sense\n");
}
#endif
sg->addr = ahc_get_sense_bufaddr(ahc, scb);
@@ -1162,29 +1162,29 @@ ahc_handle_seqint(struct ahc_softc *ahc, u_int intstat)
ahc_outb(ahc, SCSISEQ,
ahc_inb(ahc, SCSISEQ) & (ENSELI|ENRSELI|ENAUTOATNP));
- printf("%s:%c:%d: no active SCB for reconnecting "
+ printk("%s:%c:%d: no active SCB for reconnecting "
"target - issuing BUS DEVICE RESET\n",
ahc_name(ahc), devinfo.channel, devinfo.target);
- printf("SAVED_SCSIID == 0x%x, SAVED_LUN == 0x%x, "
+ printk("SAVED_SCSIID == 0x%x, SAVED_LUN == 0x%x, "
"ARG_1 == 0x%x ACCUM = 0x%x\n",
ahc_inb(ahc, SAVED_SCSIID), ahc_inb(ahc, SAVED_LUN),
ahc_inb(ahc, ARG_1), ahc_inb(ahc, ACCUM));
- printf("SEQ_FLAGS == 0x%x, SCBPTR == 0x%x, BTT == 0x%x, "
+ printk("SEQ_FLAGS == 0x%x, SCBPTR == 0x%x, BTT == 0x%x, "
"SINDEX == 0x%x\n",
ahc_inb(ahc, SEQ_FLAGS), ahc_inb(ahc, SCBPTR),
ahc_index_busy_tcl(ahc,
BUILD_TCL(ahc_inb(ahc, SAVED_SCSIID),
ahc_inb(ahc, SAVED_LUN))),
ahc_inb(ahc, SINDEX));
- printf("SCSIID == 0x%x, SCB_SCSIID == 0x%x, SCB_LUN == 0x%x, "
+ printk("SCSIID == 0x%x, SCB_SCSIID == 0x%x, SCB_LUN == 0x%x, "
"SCB_TAG == 0x%x, SCB_CONTROL == 0x%x\n",
ahc_inb(ahc, SCSIID), ahc_inb(ahc, SCB_SCSIID),
ahc_inb(ahc, SCB_LUN), ahc_inb(ahc, SCB_TAG),
ahc_inb(ahc, SCB_CONTROL));
- printf("SCSIBUSL == 0x%x, SCSISIGI == 0x%x\n",
+ printk("SCSIBUSL == 0x%x, SCSISIGI == 0x%x\n",
ahc_inb(ahc, SCSIBUSL), ahc_inb(ahc, SCSISIGI));
- printf("SXFRCTL0 == 0x%x\n", ahc_inb(ahc, SXFRCTL0));
- printf("SEQCTL == 0x%x\n", ahc_inb(ahc, SEQCTL));
+ printk("SXFRCTL0 == 0x%x\n", ahc_inb(ahc, SXFRCTL0));
+ printk("SEQCTL == 0x%x\n", ahc_inb(ahc, SEQCTL));
ahc_dump_card_state(ahc);
ahc->msgout_buf[0] = MSG_BUS_DEV_RESET;
ahc->msgout_len = 1;
@@ -1197,7 +1197,7 @@ ahc_handle_seqint(struct ahc_softc *ahc, u_int intstat)
case SEND_REJECT:
{
u_int rejbyte = ahc_inb(ahc, ACCUM);
- printf("%s:%c:%d: Warning - unknown message received from "
+ printk("%s:%c:%d: Warning - unknown message received from "
"target (0x%x). Rejecting\n",
ahc_name(ahc), devinfo.channel, devinfo.target, rejbyte);
break;
@@ -1218,7 +1218,7 @@ ahc_handle_seqint(struct ahc_softc *ahc, u_int intstat)
u_int lastphase;
lastphase = ahc_inb(ahc, LASTPHASE);
- printf("%s:%c:%d: unknown scsi bus phase %x, "
+ printk("%s:%c:%d: unknown scsi bus phase %x, "
"lastphase = 0x%x. Attempting to continue\n",
ahc_name(ahc), devinfo.channel, devinfo.target,
lastphase, ahc_inb(ahc, SCSISIGI));
@@ -1229,7 +1229,7 @@ ahc_handle_seqint(struct ahc_softc *ahc, u_int intstat)
u_int lastphase;
lastphase = ahc_inb(ahc, LASTPHASE);
- printf("%s:%c:%d: Missed busfree. "
+ printk("%s:%c:%d: Missed busfree. "
"Lastphase = 0x%x, Curphase = 0x%x\n",
ahc_name(ahc), devinfo.channel, devinfo.target,
lastphase, ahc_inb(ahc, SCSISIGI));
@@ -1257,7 +1257,7 @@ ahc_handle_seqint(struct ahc_softc *ahc, u_int intstat)
bus_phase = ahc_inb(ahc, SCSISIGI) & PHASE_MASK;
if (bus_phase != P_MESGIN
&& bus_phase != P_MESGOUT) {
- printf("ahc_intr: HOST_MSG_LOOP bad "
+ printk("ahc_intr: HOST_MSG_LOOP bad "
"phase 0x%x\n",
bus_phase);
/*
@@ -1359,7 +1359,7 @@ ahc_handle_seqint(struct ahc_softc *ahc, u_int intstat)
u_int scb_index;
ahc_print_devinfo(ahc, &devinfo);
- printf("Unable to clear parity error. "
+ printk("Unable to clear parity error. "
"Resetting bus.\n");
scb_index = ahc_inb(ahc, SCB_TAG);
scb = ahc_lookup_scb(ahc, scb_index);
@@ -1395,18 +1395,18 @@ ahc_handle_seqint(struct ahc_softc *ahc, u_int intstat)
break;
}
ahc_print_path(ahc, scb);
- printf("data overrun detected %s."
+ printk("data overrun detected %s."
" Tag == 0x%x.\n",
ahc_phase_table[i].phasemsg,
scb->hscb->tag);
ahc_print_path(ahc, scb);
- printf("%s seen Data Phase. Length = %ld. NumSGs = %d.\n",
+ printk("%s seen Data Phase. Length = %ld. NumSGs = %d.\n",
ahc_inb(ahc, SEQ_FLAGS) & DPHASE ? "Have" : "Haven't",
ahc_get_transfer_length(scb), scb->sg_count);
if (scb->sg_count > 0) {
for (i = 0; i < scb->sg_count; i++) {
- printf("sg[%d] - Addr 0x%x%x : Length %d\n",
+ printk("sg[%d] - Addr 0x%x%x : Length %d\n",
i,
(ahc_le32toh(scb->sg_list[i].len) >> 24
& SG_HIGH_ADDR_BITS),
@@ -1453,7 +1453,7 @@ ahc_handle_seqint(struct ahc_softc *ahc, u_int intstat)
{
u_int scbindex;
- printf("%s:%c:%d:%d: Attempt to issue message failed\n",
+ printk("%s:%c:%d:%d: Attempt to issue message failed\n",
ahc_name(ahc), devinfo.channel, devinfo.target,
devinfo.lun);
scbindex = ahc_inb(ahc, SCB_TAG);
@@ -1473,7 +1473,7 @@ ahc_handle_seqint(struct ahc_softc *ahc, u_int intstat)
}
case NO_FREE_SCB:
{
- printf("%s: No free or disconnected SCBs\n", ahc_name(ahc));
+ printk("%s: No free or disconnected SCBs\n", ahc_name(ahc));
ahc_dump_card_state(ahc);
panic("for safety");
break;
@@ -1483,7 +1483,7 @@ ahc_handle_seqint(struct ahc_softc *ahc, u_int intstat)
u_int scbptr;
scbptr = ahc_inb(ahc, SCBPTR);
- printf("Bogus TAG after DMA. SCBPTR %d, tag %d, our tag %d\n",
+ printk("Bogus TAG after DMA. SCBPTR %d, tag %d, our tag %d\n",
scbptr, ahc_inb(ahc, ARG_1),
ahc->scb_data->hscbs[scbptr].tag);
ahc_dump_card_state(ahc);
@@ -1492,12 +1492,12 @@ ahc_handle_seqint(struct ahc_softc *ahc, u_int intstat)
}
case OUT_OF_RANGE:
{
- printf("%s: BTT calculation out of range\n", ahc_name(ahc));
- printf("SAVED_SCSIID == 0x%x, SAVED_LUN == 0x%x, "
+ printk("%s: BTT calculation out of range\n", ahc_name(ahc));
+ printk("SAVED_SCSIID == 0x%x, SAVED_LUN == 0x%x, "
"ARG_1 == 0x%x ACCUM = 0x%x\n",
ahc_inb(ahc, SAVED_SCSIID), ahc_inb(ahc, SAVED_LUN),
ahc_inb(ahc, ARG_1), ahc_inb(ahc, ACCUM));
- printf("SEQ_FLAGS == 0x%x, SCBPTR == 0x%x, BTT == 0x%x, "
+ printk("SEQ_FLAGS == 0x%x, SCBPTR == 0x%x, BTT == 0x%x, "
"SINDEX == 0x%x\n, A == 0x%x\n",
ahc_inb(ahc, SEQ_FLAGS), ahc_inb(ahc, SCBPTR),
ahc_index_busy_tcl(ahc,
@@ -1505,19 +1505,19 @@ ahc_handle_seqint(struct ahc_softc *ahc, u_int intstat)
ahc_inb(ahc, SAVED_LUN))),
ahc_inb(ahc, SINDEX),
ahc_inb(ahc, ACCUM));
- printf("SCSIID == 0x%x, SCB_SCSIID == 0x%x, SCB_LUN == 0x%x, "
+ printk("SCSIID == 0x%x, SCB_SCSIID == 0x%x, SCB_LUN == 0x%x, "
"SCB_TAG == 0x%x, SCB_CONTROL == 0x%x\n",
ahc_inb(ahc, SCSIID), ahc_inb(ahc, SCB_SCSIID),
ahc_inb(ahc, SCB_LUN), ahc_inb(ahc, SCB_TAG),
ahc_inb(ahc, SCB_CONTROL));
- printf("SCSIBUSL == 0x%x, SCSISIGI == 0x%x\n",
+ printk("SCSIBUSL == 0x%x, SCSISIGI == 0x%x\n",
ahc_inb(ahc, SCSIBUSL), ahc_inb(ahc, SCSISIGI));
ahc_dump_card_state(ahc);
panic("for safety");
break;
}
default:
- printf("ahc_intr: seqint, "
+ printk("ahc_intr: seqint, "
"intstat == 0x%x, scsisigi = 0x%x\n",
intstat, ahc_inb(ahc, SCSISIGI));
break;
@@ -1562,7 +1562,7 @@ ahc_handle_scsiint(struct ahc_softc *ahc, u_int intstat)
intr_channel = (cur_channel == 'A') ? 'B' : 'A';
}
if (status == 0) {
- printf("%s: Spurious SCSI interrupt\n", ahc_name(ahc));
+ printk("%s: Spurious SCSI interrupt\n", ahc_name(ahc));
ahc_outb(ahc, CLRINT, CLRSCSIINT);
ahc_unpause(ahc);
return;
@@ -1583,7 +1583,7 @@ ahc_handle_scsiint(struct ahc_softc *ahc, u_int intstat)
int now_lvd;
now_lvd = ahc_inb(ahc, SBLKCTL) & ENAB40;
- printf("%s: Transceiver State Has Changed to %s mode\n",
+ printk("%s: Transceiver State Has Changed to %s mode\n",
ahc_name(ahc), now_lvd ? "LVD" : "SE");
ahc_outb(ahc, CLRSINT0, CLRIOERR);
/*
@@ -1599,7 +1599,7 @@ ahc_handle_scsiint(struct ahc_softc *ahc, u_int intstat)
ahc_reset_channel(ahc, intr_channel,
/*Initiate Reset*/now_lvd == 0);
} else if ((status & SCSIRSTI) != 0) {
- printf("%s: Someone reset channel %c\n",
+ printk("%s: Someone reset channel %c\n",
ahc_name(ahc), intr_channel);
if (intr_channel != cur_channel)
ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) ^ SELBUSB);
@@ -1659,26 +1659,26 @@ ahc_handle_scsiint(struct ahc_softc *ahc, u_int intstat)
ahc_print_path(ahc, scb);
scb->flags |= SCB_TRANSMISSION_ERROR;
} else
- printf("%s:%c:%d: ", ahc_name(ahc), intr_channel,
+ printk("%s:%c:%d: ", ahc_name(ahc), intr_channel,
SCSIID_TARGET(ahc, ahc_inb(ahc, SAVED_SCSIID)));
scsirate = ahc_inb(ahc, SCSIRATE);
if (silent == FALSE) {
- printf("parity error detected %s. "
+ printk("parity error detected %s. "
"SEQADDR(0x%x) SCSIRATE(0x%x)\n",
ahc_phase_table[i].phasemsg,
ahc_inw(ahc, SEQADDR0),
scsirate);
if ((ahc->features & AHC_DT) != 0) {
if ((sstat2 & CRCVALERR) != 0)
- printf("\tCRC Value Mismatch\n");
+ printk("\tCRC Value Mismatch\n");
if ((sstat2 & CRCENDERR) != 0)
- printf("\tNo terminal CRC packet "
+ printk("\tNo terminal CRC packet "
"recevied\n");
if ((sstat2 & CRCREQERR) != 0)
- printf("\tIllegal CRC packet "
+ printk("\tIllegal CRC packet "
"request\n");
if ((sstat2 & DUAL_EDGE_ERR) != 0)
- printf("\tUnexpected %sDT Data Phase\n",
+ printk("\tUnexpected %sDT Data Phase\n",
(scsirate & SINGLE_EDGE)
? "" : "non-");
}
@@ -1746,7 +1746,7 @@ ahc_handle_scsiint(struct ahc_softc *ahc, u_int intstat)
scb = ahc_lookup_scb(ahc, scb_index);
if (scb == NULL) {
- printf("%s: ahc_intr - referenced scb not "
+ printk("%s: ahc_intr - referenced scb not "
"valid during SELTO scb(%d, %d)\n",
ahc_name(ahc), scbptr, scb_index);
ahc_dump_card_state(ahc);
@@ -1755,7 +1755,7 @@ ahc_handle_scsiint(struct ahc_softc *ahc, u_int intstat)
#ifdef AHC_DEBUG
if ((ahc_debug & AHC_SHOW_SELTO) != 0) {
ahc_print_path(ahc, scb);
- printf("Saw Selection Timeout for SCB 0x%x\n",
+ printk("Saw Selection Timeout for SCB 0x%x\n",
scb_index);
}
#endif
@@ -1831,7 +1831,7 @@ ahc_handle_scsiint(struct ahc_softc *ahc, u_int intstat)
== MSG_ABORT_TAG)
tag = scb->hscb->tag;
ahc_print_path(ahc, scb);
- printf("SCB %d - Abort%s Completed.\n",
+ printk("SCB %d - Abort%s Completed.\n",
scb->hscb->tag, tag == SCB_LIST_NULL ?
"" : " Tag");
ahc_abort_scbs(ahc, target, channel,
@@ -1934,7 +1934,7 @@ ahc_handle_scsiint(struct ahc_softc *ahc, u_int intstat)
* We had not fully identified this connection,
* so we cannot abort anything.
*/
- printf("%s: ", ahc_name(ahc));
+ printk("%s: ", ahc_name(ahc));
}
for (i = 0; i < num_phases; i++) {
if (lastphase == ahc_phase_table[i].phase)
@@ -1949,7 +1949,7 @@ ahc_handle_scsiint(struct ahc_softc *ahc, u_int intstat)
*/
ahc_force_renegotiation(ahc, &devinfo);
}
- printf("Unexpected busfree %s\n"
+ printk("Unexpected busfree %s\n"
"SEQADDR == 0x%x\n",
ahc_phase_table[i].phasemsg,
ahc_inb(ahc, SEQADDR0)
@@ -1958,7 +1958,7 @@ ahc_handle_scsiint(struct ahc_softc *ahc, u_int intstat)
ahc_outb(ahc, CLRINT, CLRSCSIINT);
ahc_restart(ahc);
} else {
- printf("%s: Missing case in ahc_handle_scsiint. status = %x\n",
+ printk("%s: Missing case in ahc_handle_scsiint. status = %x\n",
ahc_name(ahc), status);
ahc_outb(ahc, CLRINT, CLRSCSIINT);
}
@@ -2025,7 +2025,7 @@ ahc_clear_critical_section(struct ahc_softc *ahc)
break;
if (steps > AHC_MAX_STEPS) {
- printf("%s: Infinite loop in critical section\n",
+ printk("%s: Infinite loop in critical section\n",
ahc_name(ahc));
ahc_dump_card_state(ahc);
panic("critical section loop");
@@ -2104,23 +2104,23 @@ ahc_print_scb(struct scb *scb)
struct hardware_scb *hscb = scb->hscb;
- printf("scb:%p control:0x%x scsiid:0x%x lun:%d cdb_len:%d\n",
+ printk("scb:%p control:0x%x scsiid:0x%x lun:%d cdb_len:%d\n",
(void *)scb,
hscb->control,
hscb->scsiid,
hscb->lun,
hscb->cdb_len);
- printf("Shared Data: ");
+ printk("Shared Data: ");
for (i = 0; i < sizeof(hscb->shared_data.cdb); i++)
- printf("%#02x", hscb->shared_data.cdb[i]);
- printf(" dataptr:%#x datacnt:%#x sgptr:%#x tag:%#x\n",
+ printk("%#02x", hscb->shared_data.cdb[i]);
+ printk(" dataptr:%#x datacnt:%#x sgptr:%#x tag:%#x\n",
ahc_le32toh(hscb->dataptr),
ahc_le32toh(hscb->datacnt),
ahc_le32toh(hscb->sgptr),
hscb->tag);
if (scb->sg_count > 0) {
for (i = 0; i < scb->sg_count; i++) {
- printf("sg[%d] - Addr 0x%x%x : Length %d\n",
+ printk("sg[%d] - Addr 0x%x%x : Length %d\n",
i,
(ahc_le32toh(scb->sg_list[i].len) >> 24
& SG_HIGH_ADDR_BITS),
@@ -2152,8 +2152,7 @@ ahc_alloc_tstate(struct ahc_softc *ahc, u_int scsi_id, char channel)
&& ahc->enabled_targets[scsi_id] != master_tstate)
panic("%s: ahc_alloc_tstate - Target already allocated",
ahc_name(ahc));
- tstate = (struct ahc_tmode_tstate*)malloc(sizeof(*tstate),
- M_DEVBUF, M_NOWAIT);
+ tstate = kmalloc(sizeof(*tstate), GFP_ATOMIC);
if (tstate == NULL)
return (NULL);
@@ -2202,7 +2201,7 @@ ahc_free_tstate(struct ahc_softc *ahc, u_int scsi_id, char channel, int force)
scsi_id += 8;
tstate = ahc->enabled_targets[scsi_id];
if (tstate != NULL)
- free(tstate, M_DEVBUF);
+ kfree(tstate);
ahc->enabled_targets[scsi_id] = NULL;
}
#endif
@@ -2589,13 +2588,13 @@ ahc_set_syncrate(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
CAM_LUN_WILDCARD, AC_TRANSFER_NEG);
if (bootverbose) {
if (offset != 0) {
- printf("%s: target %d synchronous at %sMHz%s, "
+ printk("%s: target %d synchronous at %sMHz%s, "
"offset = 0x%x\n", ahc_name(ahc),
devinfo->target, syncrate->rate,
(ppr_options & MSG_EXT_PPR_DT_REQ)
? " DT" : "", offset);
} else {
- printf("%s: target %d using "
+ printk("%s: target %d using "
"asynchronous transfers\n",
ahc_name(ahc), devinfo->target);
}
@@ -2658,7 +2657,7 @@ ahc_set_width(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
ahc_send_async(ahc, devinfo->channel, devinfo->target,
CAM_LUN_WILDCARD, AC_TRANSFER_NEG);
if (bootverbose) {
- printf("%s: target %d using %dbit transfers\n",
+ printk("%s: target %d using %dbit transfers\n",
ahc_name(ahc), devinfo->target,
8 * (0x01 << width));
}
@@ -2835,7 +2834,7 @@ ahc_compile_devinfo(struct ahc_devinfo *devinfo, u_int our_id, u_int target,
void
ahc_print_devinfo(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
{
- printf("%s:%c:%d:%d: ", ahc_name(ahc), devinfo->channel,
+ printk("%s:%c:%d:%d: ", ahc_name(ahc), devinfo->channel,
devinfo->target, devinfo->lun);
}
@@ -2907,7 +2906,7 @@ ahc_setup_initiator_msgout(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
ahc->msgout_buf[ahc->msgout_index++] = MSG_BUS_DEV_RESET;
ahc->msgout_len++;
ahc_print_path(ahc, scb);
- printf("Bus Device Reset Message Sent\n");
+ printk("Bus Device Reset Message Sent\n");
/*
* Clear our selection hardware in advance of
* the busfree. We may have an entry in the waiting
@@ -2923,7 +2922,7 @@ ahc_setup_initiator_msgout(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
ahc->msgout_buf[ahc->msgout_index++] = MSG_ABORT;
ahc->msgout_len++;
ahc_print_path(ahc, scb);
- printf("Abort%s Message Sent\n",
+ printk("Abort%s Message Sent\n",
(scb->hscb->control & TAG_ENB) != 0 ? " Tag" : "");
/*
* Clear our selection hardware in advance of
@@ -2936,9 +2935,9 @@ ahc_setup_initiator_msgout(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
} else if ((scb->flags & (SCB_AUTO_NEGOTIATE|SCB_NEGOTIATE)) != 0) {
ahc_build_transfer_msg(ahc, devinfo);
} else {
- printf("ahc_intr: AWAITING_MSG for an SCB that "
+ printk("ahc_intr: AWAITING_MSG for an SCB that "
"does not have a waiting message\n");
- printf("SCSIID = %x, target_mask = %x\n", scb->hscb->scsiid,
+ printk("SCSIID = %x, target_mask = %x\n", scb->hscb->scsiid,
devinfo->target_mask);
panic("SCB = %d, SCB Control = %x, MSG_OUT = %x "
"SCB flags = %x", scb->hscb->tag, scb->hscb->control,
@@ -3019,7 +3018,7 @@ ahc_build_transfer_msg(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
if (bootverbose) {
ahc_print_devinfo(ahc, devinfo);
- printf("Ensuring async\n");
+ printk("Ensuring async\n");
}
}
@@ -3067,7 +3066,7 @@ ahc_construct_sdtr(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
ahc->msgout_buf + ahc->msgout_index, period, offset);
ahc->msgout_len += 5;
if (bootverbose) {
- printf("(%s:%c:%d:%d): Sending SDTR period %x, offset %x\n",
+ printk("(%s:%c:%d:%d): Sending SDTR period %x, offset %x\n",
ahc_name(ahc), devinfo->channel, devinfo->target,
devinfo->lun, period, offset);
}
@@ -3085,7 +3084,7 @@ ahc_construct_wdtr(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
ahc->msgout_buf + ahc->msgout_index, bus_width);
ahc->msgout_len += 4;
if (bootverbose) {
- printf("(%s:%c:%d:%d): Sending WDTR %x\n",
+ printk("(%s:%c:%d:%d): Sending WDTR %x\n",
ahc_name(ahc), devinfo->channel, devinfo->target,
devinfo->lun, bus_width);
}
@@ -3107,7 +3106,7 @@ ahc_construct_ppr(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
bus_width, ppr_options);
ahc->msgout_len += 8;
if (bootverbose) {
- printf("(%s:%c:%d:%d): Sending PPR bus_width %x, period %x, "
+ printk("(%s:%c:%d:%d): Sending PPR bus_width %x, period %x, "
"offset %x, ppr_options %x\n", ahc_name(ahc),
devinfo->channel, devinfo->target, devinfo->lun,
bus_width, period, offset, ppr_options);
@@ -3160,7 +3159,7 @@ ahc_handle_proto_violation(struct ahc_softc *ahc)
* to match.
*/
ahc_print_devinfo(ahc, &devinfo);
- printf("Target did not send an IDENTIFY message. "
+ printk("Target did not send an IDENTIFY message. "
"LASTPHASE = 0x%x.\n", lastphase);
scb = NULL;
} else if (scb == NULL) {
@@ -3169,13 +3168,13 @@ ahc_handle_proto_violation(struct ahc_softc *ahc)
* transaction. Print an error and reset the bus.
*/
ahc_print_devinfo(ahc, &devinfo);
- printf("No SCB found during protocol violation\n");
+ printk("No SCB found during protocol violation\n");
goto proto_violation_reset;
} else {
ahc_set_transaction_status(scb, CAM_SEQUENCE_FAIL);
if ((seq_flags & NO_CDB_SENT) != 0) {
ahc_print_path(ahc, scb);
- printf("No or incomplete CDB sent to device.\n");
+ printk("No or incomplete CDB sent to device.\n");
} else if ((ahc_inb(ahc, SCB_CONTROL) & STATUS_RCVD) == 0) {
/*
* The target never bothered to provide status to
@@ -3185,10 +3184,10 @@ ahc_handle_proto_violation(struct ahc_softc *ahc)
* message.
*/
ahc_print_path(ahc, scb);
- printf("Completed command without status.\n");
+ printk("Completed command without status.\n");
} else {
ahc_print_path(ahc, scb);
- printf("Unknown protocol violation.\n");
+ printk("Unknown protocol violation.\n");
ahc_dump_card_state(ahc);
}
}
@@ -3202,7 +3201,7 @@ proto_violation_reset:
* it away with a bus reset.
*/
found = ahc_reset_channel(ahc, 'A', TRUE);
- printf("%s: Issued Channel %c Bus Reset. "
+ printk("%s: Issued Channel %c Bus Reset. "
"%d SCBs aborted\n", ahc_name(ahc), 'A', found);
} else {
/*
@@ -3224,7 +3223,7 @@ proto_violation_reset:
ahc_print_path(ahc, scb);
scb->flags |= SCB_ABORT;
}
- printf("Protocol violation %s. Attempting to abort.\n",
+ printk("Protocol violation %s. Attempting to abort.\n",
ahc_lookup_phase_entry(curphase)->phasemsg);
}
}
@@ -3257,14 +3256,14 @@ reswitch:
#ifdef AHC_DEBUG
if ((ahc_debug & AHC_SHOW_MESSAGES) != 0) {
ahc_print_devinfo(ahc, &devinfo);
- printf("INITIATOR_MSG_OUT");
+ printk("INITIATOR_MSG_OUT");
}
#endif
phasemis = bus_phase != P_MESGOUT;
if (phasemis) {
#ifdef AHC_DEBUG
if ((ahc_debug & AHC_SHOW_MESSAGES) != 0) {
- printf(" PHASEMIS %s\n",
+ printk(" PHASEMIS %s\n",
ahc_lookup_phase_entry(bus_phase)
->phasemsg);
}
@@ -3291,7 +3290,7 @@ reswitch:
ahc_outb(ahc, CLRSINT1, CLRREQINIT);
#ifdef AHC_DEBUG
if ((ahc_debug & AHC_SHOW_MESSAGES) != 0)
- printf(" byte 0x%x\n", ahc->send_msg_perror);
+ printk(" byte 0x%x\n", ahc->send_msg_perror);
#endif
ahc_outb(ahc, SCSIDATL, MSG_PARITY_ERROR);
break;
@@ -3321,7 +3320,7 @@ reswitch:
ahc_outb(ahc, CLRSINT1, CLRREQINIT);
#ifdef AHC_DEBUG
if ((ahc_debug & AHC_SHOW_MESSAGES) != 0)
- printf(" byte 0x%x\n",
+ printk(" byte 0x%x\n",
ahc->msgout_buf[ahc->msgout_index]);
#endif
ahc_outb(ahc, SCSIDATL, ahc->msgout_buf[ahc->msgout_index++]);
@@ -3335,14 +3334,14 @@ reswitch:
#ifdef AHC_DEBUG
if ((ahc_debug & AHC_SHOW_MESSAGES) != 0) {
ahc_print_devinfo(ahc, &devinfo);
- printf("INITIATOR_MSG_IN");
+ printk("INITIATOR_MSG_IN");
}
#endif
phasemis = bus_phase != P_MESGIN;
if (phasemis) {
#ifdef AHC_DEBUG
if ((ahc_debug & AHC_SHOW_MESSAGES) != 0) {
- printf(" PHASEMIS %s\n",
+ printk(" PHASEMIS %s\n",
ahc_lookup_phase_entry(bus_phase)
->phasemsg);
}
@@ -3363,7 +3362,7 @@ reswitch:
ahc->msgin_buf[ahc->msgin_index] = ahc_inb(ahc, SCSIBUSL);
#ifdef AHC_DEBUG
if ((ahc_debug & AHC_SHOW_MESSAGES) != 0)
- printf(" byte 0x%x\n",
+ printk(" byte 0x%x\n",
ahc->msgin_buf[ahc->msgin_index]);
#endif
@@ -3385,7 +3384,7 @@ reswitch:
#ifdef AHC_DEBUG
if ((ahc_debug & AHC_SHOW_MESSAGES) != 0) {
ahc_print_devinfo(ahc, &devinfo);
- printf("Asserting ATN for response\n");
+ printk("Asserting ATN for response\n");
}
#endif
ahc_assert_atn(ahc);
@@ -3666,7 +3665,7 @@ ahc_parse_msg(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
targ_scsirate & WIDEXFER,
devinfo->role);
if (bootverbose) {
- printf("(%s:%c:%d:%d): Received "
+ printk("(%s:%c:%d:%d): Received "
"SDTR period %x, offset %x\n\t"
"Filtered to period %x, offset %x\n",
ahc_name(ahc), devinfo->channel,
@@ -3697,7 +3696,7 @@ ahc_parse_msg(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
*/
if (bootverbose
&& devinfo->role == ROLE_INITIATOR) {
- printf("(%s:%c:%d:%d): Target "
+ printk("(%s:%c:%d:%d): Target "
"Initiated SDTR\n",
ahc_name(ahc), devinfo->channel,
devinfo->target, devinfo->lun);
@@ -3739,7 +3738,7 @@ ahc_parse_msg(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
ahc_validate_width(ahc, tinfo, &bus_width,
devinfo->role);
if (bootverbose) {
- printf("(%s:%c:%d:%d): Received WDTR "
+ printk("(%s:%c:%d:%d): Received WDTR "
"%x filtered to %x\n",
ahc_name(ahc), devinfo->channel,
devinfo->target, devinfo->lun,
@@ -3755,7 +3754,7 @@ ahc_parse_msg(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
*/
if (saved_width > bus_width) {
reject = TRUE;
- printf("(%s:%c:%d:%d): requested %dBit "
+ printk("(%s:%c:%d:%d): requested %dBit "
"transfers. Rejecting...\n",
ahc_name(ahc), devinfo->channel,
devinfo->target, devinfo->lun,
@@ -3768,7 +3767,7 @@ ahc_parse_msg(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
*/
if (bootverbose
&& devinfo->role == ROLE_INITIATOR) {
- printf("(%s:%c:%d:%d): Target "
+ printk("(%s:%c:%d:%d): Target "
"Initiated WDTR\n",
ahc_name(ahc), devinfo->channel,
devinfo->target, devinfo->lun);
@@ -3886,12 +3885,12 @@ ahc_parse_msg(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
}
} else {
if (devinfo->role != ROLE_TARGET)
- printf("(%s:%c:%d:%d): Target "
+ printk("(%s:%c:%d:%d): Target "
"Initiated PPR\n",
ahc_name(ahc), devinfo->channel,
devinfo->target, devinfo->lun);
else
- printf("(%s:%c:%d:%d): Initiator "
+ printk("(%s:%c:%d:%d): Initiator "
"Initiated PPR\n",
ahc_name(ahc), devinfo->channel,
devinfo->target, devinfo->lun);
@@ -3903,7 +3902,7 @@ ahc_parse_msg(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
response = TRUE;
}
if (bootverbose) {
- printf("(%s:%c:%d:%d): Received PPR width %x, "
+ printk("(%s:%c:%d:%d): Received PPR width %x, "
"period %x, offset %x,options %x\n"
"\tFiltered to width %x, period %x, "
"offset %x, options %x\n",
@@ -4033,7 +4032,7 @@ ahc_handle_msg_reject(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
* Attempt to negotiate SPI-2 style.
*/
if (bootverbose) {
- printf("(%s:%c:%d:%d): PPR Rejected. "
+ printk("(%s:%c:%d:%d): PPR Rejected. "
"Trying WDTR/SDTR\n",
ahc_name(ahc), devinfo->channel,
devinfo->target, devinfo->lun);
@@ -4049,7 +4048,7 @@ ahc_handle_msg_reject(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
} else if (ahc_sent_msg(ahc, AHCMSG_EXT, MSG_EXT_WDTR, /*full*/FALSE)) {
/* note 8bit xfers */
- printf("(%s:%c:%d:%d): refuses WIDE negotiation. Using "
+ printk("(%s:%c:%d:%d): refuses WIDE negotiation. Using "
"8bit transfers\n", ahc_name(ahc),
devinfo->channel, devinfo->target, devinfo->lun);
ahc_set_width(ahc, devinfo, MSG_EXT_WDTR_BUS_8_BIT,
@@ -4077,7 +4076,7 @@ ahc_handle_msg_reject(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
/*offset*/0, /*ppr_options*/0,
AHC_TRANS_ACTIVE|AHC_TRANS_GOAL,
/*paused*/TRUE);
- printf("(%s:%c:%d:%d): refuses synchronous negotiation. "
+ printk("(%s:%c:%d:%d): refuses synchronous negotiation. "
"Using asynchronous transfers\n",
ahc_name(ahc), devinfo->channel,
devinfo->target, devinfo->lun);
@@ -4088,13 +4087,13 @@ ahc_handle_msg_reject(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
tag_type = (scb->hscb->control & MSG_SIMPLE_TASK);
if (tag_type == MSG_SIMPLE_TASK) {
- printf("(%s:%c:%d:%d): refuses tagged commands. "
+ printk("(%s:%c:%d:%d): refuses tagged commands. "
"Performing non-tagged I/O\n", ahc_name(ahc),
devinfo->channel, devinfo->target, devinfo->lun);
ahc_set_tags(ahc, scb->io_ctx, devinfo, AHC_QUEUE_NONE);
mask = ~0x23;
} else {
- printf("(%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",
ahc_name(ahc), devinfo->channel, devinfo->target,
devinfo->lun, tag_type == MSG_ORDERED_TASK
@@ -4144,7 +4143,7 @@ ahc_handle_msg_reject(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
/*
* Otherwise, we ignore it.
*/
- printf("%s:%c:%d: Message reject for %x -- ignored\n",
+ printk("%s:%c:%d: Message reject for %x -- ignored\n",
ahc_name(ahc), devinfo->channel, devinfo->target,
last_msg);
}
@@ -4369,7 +4368,7 @@ ahc_handle_devreset(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
if (message != NULL
&& (verbose_level <= bootverbose))
- printf("%s: %s on %c:%d. %d SCBs aborted\n", ahc_name(ahc),
+ printk("%s: %s on %c:%d. %d SCBs aborted\n", ahc_name(ahc),
message, devinfo->channel, devinfo->target, found);
}
@@ -4408,23 +4407,22 @@ ahc_alloc(void *platform_arg, char *name)
int i;
#ifndef __FreeBSD__
- ahc = malloc(sizeof(*ahc), M_DEVBUF, M_NOWAIT);
+ ahc = kmalloc(sizeof(*ahc), GFP_ATOMIC);
if (!ahc) {
- printf("aic7xxx: cannot malloc softc!\n");
- free(name, M_DEVBUF);
+ printk("aic7xxx: cannot malloc softc!\n");
+ kfree(name);
return NULL;
}
#else
ahc = device_get_softc((device_t)platform_arg);
#endif
memset(ahc, 0, sizeof(*ahc));
- ahc->seep_config = malloc(sizeof(*ahc->seep_config),
- M_DEVBUF, M_NOWAIT);
+ ahc->seep_config = kmalloc(sizeof(*ahc->seep_config), GFP_ATOMIC);
if (ahc->seep_config == NULL) {
#ifndef __FreeBSD__
- free(ahc, M_DEVBUF);
+ kfree(ahc);
#endif
- free(name, M_DEVBUF);
+ kfree(name);
return (NULL);
}
LIST_INIT(&ahc->pending_scbs);
@@ -4466,8 +4464,7 @@ ahc_softc_init(struct ahc_softc *ahc)
ahc->pause = ahc->unpause | PAUSE;
/* XXX The shared scb data stuff should be deprecated */
if (ahc->scb_data == NULL) {
- ahc->scb_data = malloc(sizeof(*ahc->scb_data),
- M_DEVBUF, M_NOWAIT);
+ ahc->scb_data = kmalloc(sizeof(*ahc->scb_data), GFP_ATOMIC);
if (ahc->scb_data == NULL)
return (ENOMEM);
memset(ahc->scb_data, 0, sizeof(*ahc->scb_data));
@@ -4486,7 +4483,7 @@ void
ahc_set_name(struct ahc_softc *ahc, char *name)
{
if (ahc->name != NULL)
- free(ahc->name, M_DEVBUF);
+ kfree(ahc->name);
ahc->name = name;
}
@@ -4540,25 +4537,25 @@ ahc_free(struct ahc_softc *ahc)
lstate = tstate->enabled_luns[j];
if (lstate != NULL) {
xpt_free_path(lstate->path);
- free(lstate, M_DEVBUF);
+ kfree(lstate);
}
}
#endif
- free(tstate, M_DEVBUF);
+ kfree(tstate);
}
}
#ifdef AHC_TARGET_MODE
if (ahc->black_hole != NULL) {
xpt_free_path(ahc->black_hole->path);
- free(ahc->black_hole, M_DEVBUF);
+ kfree(ahc->black_hole);
}
#endif
if (ahc->name != NULL)
- free(ahc->name, M_DEVBUF);
+ kfree(ahc->name);
if (ahc->seep_config != NULL)
- free(ahc->seep_config, M_DEVBUF);
+ kfree(ahc->seep_config);
#ifndef __FreeBSD__
- free(ahc, M_DEVBUF);
+ kfree(ahc);
#endif
return;
}
@@ -4633,7 +4630,7 @@ ahc_reset(struct ahc_softc *ahc, int reinit)
} while (--wait && !(ahc_inb(ahc, HCNTRL) & CHIPRSTACK));
if (wait == 0) {
- printf("%s: WARNING - Failed chip reset! "
+ printk("%s: WARNING - Failed chip reset! "
"Trying to initialize anyway.\n", ahc_name(ahc));
}
ahc_outb(ahc, HCNTRL, ahc->pause);
@@ -4656,7 +4653,7 @@ ahc_reset(struct ahc_softc *ahc, int reinit)
ahc->features |= AHC_TWIN;
break;
default:
- printf(" Unsupported adapter type. Ignoring\n");
+ printk(" Unsupported adapter type. Ignoring\n");
return(-1);
}
@@ -4783,9 +4780,7 @@ ahc_init_scbdata(struct ahc_softc *ahc)
SLIST_INIT(&scb_data->sg_maps);
/* Allocate SCB resources */
- scb_data->scbarray =
- (struct scb *)malloc(sizeof(struct scb) * AHC_SCB_MAX_ALLOC,
- M_DEVBUF, M_NOWAIT);
+ scb_data->scbarray = (struct scb *)kmalloc(sizeof(struct scb) * AHC_SCB_MAX_ALLOC, GFP_ATOMIC);
if (scb_data->scbarray == NULL)
return (ENOMEM);
memset(scb_data->scbarray, 0, sizeof(struct scb) * AHC_SCB_MAX_ALLOC);
@@ -4794,7 +4789,7 @@ ahc_init_scbdata(struct ahc_softc *ahc)
scb_data->maxhscbs = ahc_probe_scbs(ahc);
if (ahc->scb_data->maxhscbs == 0) {
- printf("%s: No SCB space found\n", ahc_name(ahc));
+ printk("%s: No SCB space found\n", ahc_name(ahc));
return (ENXIO);
}
@@ -4892,7 +4887,7 @@ ahc_init_scbdata(struct ahc_softc *ahc)
ahc_alloc_scbs(ahc);
if (scb_data->numscbs == 0) {
- printf("%s: ahc_init_scbdata - "
+ printk("%s: ahc_init_scbdata - "
"Unable to allocate initial scbs\n",
ahc_name(ahc));
goto error_exit;
@@ -4935,7 +4930,7 @@ ahc_fini_scbdata(struct ahc_softc *ahc)
ahc_dmamem_free(ahc, scb_data->sg_dmat,
sg_map->sg_vaddr,
sg_map->sg_dmamap);
- free(sg_map, M_DEVBUF);
+ kfree(sg_map);
}
ahc_dma_tag_destroy(ahc, scb_data->sg_dmat);
}
@@ -4964,7 +4959,7 @@ ahc_fini_scbdata(struct ahc_softc *ahc)
break;
}
if (scb_data->scbarray != NULL)
- free(scb_data->scbarray, M_DEVBUF);
+ kfree(scb_data->scbarray);
}
static void
@@ -4985,7 +4980,7 @@ ahc_alloc_scbs(struct ahc_softc *ahc)
next_scb = &scb_data->scbarray[scb_data->numscbs];
- sg_map = malloc(sizeof(*sg_map), M_DEVBUF, M_NOWAIT);
+ sg_map = kmalloc(sizeof(*sg_map), GFP_ATOMIC);
if (sg_map == NULL)
return;
@@ -4994,7 +4989,7 @@ ahc_alloc_scbs(struct ahc_softc *ahc)
if (ahc_dmamem_alloc(ahc, scb_data->sg_dmat,
(void **)&sg_map->sg_vaddr,
BUS_DMA_NOWAIT, &sg_map->sg_dmamap) != 0) {
- free(sg_map, M_DEVBUF);
+ kfree(sg_map);
return;
}
@@ -5014,8 +5009,7 @@ ahc_alloc_scbs(struct ahc_softc *ahc)
#ifndef __linux__
int error;
#endif
- pdata = (struct scb_platform_data *)malloc(sizeof(*pdata),
- M_DEVBUF, M_NOWAIT);
+ pdata = kmalloc(sizeof(*pdata), GFP_ATOMIC);
if (pdata == NULL)
break;
next_scb->platform_data = pdata;
@@ -5244,7 +5238,7 @@ ahc_chip_init(struct ahc_softc *ahc)
* in "fast" mode.
*/
if (bootverbose)
- printf("%s: Downloading Sequencer Program...",
+ printk("%s: Downloading Sequencer Program...",
ahc_name(ahc));
error = ahc_loadseq(ahc);
@@ -5290,22 +5284,22 @@ ahc_init(struct ahc_softc *ahc)
#endif
#ifdef AHC_PRINT_SRAM
- printf("Scratch Ram:");
+ printk("Scratch Ram:");
for (i = 0x20; i < 0x5f; i++) {
if (((i % 8) == 0) && (i != 0)) {
- printf ("\n ");
+ printk ("\n ");
}
- printf (" 0x%x", ahc_inb(ahc, i));
+ printk (" 0x%x", ahc_inb(ahc, i));
}
if ((ahc->features & AHC_MORE_SRAM) != 0) {
for (i = 0x70; i < 0x7f; i++) {
if (((i % 8) == 0) && (i != 0)) {
- printf ("\n ");
+ printk ("\n ");
}
- printf (" 0x%x", ahc_inb(ahc, i));
+ printk (" 0x%x", ahc_inb(ahc, i));
}
}
- printf ("\n");
+ printk ("\n");
/*
* Reading uninitialized scratch ram may
* generate parity errors.
@@ -5419,14 +5413,14 @@ ahc_init(struct ahc_softc *ahc)
* data for any target mode initiator.
*/
if (ahc_alloc_tstate(ahc, ahc->our_id, 'A') == NULL) {
- printf("%s: unable to allocate ahc_tmode_tstate. "
+ printk("%s: unable to allocate ahc_tmode_tstate. "
"Failing attach\n", ahc_name(ahc));
return (ENOMEM);
}
if ((ahc->features & AHC_TWIN) != 0) {
if (ahc_alloc_tstate(ahc, ahc->our_id_b, 'B') == NULL) {
- printf("%s: unable to allocate ahc_tmode_tstate. "
+ printk("%s: unable to allocate ahc_tmode_tstate. "
"Failing attach\n", ahc_name(ahc));
return (ENOMEM);
}
@@ -5440,7 +5434,7 @@ ahc_init(struct ahc_softc *ahc)
#ifdef AHC_DEBUG
if (ahc_debug & AHC_SHOW_MISC) {
- printf("%s: hardware scb %u bytes; kernel scb %u bytes; "
+ printk("%s: hardware scb %u bytes; kernel scb %u bytes; "
"ahc_dma %u bytes\n",
ahc_name(ahc),
(u_int)sizeof(struct hardware_scb),
@@ -5470,7 +5464,7 @@ ahc_init(struct ahc_softc *ahc)
/* Grab the disconnection disable table and invert it for our needs */
if ((ahc->flags & AHC_USEDEFAULTS) != 0) {
- printf("%s: Host Adapter Bios disabled. Using default SCSI "
+ printk("%s: Host Adapter Bios disabled. Using default SCSI "
"device parameters\n", ahc_name(ahc));
ahc->flags |= AHC_EXTENDED_TRANS_A|AHC_EXTENDED_TRANS_B|
AHC_TERM_ENB_A|AHC_TERM_ENB_B;
@@ -5651,7 +5645,7 @@ ahc_pause_and_flushwork(struct ahc_softc *ahc)
&& ((intstat & INT_PEND) != 0
|| (ahc_inb(ahc, SSTAT0) & (SELDO|SELINGO)) != 0));
if (maxloops == 0) {
- printf("Infinite interrupt loop, INTSTAT = %x",
+ printk("Infinite interrupt loop, INTSTAT = %x",
ahc_inb(ahc, INTSTAT));
}
ahc_platform_flushwork(ahc);
@@ -5910,7 +5904,7 @@ ahc_search_qinfifo(struct ahc_softc *ahc, int target, char channel,
while (qinpos != qintail) {
scb = ahc_lookup_scb(ahc, ahc->qinfifo[qinpos]);
if (scb == NULL) {
- printf("qinpos = %d, SCB index = %d\n",
+ printk("qinpos = %d, SCB index = %d\n",
qinpos, ahc->qinfifo[qinpos]);
panic("Loop 1\n");
}
@@ -5933,7 +5927,7 @@ ahc_search_qinfifo(struct ahc_softc *ahc, int target, char channel,
if (cstat != CAM_REQ_CMP)
ahc_freeze_scb(scb);
if ((scb->flags & SCB_ACTIVE) == 0)
- printf("Inactive SCB in qinfifo\n");
+ printk("Inactive SCB in qinfifo\n");
ahc_done(ahc, scb);
/* FALLTHROUGH */
@@ -5976,7 +5970,7 @@ ahc_search_qinfifo(struct ahc_softc *ahc, int target, char channel,
scb = ahc_lookup_scb(ahc, ahc->qinfifo[qinstart]);
if (scb == NULL) {
- printf("found = %d, qinstart = %d, qinfifionext = %d\n",
+ printk("found = %d, qinstart = %d, qinfifionext = %d\n",
found, qinstart, ahc->qinfifonext);
panic("First/Second Qinfifo fixup\n");
}
@@ -6014,7 +6008,7 @@ ahc_search_qinfifo(struct ahc_softc *ahc, int target, char channel,
ahc_outb(ahc, SCBPTR, next);
scb_index = ahc_inb(ahc, SCB_TAG);
if (scb_index >= ahc->scb_data->numscbs) {
- printf("Waiting List inconsistency. "
+ printk("Waiting List inconsistency. "
"SCB index == %d, yet numscbs == %d.",
scb_index, ahc->scb_data->numscbs);
ahc_dump_card_state(ahc);
@@ -6022,7 +6016,7 @@ ahc_search_qinfifo(struct ahc_softc *ahc, int target, char channel,
}
scb = ahc_lookup_scb(ahc, scb_index);
if (scb == NULL) {
- printf("scb_index = %d, next = %d\n",
+ printk("scb_index = %d, next = %d\n",
scb_index, next);
panic("Waiting List traversal\n");
}
@@ -6046,7 +6040,7 @@ ahc_search_qinfifo(struct ahc_softc *ahc, int target, char channel,
if (cstat != CAM_REQ_CMP)
ahc_freeze_scb(scb);
if ((scb->flags & SCB_ACTIVE) == 0)
- printf("Inactive SCB in Waiting List\n");
+ printk("Inactive SCB in Waiting List\n");
ahc_done(ahc, scb);
/* FALLTHROUGH */
}
@@ -6153,7 +6147,7 @@ ahc_search_untagged_queues(struct ahc_softc *ahc, ahc_io_ctx_t ctx,
if (cstat != CAM_REQ_CMP)
ahc_freeze_scb(scb);
if ((scb->flags & SCB_ACTIVE) == 0)
- printf("Inactive SCB in untaggedQ\n");
+ printk("Inactive SCB in untaggedQ\n");
ahc_done(ahc, scb);
break;
}
@@ -6200,7 +6194,7 @@ ahc_search_disc_list(struct ahc_softc *ahc, int target, char channel,
ahc_outb(ahc, SCBPTR, next);
scb_index = ahc_inb(ahc, SCB_TAG);
if (scb_index >= ahc->scb_data->numscbs) {
- printf("Disconnected List inconsistency. "
+ printk("Disconnected List inconsistency. "
"SCB index == %d, yet numscbs == %d.",
scb_index, ahc->scb_data->numscbs);
ahc_dump_card_state(ahc);
@@ -6456,7 +6450,7 @@ ahc_abort_scbs(struct ahc_softc *ahc, int target, char channel,
if (ahc_get_transaction_status(scbp) != CAM_REQ_CMP)
ahc_freeze_scb(scbp);
if ((scbp->flags & SCB_ACTIVE) == 0)
- printf("Inactive SCB on pending list\n");
+ printk("Inactive SCB on pending list\n");
ahc_done(ahc, scbp);
found++;
}
@@ -6734,7 +6728,7 @@ ahc_calc_residual(struct ahc_softc *ahc, struct scb *scb)
#ifdef AHC_DEBUG
if ((ahc_debug & AHC_SHOW_MISC) != 0) {
ahc_print_path(ahc, scb);
- printf("Handled %sResidual of %d bytes\n",
+ printk("Handled %sResidual of %d bytes\n",
(scb->flags & SCB_SENSE) ? "Sense " : "", resid);
}
#endif
@@ -6774,7 +6768,7 @@ ahc_queue_lstate_event(struct ahc_softc *ahc, struct ahc_tmode_lstate *lstate,
if (pending == AHC_TMODE_EVENT_BUFFER_SIZE) {
xpt_print_path(lstate->path);
- printf("immediate event %x:%x lost\n",
+ printk("immediate event %x:%x lost\n",
lstate->event_buffer[lstate->event_r_idx].event_type,
lstate->event_buffer[lstate->event_r_idx].event_arg);
lstate->event_r_idx++;
@@ -6844,7 +6838,7 @@ ahc_dumpseq(struct ahc_softc* ahc)
uint8_t ins_bytes[4];
ahc_insb(ahc, SEQRAM, ins_bytes, 4);
- printf("0x%08x\n", ins_bytes[0] << 24
+ printk("0x%08x\n", ins_bytes[0] << 24
| ins_bytes[1] << 16
| ins_bytes[2] << 8
| ins_bytes[3]);
@@ -6912,7 +6906,7 @@ ahc_loadseq(struct ahc_softc *ahc)
* storage capacity for this chip. Fail
* the load.
*/
- printf("\n%s: Program too large for instruction memory "
+ printk("\n%s: Program too large for instruction memory "
"size of %d!\n", ahc_name(ahc),
ahc->instruction_ram_size);
return (ENOMEM);
@@ -6947,7 +6941,7 @@ ahc_loadseq(struct ahc_softc *ahc)
if (cs_count != 0) {
cs_count *= sizeof(struct cs);
- ahc->critical_sections = malloc(cs_count, M_DEVBUF, M_NOWAIT);
+ ahc->critical_sections = kmalloc(cs_count, GFP_ATOMIC);
if (ahc->critical_sections == NULL)
panic("ahc_loadseq: Could not malloc");
memcpy(ahc->critical_sections, cs_table, cs_count);
@@ -6955,8 +6949,8 @@ ahc_loadseq(struct ahc_softc *ahc)
ahc_outb(ahc, SEQCTL, PERRORDIS|FAILDIS|FASTMODE);
if (bootverbose) {
- printf(" %d instructions downloaded\n", downloaded);
- printf("%s: Features 0x%x, Bugs 0x%x, Flags 0x%x\n",
+ printk(" %d instructions downloaded\n", downloaded);
+ printk("%s: Features 0x%x, Bugs 0x%x, Flags 0x%x\n",
ahc_name(ahc), ahc->features, ahc->bugs, ahc->flags);
}
return (0);
@@ -7132,12 +7126,12 @@ ahc_print_register(const ahc_reg_parse_entry_t *table, u_int num_entries,
u_int printed_mask;
if (cur_column != NULL && *cur_column >= wrap_point) {
- printf("\n");
+ printk("\n");
*cur_column = 0;
}
- printed = printf("%s[0x%x]", name, value);
+ printed = printk("%s[0x%x]", name, value);
if (table == NULL) {
- printed += printf(" ");
+ printed += printk(" ");
*cur_column += printed;
return (printed);
}
@@ -7152,7 +7146,7 @@ ahc_print_register(const ahc_reg_parse_entry_t *table, u_int num_entries,
== table[entry].mask))
continue;
- printed += printf("%s%s",
+ printed += printk("%s%s",
printed_mask == 0 ? ":(" : "|",
table[entry].name);
printed_mask |= table[entry].mask;
@@ -7163,9 +7157,9 @@ ahc_print_register(const ahc_reg_parse_entry_t *table, u_int num_entries,
break;
}
if (printed_mask != 0)
- printed += printf(") ");
+ printed += printk(") ");
else
- printed += printf(" ");
+ printed += printk(" ");
if (cur_column != NULL)
*cur_column += printed;
return (printed);
@@ -7197,16 +7191,16 @@ ahc_dump_card_state(struct ahc_softc *ahc)
saved_scbptr = ahc_inb(ahc, SCBPTR);
last_phase = ahc_inb(ahc, LASTPHASE);
- printf(">>>>>>>>>>>>>>>>>> Dump Card State Begins <<<<<<<<<<<<<<<<<\n"
+ printk(">>>>>>>>>>>>>>>>>> Dump Card State Begins <<<<<<<<<<<<<<<<<\n"
"%s: Dumping Card State %s, at SEQADDR 0x%x\n",
ahc_name(ahc), ahc_lookup_phase_entry(last_phase)->phasemsg,
ahc_inb(ahc, SEQADDR0) | (ahc_inb(ahc, SEQADDR1) << 8));
if (paused)
- printf("Card was paused\n");
- printf("ACCUM = 0x%x, SINDEX = 0x%x, DINDEX = 0x%x, ARG_2 = 0x%x\n",
+ printk("Card was paused\n");
+ printk("ACCUM = 0x%x, SINDEX = 0x%x, DINDEX = 0x%x, ARG_2 = 0x%x\n",
ahc_inb(ahc, ACCUM), ahc_inb(ahc, SINDEX), ahc_inb(ahc, DINDEX),
ahc_inb(ahc, ARG_2));
- printf("HCNT = 0x%x SCBPTR = 0x%x\n", ahc_inb(ahc, HCNT),
+ printk("HCNT = 0x%x SCBPTR = 0x%x\n", ahc_inb(ahc, HCNT),
ahc_inb(ahc, SCBPTR));
cur_col = 0;
if ((ahc->features & AHC_DT) != 0)
@@ -7230,15 +7224,15 @@ ahc_dump_card_state(struct ahc_softc *ahc)
ahc_dfcntrl_print(ahc_inb(ahc, DFCNTRL), &cur_col, 50);
ahc_dfstatus_print(ahc_inb(ahc, DFSTATUS), &cur_col, 50);
if (cur_col != 0)
- printf("\n");
- printf("STACK:");
+ printk("\n");
+ printk("STACK:");
for (i = 0; i < STACK_SIZE; i++)
- printf(" 0x%x", ahc_inb(ahc, STACK)|(ahc_inb(ahc, STACK) << 8));
- printf("\nSCB count = %d\n", ahc->scb_data->numscbs);
- printf("Kernel NEXTQSCB = %d\n", ahc->next_queued_scb->hscb->tag);
- printf("Card NEXTQSCB = %d\n", ahc_inb(ahc, NEXT_QUEUED_SCB));
+ printk(" 0x%x", ahc_inb(ahc, STACK)|(ahc_inb(ahc, STACK) << 8));
+ printk("\nSCB count = %d\n", ahc->scb_data->numscbs);
+ printk("Kernel NEXTQSCB = %d\n", ahc->next_queued_scb->hscb->tag);
+ printk("Card NEXTQSCB = %d\n", ahc_inb(ahc, NEXT_QUEUED_SCB));
/* QINFIFO */
- printf("QINFIFO entries: ");
+ printk("QINFIFO entries: ");
if ((ahc->features & AHC_QUEUE_REGS) != 0) {
qinpos = ahc_inb(ahc, SNSCB_QOFF);
ahc_outb(ahc, SNSCB_QOFF, qinpos);
@@ -7246,109 +7240,109 @@ ahc_dump_card_state(struct ahc_softc *ahc)
qinpos = ahc_inb(ahc, QINPOS);
qintail = ahc->qinfifonext;
while (qinpos != qintail) {
- printf("%d ", ahc->qinfifo[qinpos]);
+ printk("%d ", ahc->qinfifo[qinpos]);
qinpos++;
}
- printf("\n");
+ printk("\n");
- printf("Waiting Queue entries: ");
+ printk("Waiting Queue entries: ");
scb_index = ahc_inb(ahc, WAITING_SCBH);
i = 0;
while (scb_index != SCB_LIST_NULL && i++ < 256) {
ahc_outb(ahc, SCBPTR, scb_index);
- printf("%d:%d ", scb_index, ahc_inb(ahc, SCB_TAG));
+ printk("%d:%d ", scb_index, ahc_inb(ahc, SCB_TAG));
scb_index = ahc_inb(ahc, SCB_NEXT);
}
- printf("\n");
+ printk("\n");
- printf("Disconnected Queue entries: ");
+ printk("Disconnected Queue entries: ");
scb_index = ahc_inb(ahc, DISCONNECTED_SCBH);
i = 0;
while (scb_index != SCB_LIST_NULL && i++ < 256) {
ahc_outb(ahc, SCBPTR, scb_index);
- printf("%d:%d ", scb_index, ahc_inb(ahc, SCB_TAG));
+ printk("%d:%d ", scb_index, ahc_inb(ahc, SCB_TAG));
scb_index = ahc_inb(ahc, SCB_NEXT);
}
- printf("\n");
+ printk("\n");
ahc_sync_qoutfifo(ahc, BUS_DMASYNC_POSTREAD);
- printf("QOUTFIFO entries: ");
+ printk("QOUTFIFO entries: ");
qoutpos = ahc->qoutfifonext;
i = 0;
while (ahc->qoutfifo[qoutpos] != SCB_LIST_NULL && i++ < 256) {
- printf("%d ", ahc->qoutfifo[qoutpos]);
+ printk("%d ", ahc->qoutfifo[qoutpos]);
qoutpos++;
}
- printf("\n");
+ printk("\n");
- printf("Sequencer Free SCB List: ");
+ printk("Sequencer Free SCB List: ");
scb_index = ahc_inb(ahc, FREE_SCBH);
i = 0;
while (scb_index != SCB_LIST_NULL && i++ < 256) {
ahc_outb(ahc, SCBPTR, scb_index);
- printf("%d ", scb_index);
+ printk("%d ", scb_index);
scb_index = ahc_inb(ahc, SCB_NEXT);
}
- printf("\n");
+ printk("\n");
- printf("Sequencer SCB Info: ");
+ printk("Sequencer SCB Info: ");
for (i = 0; i < ahc->scb_data->maxhscbs; i++) {
ahc_outb(ahc, SCBPTR, i);
- cur_col = printf("\n%3d ", i);
+ cur_col = printk("\n%3d ", i);
ahc_scb_control_print(ahc_inb(ahc, SCB_CONTROL), &cur_col, 60);
ahc_scb_scsiid_print(ahc_inb(ahc, SCB_SCSIID), &cur_col, 60);
ahc_scb_lun_print(ahc_inb(ahc, SCB_LUN), &cur_col, 60);
ahc_scb_tag_print(ahc_inb(ahc, SCB_TAG), &cur_col, 60);
}
- printf("\n");
+ printk("\n");
- printf("Pending list: ");
+ printk("Pending list: ");
i = 0;
LIST_FOREACH(scb, &ahc->pending_scbs, pending_links) {
if (i++ > 256)
break;
- cur_col = printf("\n%3d ", scb->hscb->tag);
+ cur_col = printk("\n%3d ", scb->hscb->tag);
ahc_scb_control_print(scb->hscb->control, &cur_col, 60);
ahc_scb_scsiid_print(scb->hscb->scsiid, &cur_col, 60);
ahc_scb_lun_print(scb->hscb->lun, &cur_col, 60);
if ((ahc->flags & AHC_PAGESCBS) == 0) {
ahc_outb(ahc, SCBPTR, scb->hscb->tag);
- printf("(");
+ printk("(");
ahc_scb_control_print(ahc_inb(ahc, SCB_CONTROL),
&cur_col, 60);
ahc_scb_tag_print(ahc_inb(ahc, SCB_TAG), &cur_col, 60);
- printf(")");
+ printk(")");
}
}
- printf("\n");
+ printk("\n");
- printf("Kernel Free SCB list: ");
+ printk("Kernel Free SCB list: ");
i = 0;
SLIST_FOREACH(scb, &ahc->scb_data->free_scbs, links.sle) {
if (i++ > 256)
break;
- printf("%d ", scb->hscb->tag);
+ printk("%d ", scb->hscb->tag);
}
- printf("\n");
+ printk("\n");
maxtarget = (ahc->features & (AHC_WIDE|AHC_TWIN)) ? 15 : 7;
for (target = 0; target <= maxtarget; target++) {
untagged_q = &ahc->untagged_queues[target];
if (TAILQ_FIRST(untagged_q) == NULL)
continue;
- printf("Untagged Q(%d): ", target);
+ printk("Untagged Q(%d): ", target);
i = 0;
TAILQ_FOREACH(scb, untagged_q, links.tqe) {
if (i++ > 256)
break;
- printf("%d ", scb->hscb->tag);
+ printk("%d ", scb->hscb->tag);
}
- printf("\n");
+ printk("\n");
}
ahc_platform_dump_card_state(ahc);
- printf("\n<<<<<<<<<<<<<<<<< Dump Card State Ends >>>>>>>>>>>>>>>>>>\n");
+ printk("\n<<<<<<<<<<<<<<<<< Dump Card State Ends >>>>>>>>>>>>>>>>>>\n");
ahc_outb(ahc, SCBPTR, saved_scbptr);
if (paused == 0)
ahc_unpause(ahc);
@@ -7489,7 +7483,7 @@ ahc_handle_en_lun(struct ahc_softc *ahc, struct cam_sim *sim, union ccb *ccb)
u_long s;
ahc_flag saved_flags;
- printf("Configuring Target Mode\n");
+ printk("Configuring Target Mode\n");
ahc_lock(ahc, &s);
if (LIST_FIRST(&ahc->pending_scbs) != NULL) {
ccb->ccb_h.status = CAM_BUSY;
@@ -7535,7 +7529,7 @@ ahc_handle_en_lun(struct ahc_softc *ahc, struct cam_sim *sim, union ccb *ccb)
/* Are we already enabled?? */
if (lstate != NULL) {
xpt_print_path(ccb->ccb_h.path);
- printf("Lun already enabled\n");
+ printk("Lun already enabled\n");
ccb->ccb_h.status = CAM_LUN_ALRDY_ENA;
return;
}
@@ -7547,7 +7541,7 @@ ahc_handle_en_lun(struct ahc_softc *ahc, struct cam_sim *sim, union ccb *ccb)
* specific commands.
*/
ccb->ccb_h.status = CAM_REQ_INVALID;
- printf("Non-zero Group Codes\n");
+ printk("Non-zero Group Codes\n");
return;
}
@@ -7559,15 +7553,15 @@ ahc_handle_en_lun(struct ahc_softc *ahc, struct cam_sim *sim, union ccb *ccb)
tstate = ahc_alloc_tstate(ahc, target, channel);
if (tstate == NULL) {
xpt_print_path(ccb->ccb_h.path);
- printf("Couldn't allocate tstate\n");
+ printk("Couldn't allocate tstate\n");
ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
return;
}
}
- lstate = malloc(sizeof(*lstate), M_DEVBUF, M_NOWAIT);
+ lstate = kmalloc(sizeof(*lstate), GFP_ATOMIC);
if (lstate == NULL) {
xpt_print_path(ccb->ccb_h.path);
- printf("Couldn't allocate lstate\n");
+ printk("Couldn't allocate lstate\n");
ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
return;
}
@@ -7577,9 +7571,9 @@ ahc_handle_en_lun(struct ahc_softc *ahc, struct cam_sim *sim, union ccb *ccb)
xpt_path_target_id(ccb->ccb_h.path),
xpt_path_lun_id(ccb->ccb_h.path));
if (status != CAM_REQ_CMP) {
- free(lstate, M_DEVBUF);
+ kfree(lstate);
xpt_print_path(ccb->ccb_h.path);
- printf("Couldn't allocate path\n");
+ printk("Couldn't allocate path\n");
ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
return;
}
@@ -7654,7 +7648,7 @@ ahc_handle_en_lun(struct ahc_softc *ahc, struct cam_sim *sim, union ccb *ccb)
ahc_unlock(ahc, &s);
ccb->ccb_h.status = CAM_REQ_CMP;
xpt_print_path(ccb->ccb_h.path);
- printf("Lun now enabled for target mode\n");
+ printk("Lun now enabled for target mode\n");
} else {
struct scb *scb;
int i, empty;
@@ -7673,7 +7667,7 @@ ahc_handle_en_lun(struct ahc_softc *ahc, struct cam_sim *sim, union ccb *ccb)
ccbh = &scb->io_ctx->ccb_h;
if (ccbh->func_code == XPT_CONT_TARGET_IO
&& !xpt_path_comp(ccbh->path, ccb->ccb_h.path)){
- printf("CTIO pending\n");
+ printk("CTIO pending\n");
ccb->ccb_h.status = CAM_REQ_INVALID;
ahc_unlock(ahc, &s);
return;
@@ -7681,12 +7675,12 @@ ahc_handle_en_lun(struct ahc_softc *ahc, struct cam_sim *sim, union ccb *ccb)
}
if (SLIST_FIRST(&lstate->accept_tios) != NULL) {
- printf("ATIOs pending\n");
+ printk("ATIOs pending\n");
ccb->ccb_h.status = CAM_REQ_INVALID;
}
if (SLIST_FIRST(&lstate->immed_notifies) != NULL) {
- printf("INOTs pending\n");
+ printk("INOTs pending\n");
ccb->ccb_h.status = CAM_REQ_INVALID;
}
@@ -7696,9 +7690,9 @@ ahc_handle_en_lun(struct ahc_softc *ahc, struct cam_sim *sim, union ccb *ccb)
}
xpt_print_path(ccb->ccb_h.path);
- printf("Target mode disabled\n");
+ printk("Target mode disabled\n");
xpt_free_path(lstate->path);
- free(lstate, M_DEVBUF);
+ kfree(lstate);
ahc_pause(ahc);
/* Can we clean up the target too? */
@@ -7750,7 +7744,7 @@ ahc_handle_en_lun(struct ahc_softc *ahc, struct cam_sim *sim, union ccb *ccb)
ahc_outb(ahc, SCSISEQ, scsiseq);
if ((ahc->features & AHC_MULTIROLE) == 0) {
- printf("Configuring Initiator Mode\n");
+ printk("Configuring Initiator Mode\n");
ahc->flags &= ~AHC_TARGETROLE;
ahc->flags |= AHC_INITIATORROLE;
/*
@@ -7897,12 +7891,12 @@ ahc_handle_target_cmd(struct ahc_softc *ahc, struct target_cmd *cmd)
* Wait for more ATIOs from the peripheral driver for this lun.
*/
if (bootverbose)
- printf("%s: ATIOs exhausted\n", ahc_name(ahc));
+ printk("%s: ATIOs exhausted\n", ahc_name(ahc));
return (1);
} else
ahc->flags &= ~AHC_TQINFIFO_BLOCKED;
#if 0
- printf("Incoming command from %d for %d:%d%s\n",
+ printk("Incoming command from %d for %d:%d%s\n",
initiator, target, lun,
lstate == ahc->black_hole ? "(Black Holed)" : "");
#endif
@@ -7949,7 +7943,7 @@ ahc_handle_target_cmd(struct ahc_softc *ahc, struct target_cmd *cmd)
default:
/* Only copy the opcode. */
atio->cdb_len = 1;
- printf("Reserved or VU command code type encountered\n");
+ printk("Reserved or VU command code type encountered\n");
break;
}
@@ -7965,7 +7959,7 @@ ahc_handle_target_cmd(struct ahc_softc *ahc, struct target_cmd *cmd)
* to this accept tio.
*/
#if 0
- printf("Received Immediate Command %d:%d:%d - %p\n",
+ printk("Received Immediate Command %d:%d:%d - %p\n",
initiator, target, lun, ahc->pending_device);
#endif
ahc->pending_device = lstate;
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c
index 5e42dac2350..aeea7a61478 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_osm.c
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c
@@ -653,7 +653,7 @@ ahc_linux_slave_alloc(struct scsi_device *sdev)
struct ahc_linux_device *dev;
if (bootverbose)
- printf("%s: Slave Alloc %d\n", ahc_name(ahc), sdev->id);
+ printk("%s: Slave Alloc %d\n", ahc_name(ahc), sdev->id);
dev = scsi_transport_device_data(sdev);
memset(dev, 0, sizeof(*dev));
@@ -755,7 +755,7 @@ ahc_linux_abort(struct scsi_cmnd *cmd)
error = ahc_linux_queue_recovery_cmd(cmd, SCB_ABORT);
if (error != 0)
- printf("aic7xxx_abort returns 0x%x\n", error);
+ printk("aic7xxx_abort returns 0x%x\n", error);
return (error);
}
@@ -769,7 +769,7 @@ ahc_linux_dev_reset(struct scsi_cmnd *cmd)
error = ahc_linux_queue_recovery_cmd(cmd, SCB_DEVICE_RESET);
if (error != 0)
- printf("aic7xxx_dev_reset returns 0x%x\n", error);
+ printk("aic7xxx_dev_reset returns 0x%x\n", error);
return (error);
}
@@ -791,7 +791,7 @@ ahc_linux_bus_reset(struct scsi_cmnd *cmd)
ahc_unlock(ahc, &flags);
if (bootverbose)
- printf("%s: SCSI bus reset delivered. "
+ printk("%s: SCSI bus reset delivered. "
"%d SCBs aborted.\n", ahc_name(ahc), found);
return SUCCESS;
@@ -840,7 +840,7 @@ ahc_dma_tag_create(struct ahc_softc *ahc, bus_dma_tag_t parent,
{
bus_dma_tag_t dmat;
- dmat = malloc(sizeof(*dmat), M_DEVBUF, M_NOWAIT);
+ dmat = kmalloc(sizeof(*dmat), GFP_ATOMIC);
if (dmat == NULL)
return (ENOMEM);
@@ -861,7 +861,7 @@ ahc_dma_tag_create(struct ahc_softc *ahc, bus_dma_tag_t parent,
void
ahc_dma_tag_destroy(struct ahc_softc *ahc, bus_dma_tag_t dmat)
{
- free(dmat, M_DEVBUF);
+ kfree(dmat);
}
int
@@ -918,7 +918,7 @@ ahc_linux_setup_tag_info_global(char *p)
int tags, i, j;
tags = simple_strtoul(p + 1, NULL, 0) & 0xff;
- printf("Setting Global Tags= %d\n", tags);
+ printk("Setting Global Tags= %d\n", tags);
for (i = 0; i < ARRAY_SIZE(aic7xxx_tag_info); i++) {
for (j = 0; j < AHC_NUM_TARGETS; j++) {
@@ -936,7 +936,7 @@ ahc_linux_setup_tag_info(u_long arg, int instance, int targ, int32_t value)
&& (targ < AHC_NUM_TARGETS)) {
aic7xxx_tag_info[instance].tag_commands[targ] = value & 0xff;
if (bootverbose)
- printf("tag_info[%d:%d] = %d\n", instance, targ, value);
+ printk("tag_info[%d:%d] = %d\n", instance, targ, value);
}
}
@@ -977,7 +977,7 @@ ahc_parse_brace_option(char *opt_name, char *opt_arg, char *end, int depth,
if (targ == -1)
targ = 0;
} else {
- printf("Malformed Option %s\n",
+ printk("Malformed Option %s\n",
opt_name);
done = TRUE;
}
@@ -1120,7 +1120,7 @@ ahc_linux_register_host(struct ahc_softc *ahc, struct scsi_host_template *templa
ahc_set_unit(ahc, ahc_linux_unit++);
ahc_unlock(ahc, &s);
sprintf(buf, "scsi%d", host->host_no);
- new_name = malloc(strlen(buf) + 1, M_DEVBUF, M_NOWAIT);
+ new_name = kmalloc(strlen(buf) + 1, GFP_ATOMIC);
if (new_name != NULL) {
strcpy(new_name, buf);
ahc_set_name(ahc, new_name);
@@ -1220,7 +1220,7 @@ ahc_platform_alloc(struct ahc_softc *ahc, void *platform_arg)
{
ahc->platform_data =
- malloc(sizeof(struct ahc_platform_data), M_DEVBUF, M_NOWAIT);
+ kmalloc(sizeof(struct ahc_platform_data), GFP_ATOMIC);
if (ahc->platform_data == NULL)
return (ENOMEM);
memset(ahc->platform_data, 0, sizeof(struct ahc_platform_data));
@@ -1264,7 +1264,7 @@ ahc_platform_free(struct ahc_softc *ahc)
if (ahc->platform_data->host)
scsi_host_put(ahc->platform_data->host);
- free(ahc->platform_data, M_DEVBUF);
+ kfree(ahc->platform_data);
}
}
@@ -1378,7 +1378,7 @@ ahc_linux_user_tagdepth(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
if (ahc->unit >= ARRAY_SIZE(aic7xxx_tag_info)) {
if (warned_user == 0) {
- printf(KERN_WARNING
+ printk(KERN_WARNING
"aic7xxx: WARNING: Insufficient tag_info instances\n"
"aic7xxx: for installed controllers. Using defaults\n"
"aic7xxx: Please update the aic7xxx_tag_info array in\n"
@@ -1421,7 +1421,7 @@ ahc_linux_device_queue_depth(struct scsi_device *sdev)
ahc_send_async(ahc, devinfo.channel, devinfo.target,
devinfo.lun, AC_TRANSFER_NEG);
ahc_print_devinfo(ahc, &devinfo);
- printf("Tagged Queuing enabled. Depth %d\n", tags);
+ printk("Tagged Queuing enabled. Depth %d\n", tags);
} else {
ahc_platform_set_tags(ahc, sdev, &devinfo, AHC_QUEUE_NONE);
ahc_send_async(ahc, devinfo.channel, devinfo.target,
@@ -1735,7 +1735,7 @@ ahc_done(struct ahc_softc *ahc, struct scb *scb)
* not have been dispatched to the controller, so
* only check the SCB_ACTIVE flag for tagged transactions.
*/
- printf("SCB %d done'd twice\n", scb->hscb->tag);
+ printk("SCB %d done'd twice\n", scb->hscb->tag);
ahc_dump_card_state(ahc);
panic("Stopping for safety");
}
@@ -1765,7 +1765,7 @@ ahc_done(struct ahc_softc *ahc, struct scb *scb)
#ifdef AHC_DEBUG
if ((ahc_debug & AHC_SHOW_MISC) != 0) {
ahc_print_path(ahc, scb);
- printf("Set CAM_UNCOR_PARITY\n");
+ printk("Set CAM_UNCOR_PARITY\n");
}
#endif
ahc_set_transaction_status(scb, CAM_UNCOR_PARITY);
@@ -1783,12 +1783,12 @@ ahc_done(struct ahc_softc *ahc, struct scb *scb)
u_int i;
ahc_print_path(ahc, scb);
- printf("CDB:");
+ printk("CDB:");
for (i = 0; i < scb->io_ctx->cmd_len; i++)
- printf(" 0x%x", scb->io_ctx->cmnd[i]);
- printf("\n");
+ printk(" 0x%x", scb->io_ctx->cmnd[i]);
+ printk("\n");
ahc_print_path(ahc, scb);
- printf("Saw underflow (%ld of %ld bytes). "
+ printk("Saw underflow (%ld of %ld bytes). "
"Treated as error\n",
ahc_get_residual(scb),
ahc_get_transfer_length(scb));
@@ -1821,7 +1821,7 @@ ahc_done(struct ahc_softc *ahc, struct scb *scb)
dev->commands_since_idle_or_otag = 0;
if ((scb->flags & SCB_RECOVERY_SCB) != 0) {
- printf("Recovery SCB completes\n");
+ printk("Recovery SCB completes\n");
if (ahc_get_transaction_status(scb) == CAM_BDR_SENT
|| ahc_get_transaction_status(scb) == CAM_REQ_ABORTED)
ahc_set_transaction_status(scb, CAM_CMD_TIMEOUT);
@@ -1886,14 +1886,14 @@ ahc_linux_handle_scsi_status(struct ahc_softc *ahc,
if (ahc_debug & AHC_SHOW_SENSE) {
int i;
- printf("Copied %d bytes of sense data:",
+ printk("Copied %d bytes of sense data:",
sense_size);
for (i = 0; i < sense_size; i++) {
if ((i & 0xF) == 0)
- printf("\n");
- printf("0x%x ", cmd->sense_buffer[i]);
+ printk("\n");
+ printk("0x%x ", cmd->sense_buffer[i]);
}
- printf("\n");
+ printk("\n");
}
#endif
}
@@ -1918,7 +1918,7 @@ ahc_linux_handle_scsi_status(struct ahc_softc *ahc,
dev->openings = 0;
/*
ahc_print_path(ahc, scb);
- printf("Dropping tag count to %d\n", dev->active);
+ printk("Dropping tag count to %d\n", dev->active);
*/
if (dev->active == dev->tags_on_last_queuefull) {
@@ -1935,7 +1935,7 @@ ahc_linux_handle_scsi_status(struct ahc_softc *ahc,
== AHC_LOCK_TAGS_COUNT) {
dev->maxtags = dev->active;
ahc_print_path(ahc, scb);
- printf("Locking max tag count at %d\n",
+ printk("Locking max tag count at %d\n",
dev->active);
}
} else {
@@ -2100,10 +2100,10 @@ ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
scmd_printk(KERN_INFO, cmd, "Attempting to queue a%s message\n",
flag == SCB_ABORT ? "n ABORT" : " TARGET RESET");
- printf("CDB:");
+ printk("CDB:");
for (cdb_byte = 0; cdb_byte < cmd->cmd_len; cdb_byte++)
- printf(" 0x%x", cmd->cmnd[cdb_byte]);
- printf("\n");
+ printk(" 0x%x", cmd->cmnd[cdb_byte]);
+ printk("\n");
ahc_lock(ahc, &flags);
@@ -2121,7 +2121,7 @@ ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
* No target device for this command exists,
* so we must not still own the command.
*/
- printf("%s:%d:%d:%d: Is not an active device\n",
+ printk("%s:%d:%d:%d: Is not an active device\n",
ahc_name(ahc), cmd->device->channel, cmd->device->id,
cmd->device->lun);
retval = SUCCESS;
@@ -2133,7 +2133,7 @@ ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
cmd->device->channel + 'A',
cmd->device->lun,
CAM_REQ_ABORTED, SEARCH_COMPLETE) != 0) {
- printf("%s:%d:%d:%d: Command found on untagged queue\n",
+ printk("%s:%d:%d:%d: Command found on untagged queue\n",
ahc_name(ahc), cmd->device->channel, cmd->device->id,
cmd->device->lun);
retval = SUCCESS;
@@ -2187,7 +2187,7 @@ ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
goto no_cmd;
}
- printf("%s: At time of recovery, card was %spaused\n",
+ printk("%s: At time of recovery, card was %spaused\n",
ahc_name(ahc), was_paused ? "" : "not ");
ahc_dump_card_state(ahc);
@@ -2199,7 +2199,7 @@ ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
pending_scb->hscb->tag,
ROLE_INITIATOR, CAM_REQ_ABORTED,
SEARCH_COMPLETE) > 0) {
- printf("%s:%d:%d:%d: Cmd aborted from QINFIFO\n",
+ printk("%s:%d:%d:%d: Cmd aborted from QINFIFO\n",
ahc_name(ahc), cmd->device->channel,
cmd->device->id, cmd->device->lun);
retval = SUCCESS;
@@ -2313,7 +2313,7 @@ ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
ahc_qinfifo_requeue_tail(ahc, pending_scb);
ahc_outb(ahc, SCBPTR, saved_scbptr);
ahc_print_path(ahc, pending_scb);
- printf("Device is disconnected, re-queuing SCB\n");
+ printk("Device is disconnected, re-queuing SCB\n");
wait = TRUE;
} else {
scmd_printk(KERN_INFO, cmd, "Unable to deliver message\n");
@@ -2338,16 +2338,16 @@ done:
ahc->platform_data->eh_done = &done;
ahc_unlock(ahc, &flags);
- printf("Recovery code sleeping\n");
+ printk("Recovery code sleeping\n");
if (!wait_for_completion_timeout(&done, 5 * HZ)) {
ahc_lock(ahc, &flags);
ahc->platform_data->eh_done = NULL;
ahc_unlock(ahc, &flags);
- printf("Timer Expired\n");
+ printk("Timer Expired\n");
retval = FAILED;
}
- printf("Recovery code awake\n");
+ printk("Recovery code awake\n");
} else
ahc_unlock(ahc, &flags);
return (retval);
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.h b/drivers/scsi/aic7xxx/aic7xxx_osm.h
index 56f07e527b4..bca0fb83f55 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_osm.h
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm.h
@@ -368,13 +368,6 @@ struct ahc_platform_data {
resource_size_t mem_busaddr; /* Mem Base Addr */
};
-/************************** OS Utility Wrappers *******************************/
-#define printf printk
-#define M_NOWAIT GFP_ATOMIC
-#define M_WAITOK 0
-#define malloc(size, type, flags) kmalloc(size, flags)
-#define free(ptr, type) kfree(ptr)
-
void ahc_delay(long);
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c b/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c
index 78fc70c24e0..ee05e841075 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c
@@ -225,7 +225,7 @@ ahc_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
ahc_get_pci_bus(pci),
ahc_get_pci_slot(pci),
ahc_get_pci_function(pci));
- name = malloc(strlen(buf) + 1, M_DEVBUF, M_NOWAIT);
+ name = kmalloc(strlen(buf) + 1, GFP_ATOMIC);
if (name == NULL)
return (-ENOMEM);
strcpy(name, buf);
@@ -412,7 +412,7 @@ ahc_pci_map_registers(struct ahc_softc *ahc)
*/
if (ahc_pci_test_register_access(ahc) != 0) {
- printf("aic7xxx: PCI Device %d:%d:%d "
+ printk("aic7xxx: PCI Device %d:%d:%d "
"failed memory mapped test. Using PIO.\n",
ahc_get_pci_bus(ahc->dev_softc),
ahc_get_pci_slot(ahc->dev_softc),
@@ -425,7 +425,7 @@ ahc_pci_map_registers(struct ahc_softc *ahc)
} else
command |= PCIM_CMD_MEMEN;
} else {
- printf("aic7xxx: PCI%d:%d:%d MEM region 0x%llx "
+ printk("aic7xxx: PCI%d:%d:%d MEM region 0x%llx "
"unavailable. Cannot memory map device.\n",
ahc_get_pci_bus(ahc->dev_softc),
ahc_get_pci_slot(ahc->dev_softc),
@@ -444,7 +444,7 @@ ahc_pci_map_registers(struct ahc_softc *ahc)
ahc->bsh.ioport = (u_long)base;
command |= PCIM_CMD_PORTEN;
} else {
- printf("aic7xxx: PCI%d:%d:%d IO region 0x%llx[0..255] "
+ printk("aic7xxx: PCI%d:%d:%d IO region 0x%llx[0..255] "
"unavailable. Cannot map device.\n",
ahc_get_pci_bus(ahc->dev_softc),
ahc_get_pci_slot(ahc->dev_softc),
diff --git a/drivers/scsi/aic7xxx/aic7xxx_pci.c b/drivers/scsi/aic7xxx/aic7xxx_pci.c
index 27014b9de12..2b11a427236 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_pci.c
+++ b/drivers/scsi/aic7xxx/aic7xxx_pci.c
@@ -752,7 +752,7 @@ ahc_pci_config(struct ahc_softc *ahc, const struct ahc_pci_identity *entry)
if ((ahc->flags & AHC_39BIT_ADDRESSING) != 0) {
if (bootverbose)
- printf("%s: Enabling 39Bit Addressing\n",
+ printk("%s: Enabling 39Bit Addressing\n",
ahc_name(ahc));
devconfig |= DACEN;
}
@@ -896,7 +896,7 @@ ahc_pci_config(struct ahc_softc *ahc, const struct ahc_pci_identity *entry)
/* See if someone else set us up already */
if ((ahc->flags & AHC_NO_BIOS_INIT) == 0
&& scsiseq != 0) {
- printf("%s: Using left over BIOS settings\n",
+ printk("%s: Using left over BIOS settings\n",
ahc_name(ahc));
ahc->flags &= ~AHC_USEDEFAULTS;
ahc->flags |= AHC_BIOS_ENABLED;
@@ -1155,7 +1155,7 @@ done:
ahc_outb(ahc, CLRINT, CLRPARERR);
ahc_outb(ahc, CLRINT, CLRBRKADRINT);
if (bootverbose && enable) {
- printf("%s: External SRAM, %s access%s, %dbytes/SCB\n",
+ printk("%s: External SRAM, %s access%s, %dbytes/SCB\n",
ahc_name(ahc), fast ? "fast" : "slow",
pcheck ? ", parity checking enabled" : "",
large ? 64 : 32);
@@ -1292,7 +1292,7 @@ check_extport(struct ahc_softc *ahc, u_int *sxfrctl1)
if (have_seeprom) {
if (bootverbose)
- printf("%s: Reading SEEPROM...", ahc_name(ahc));
+ printk("%s: Reading SEEPROM...", ahc_name(ahc));
for (;;) {
u_int start_addr;
@@ -1309,9 +1309,9 @@ check_extport(struct ahc_softc *ahc, u_int *sxfrctl1)
if (have_seeprom != 0 || sd.sd_chip == C56_66) {
if (bootverbose) {
if (have_seeprom == 0)
- printf ("checksum error\n");
+ printk ("checksum error\n");
else
- printf ("done.\n");
+ printk ("done.\n");
}
break;
}
@@ -1362,9 +1362,9 @@ check_extport(struct ahc_softc *ahc, u_int *sxfrctl1)
if (!have_seeprom) {
if (bootverbose)
- printf("%s: No SEEPROM available.\n", ahc_name(ahc));
+ printk("%s: No SEEPROM available.\n", ahc_name(ahc));
ahc->flags |= AHC_USEDEFAULTS;
- free(ahc->seep_config, M_DEVBUF);
+ kfree(ahc->seep_config);
ahc->seep_config = NULL;
sc = NULL;
} else {
@@ -1399,7 +1399,7 @@ check_extport(struct ahc_softc *ahc, u_int *sxfrctl1)
if ((sc->adapter_control & CFSTERM) != 0)
*sxfrctl1 |= STPWEN;
if (bootverbose)
- printf("%s: Low byte termination %sabled\n",
+ printk("%s: Low byte termination %sabled\n",
ahc_name(ahc),
(*sxfrctl1 & STPWEN) ? "en" : "dis");
}
@@ -1569,7 +1569,7 @@ configure_termination(struct ahc_softc *ahc,
&eeprom_present);
if ((adapter_control & CFSEAUTOTERM) == 0) {
if (bootverbose)
- printf("%s: Manual SE Termination\n",
+ printk("%s: Manual SE Termination\n",
ahc_name(ahc));
enableSEC_low = (adapter_control & CFSELOWTERM);
enableSEC_high =
@@ -1577,7 +1577,7 @@ configure_termination(struct ahc_softc *ahc,
}
if ((adapter_control & CFAUTOTERM) == 0) {
if (bootverbose)
- printf("%s: Manual LVD Termination\n",
+ printk("%s: Manual LVD Termination\n",
ahc_name(ahc));
enablePRI_low = (adapter_control & CFSTERM);
enablePRI_high = (adapter_control & CFWSTERM);
@@ -1604,19 +1604,19 @@ configure_termination(struct ahc_softc *ahc,
if (bootverbose
&& (ahc->features & AHC_ULTRA2) == 0) {
- printf("%s: internal 50 cable %s present",
+ printk("%s: internal 50 cable %s present",
ahc_name(ahc),
internal50_present ? "is":"not");
if ((ahc->features & AHC_WIDE) != 0)
- printf(", internal 68 cable %s present",
+ printk(", internal 68 cable %s present",
internal68_present ? "is":"not");
- printf("\n%s: external cable %s present\n",
+ printk("\n%s: external cable %s present\n",
ahc_name(ahc),
externalcable_present ? "is":"not");
}
if (bootverbose)
- printf("%s: BIOS eeprom %s present\n",
+ printk("%s: BIOS eeprom %s present\n",
ahc_name(ahc), eeprom_present ? "is" : "not");
if ((ahc->flags & AHC_INT50_SPEEDFLEX) != 0) {
@@ -1642,7 +1642,7 @@ configure_termination(struct ahc_softc *ahc,
&& (internal50_present != 0)
&& (internal68_present != 0)
&& (externalcable_present != 0)) {
- printf("%s: Illegal cable configuration!!. "
+ printk("%s: Illegal cable configuration!!. "
"Only two connectors on the "
"adapter may be used at a "
"time!\n", ahc_name(ahc));
@@ -1664,10 +1664,10 @@ configure_termination(struct ahc_softc *ahc,
brddat |= BRDDAT6;
if (bootverbose) {
if ((ahc->flags & AHC_INT50_SPEEDFLEX) != 0)
- printf("%s: 68 pin termination "
+ printk("%s: 68 pin termination "
"Enabled\n", ahc_name(ahc));
else
- printf("%s: %sHigh byte termination "
+ printk("%s: %sHigh byte termination "
"Enabled\n", ahc_name(ahc),
enableSEC_high ? "Secondary "
: "");
@@ -1683,10 +1683,10 @@ configure_termination(struct ahc_softc *ahc,
*sxfrctl1 |= STPWEN;
if (bootverbose) {
if ((ahc->flags & AHC_INT50_SPEEDFLEX) != 0)
- printf("%s: 50 pin termination "
+ printk("%s: 50 pin termination "
"Enabled\n", ahc_name(ahc));
else
- printf("%s: %sLow byte termination "
+ printk("%s: %sLow byte termination "
"Enabled\n", ahc_name(ahc),
enableSEC_low ? "Secondary "
: "");
@@ -1696,7 +1696,7 @@ configure_termination(struct ahc_softc *ahc,
if (enablePRI_low != 0) {
*sxfrctl1 |= STPWEN;
if (bootverbose)
- printf("%s: Primary Low Byte termination "
+ printk("%s: Primary Low Byte termination "
"Enabled\n", ahc_name(ahc));
}
@@ -1709,7 +1709,7 @@ configure_termination(struct ahc_softc *ahc,
if (enablePRI_high != 0) {
brddat |= BRDDAT4;
if (bootverbose)
- printf("%s: Primary High Byte "
+ printk("%s: Primary High Byte "
"termination Enabled\n",
ahc_name(ahc));
}
@@ -1721,7 +1721,7 @@ configure_termination(struct ahc_softc *ahc,
*sxfrctl1 |= STPWEN;
if (bootverbose)
- printf("%s: %sLow byte termination Enabled\n",
+ printk("%s: %sLow byte termination Enabled\n",
ahc_name(ahc),
(ahc->features & AHC_ULTRA2) ? "Primary "
: "");
@@ -1731,7 +1731,7 @@ configure_termination(struct ahc_softc *ahc,
&& (ahc->features & AHC_WIDE) != 0) {
brddat |= BRDDAT6;
if (bootverbose)
- printf("%s: %sHigh byte termination Enabled\n",
+ printk("%s: %sHigh byte termination Enabled\n",
ahc_name(ahc),
(ahc->features & AHC_ULTRA2)
? "Secondary " : "");
@@ -1937,29 +1937,29 @@ ahc_pci_intr(struct ahc_softc *ahc)
status1 = ahc_pci_read_config(ahc->dev_softc,
PCIR_STATUS + 1, /*bytes*/1);
- printf("%s: PCI error Interrupt at seqaddr = 0x%x\n",
+ printk("%s: PCI error Interrupt at seqaddr = 0x%x\n",
ahc_name(ahc),
ahc_inb(ahc, SEQADDR0) | (ahc_inb(ahc, SEQADDR1) << 8));
if (status1 & DPE) {
ahc->pci_target_perr_count++;
- printf("%s: Data Parity Error Detected during address "
+ printk("%s: Data Parity Error Detected during address "
"or write data phase\n", ahc_name(ahc));
}
if (status1 & SSE) {
- printf("%s: Signal System Error Detected\n", ahc_name(ahc));
+ printk("%s: Signal System Error Detected\n", ahc_name(ahc));
}
if (status1 & RMA) {
- printf("%s: Received a Master Abort\n", ahc_name(ahc));
+ printk("%s: Received a Master Abort\n", ahc_name(ahc));
}
if (status1 & RTA) {
- printf("%s: Received a Target Abort\n", ahc_name(ahc));
+ printk("%s: Received a Target Abort\n", ahc_name(ahc));
}
if (status1 & STA) {
- printf("%s: Signaled a Target Abort\n", ahc_name(ahc));
+ printk("%s: Signaled a Target Abort\n", ahc_name(ahc));
}
if (status1 & DPR) {
- printf("%s: Data Parity Error has been reported via PERR#\n",
+ printk("%s: Data Parity Error has been reported via PERR#\n",
ahc_name(ahc));
}
@@ -1968,14 +1968,14 @@ ahc_pci_intr(struct ahc_softc *ahc)
status1, /*bytes*/1);
if ((status1 & (DPE|SSE|RMA|RTA|STA|DPR)) == 0) {
- printf("%s: Latched PCIERR interrupt with "
+ printk("%s: Latched PCIERR interrupt with "
"no status bits set\n", ahc_name(ahc));
} else {
ahc_outb(ahc, CLRINT, CLRPARERR);
}
if (ahc->pci_target_perr_count > AHC_PCI_TARGET_PERR_THRESH) {
- printf(
+ printk(
"%s: WARNING WARNING WARNING WARNING\n"
"%s: Too many PCI parity errors observed as a target.\n"
"%s: Some device on this bus is generating bad parity.\n"
@@ -2386,7 +2386,7 @@ ahc_aha29160C_setup(struct ahc_softc *ahc)
static int
ahc_raid_setup(struct ahc_softc *ahc)
{
- printf("RAID functionality unsupported\n");
+ printk("RAID functionality unsupported\n");
return (ENXIO);
}
@@ -2404,7 +2404,7 @@ ahc_aha394XX_setup(struct ahc_softc *ahc)
ahc->channel = 'B';
break;
default:
- printf("adapter at unexpected slot %d\n"
+ printk("adapter at unexpected slot %d\n"
"unable to map to a channel\n",
ahc_get_pci_slot(pci));
ahc->channel = 'A';
@@ -2429,7 +2429,7 @@ ahc_aha398XX_setup(struct ahc_softc *ahc)
ahc->channel = 'C';
break;
default:
- printf("adapter at unexpected slot %d\n"
+ printk("adapter at unexpected slot %d\n"
"unable to map to a channel\n",
ahc_get_pci_slot(pci));
ahc->channel = 'A';
@@ -2459,7 +2459,7 @@ ahc_aha494XX_setup(struct ahc_softc *ahc)
ahc->channel = 'D';
break;
default:
- printf("adapter at unexpected slot %d\n"
+ printk("adapter at unexpected slot %d\n"
"unable to map to a channel\n",
ahc_get_pci_slot(pci));
ahc->channel = 'A';
diff --git a/drivers/scsi/aic7xxx/aic7xxx_proc.c b/drivers/scsi/aic7xxx/aic7xxx_proc.c
index e92991a7c48..f2525f8ed1c 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_proc.c
+++ b/drivers/scsi/aic7xxx/aic7xxx_proc.c
@@ -248,13 +248,13 @@ ahc_proc_write_seeprom(struct ahc_softc *ahc, char *buffer, int length)
ahc_pause(ahc);
if (length != sizeof(struct seeprom_config)) {
- printf("ahc_proc_write_seeprom: incorrect buffer size\n");
+ printk("ahc_proc_write_seeprom: incorrect buffer size\n");
goto done;
}
have_seeprom = ahc_verify_cksum((struct seeprom_config*)buffer);
if (have_seeprom == 0) {
- printf("ahc_proc_write_seeprom: cksum verification failed\n");
+ printk("ahc_proc_write_seeprom: cksum verification failed\n");
goto done;
}
@@ -290,26 +290,25 @@ ahc_proc_write_seeprom(struct ahc_softc *ahc, char *buffer, int length)
sd.sd_DI = DI_2840;
have_seeprom = TRUE;
} else {
- printf("ahc_proc_write_seeprom: unsupported adapter type\n");
+ printk("ahc_proc_write_seeprom: unsupported adapter type\n");
goto done;
}
if (!have_seeprom) {
- printf("ahc_proc_write_seeprom: No Serial EEPROM\n");
+ printk("ahc_proc_write_seeprom: No Serial EEPROM\n");
goto done;
} else {
u_int start_addr;
if (ahc->seep_config == NULL) {
- ahc->seep_config = malloc(sizeof(*ahc->seep_config),
- M_DEVBUF, M_NOWAIT);
+ ahc->seep_config = kmalloc(sizeof(*ahc->seep_config), GFP_ATOMIC);
if (ahc->seep_config == NULL) {
- printf("aic7xxx: Unable to allocate serial "
+ printk("aic7xxx: Unable to allocate serial "
"eeprom buffer. Write failing\n");
goto done;
}
}
- printf("aic7xxx: Writing Serial EEPROM\n");
+ printk("aic7xxx: Writing Serial EEPROM\n");
start_addr = 32 * (ahc->channel - 'A');
ahc_write_seeprom(&sd, (u_int16_t *)buffer, start_addr,
sizeof(struct seeprom_config)/2);
diff --git a/drivers/scsi/aic94xx/aic94xx_task.c b/drivers/scsi/aic94xx/aic94xx_task.c
index 75d20f72501..532d212b6b2 100644
--- a/drivers/scsi/aic94xx/aic94xx_task.c
+++ b/drivers/scsi/aic94xx/aic94xx_task.c
@@ -223,7 +223,7 @@ Again:
switch (opcode) {
case TC_NO_ERROR:
ts->resp = SAS_TASK_COMPLETE;
- ts->stat = SAM_GOOD;
+ ts->stat = SAM_STAT_GOOD;
break;
case TC_UNDERRUN:
ts->resp = SAS_TASK_COMPLETE;
diff --git a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h
index ce5371b3cdd..475c31ae985 100644
--- a/drivers/scsi/arcmsr/arcmsr.h
+++ b/drivers/scsi/arcmsr/arcmsr.h
@@ -43,21 +43,27 @@
*******************************************************************************
*/
#include <linux/interrupt.h>
-
struct device_attribute;
/*The limit of outstanding scsi command that firmware can handle*/
#define ARCMSR_MAX_OUTSTANDING_CMD 256
#define ARCMSR_MAX_FREECCB_NUM 320
-#define ARCMSR_DRIVER_VERSION "Driver Version 1.20.00.15 2008/11/03"
+#define ARCMSR_DRIVER_VERSION "Driver Version 1.20.00.15 2010/02/02"
#define ARCMSR_SCSI_INITIATOR_ID 255
#define ARCMSR_MAX_XFER_SECTORS 512
#define ARCMSR_MAX_XFER_SECTORS_B 4096
+#define ARCMSR_MAX_XFER_SECTORS_C 304
#define ARCMSR_MAX_TARGETID 17
#define ARCMSR_MAX_TARGETLUN 8
#define ARCMSR_MAX_CMD_PERLUN ARCMSR_MAX_OUTSTANDING_CMD
#define ARCMSR_MAX_QBUFFER 4096
-#define ARCMSR_MAX_SG_ENTRIES 38
+#define ARCMSR_DEFAULT_SG_ENTRIES 38
#define ARCMSR_MAX_HBB_POSTQUEUE 264
+#define ARCMSR_MAX_XFER_LEN 0x26000 /* 152K */
+#define ARCMSR_CDB_SG_PAGE_LENGTH 256
+#define SCSI_CMD_ARECA_SPECIFIC 0xE1
+#ifndef PCI_DEVICE_ID_ARECA_1880
+#define PCI_DEVICE_ID_ARECA_1880 0x1880
+ #endif
/*
**********************************************************************************
**
@@ -132,35 +138,28 @@ struct CMD_MESSAGE_FIELD
#define ARCMSR_MESSAGE_FLUSH_ADAPTER_CACHE \
ARECA_SATA_RAID | FUNCTION_FLUSH_ADAPTER_CACHE
/* ARECA IOCTL ReturnCode */
-#define ARCMSR_MESSAGE_RETURNCODE_OK 0x00000001
-#define ARCMSR_MESSAGE_RETURNCODE_ERROR 0x00000006
-#define ARCMSR_MESSAGE_RETURNCODE_3F 0x0000003F
+#define ARCMSR_MESSAGE_RETURNCODE_OK 0x00000001
+#define ARCMSR_MESSAGE_RETURNCODE_ERROR 0x00000006
+#define ARCMSR_MESSAGE_RETURNCODE_3F 0x0000003F
#define ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON 0x00000088
/*
*************************************************************
** structure for holding DMA address data
*************************************************************
*/
+#define IS_DMA64 (sizeof(dma_addr_t) == 8)
#define IS_SG64_ADDR 0x01000000 /* bit24 */
struct SG32ENTRY
{
__le32 length;
__le32 address;
-};
+}__attribute__ ((packed));
struct SG64ENTRY
{
__le32 length;
__le32 address;
__le32 addresshigh;
-};
-struct SGENTRY_UNION
-{
- union
- {
- struct SG32ENTRY sg32entry;
- struct SG64ENTRY sg64entry;
- }u;
-};
+}__attribute__ ((packed));
/*
********************************************************************
** Q Buffer of IOP Message Transfer
@@ -187,6 +186,9 @@ struct FIRMWARE_INFO
char model[8]; /*15, 60-67*/
char firmware_ver[16]; /*17, 68-83*/
char device_map[16]; /*21, 84-99*/
+ uint32_t cfgVersion; /*25,100-103 Added for checking of new firmware capability*/
+ uint8_t cfgSerial[16]; /*26,104-119*/
+ uint32_t cfgPicStatus; /*30,120-123*/
};
/* signature of set and get firmware config */
#define ARCMSR_SIGNATURE_GET_CONFIG 0x87974060
@@ -210,9 +212,15 @@ struct FIRMWARE_INFO
#define ARCMSR_CCBPOST_FLAG_SGL_BSIZE 0x80000000
#define ARCMSR_CCBPOST_FLAG_IAM_BIOS 0x40000000
#define ARCMSR_CCBREPLY_FLAG_IAM_BIOS 0x40000000
-#define ARCMSR_CCBREPLY_FLAG_ERROR 0x10000000
+#define ARCMSR_CCBREPLY_FLAG_ERROR_MODE0 0x10000000
+#define ARCMSR_CCBREPLY_FLAG_ERROR_MODE1 0x00000001
/* outbound firmware ok */
#define ARCMSR_OUTBOUND_MESG1_FIRMWARE_OK 0x80000000
+/* ARC-1680 Bus Reset*/
+#define ARCMSR_ARC1680_BUS_RESET 0x00000003
+/* ARC-1880 Bus Reset*/
+#define ARCMSR_ARC1880_RESET_ADAPTER 0x00000024
+#define ARCMSR_ARC1880_DiagWrite_ENABLE 0x00000080
/*
************************************************************************
@@ -264,11 +272,66 @@ struct FIRMWARE_INFO
/* data tunnel buffer between user space program and its firmware */
/* user space data to iop 128bytes */
-#define ARCMSR_IOCTL_WBUFFER 0x0000fe00
+#define ARCMSR_MESSAGE_WBUFFER 0x0000fe00
/* iop data to user space 128bytes */
-#define ARCMSR_IOCTL_RBUFFER 0x0000ff00
+#define ARCMSR_MESSAGE_RBUFFER 0x0000ff00
/* iop message_rwbuffer for message command */
-#define ARCMSR_MSGCODE_RWBUFFER 0x0000fa00
+#define ARCMSR_MESSAGE_RWBUFFER 0x0000fa00
+/*
+************************************************************************
+** SPEC. for Areca HBC adapter
+************************************************************************
+*/
+#define ARCMSR_HBC_ISR_THROTTLING_LEVEL 12
+#define ARCMSR_HBC_ISR_MAX_DONE_QUEUE 20
+/* Host Interrupt Mask */
+#define ARCMSR_HBCMU_UTILITY_A_ISR_MASK 0x00000001 /* When clear, the Utility_A interrupt routes to the host.*/
+#define ARCMSR_HBCMU_OUTBOUND_DOORBELL_ISR_MASK 0x00000004 /* When clear, the General Outbound Doorbell interrupt routes to the host.*/
+#define ARCMSR_HBCMU_OUTBOUND_POSTQUEUE_ISR_MASK 0x00000008 /* When clear, the Outbound Post List FIFO Not Empty interrupt routes to the host.*/
+#define ARCMSR_HBCMU_ALL_INTMASKENABLE 0x0000000D /* disable all ISR */
+/* Host Interrupt Status */
+#define ARCMSR_HBCMU_UTILITY_A_ISR 0x00000001
+ /*
+ ** Set when the Utility_A Interrupt bit is set in the Outbound Doorbell Register.
+ ** It clears by writing a 1 to the Utility_A bit in the Outbound Doorbell Clear Register or through automatic clearing (if enabled).
+ */
+#define ARCMSR_HBCMU_OUTBOUND_DOORBELL_ISR 0x00000004
+ /*
+ ** Set if Outbound Doorbell register bits 30:1 have a non-zero
+ ** value. This bit clears only when Outbound Doorbell bits
+ ** 30:1 are ALL clear. Only a write to the Outbound Doorbell
+ ** Clear register clears bits in the Outbound Doorbell register.
+ */
+#define ARCMSR_HBCMU_OUTBOUND_POSTQUEUE_ISR 0x00000008
+ /*
+ ** Set whenever the Outbound Post List Producer/Consumer
+ ** Register (FIFO) is not empty. It clears when the Outbound
+ ** Post List FIFO is empty.
+ */
+#define ARCMSR_HBCMU_SAS_ALL_INT 0x00000010
+ /*
+ ** This bit indicates a SAS interrupt from a source external to
+ ** the PCIe core. This bit is not maskable.
+ */
+ /* DoorBell*/
+#define ARCMSR_HBCMU_DRV2IOP_DATA_WRITE_OK 0x00000002
+#define ARCMSR_HBCMU_DRV2IOP_DATA_READ_OK 0x00000004
+ /*inbound message 0 ready*/
+#define ARCMSR_HBCMU_DRV2IOP_MESSAGE_CMD_DONE 0x00000008
+ /*more than 12 request completed in a time*/
+#define ARCMSR_HBCMU_DRV2IOP_POSTQUEUE_THROTTLING 0x00000010
+#define ARCMSR_HBCMU_IOP2DRV_DATA_WRITE_OK 0x00000002
+ /*outbound DATA WRITE isr door bell clear*/
+#define ARCMSR_HBCMU_IOP2DRV_DATA_WRITE_DOORBELL_CLEAR 0x00000002
+#define ARCMSR_HBCMU_IOP2DRV_DATA_READ_OK 0x00000004
+ /*outbound DATA READ isr door bell clear*/
+#define ARCMSR_HBCMU_IOP2DRV_DATA_READ_DOORBELL_CLEAR 0x00000004
+ /*outbound message 0 ready*/
+#define ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE 0x00000008
+ /*outbound message cmd isr door bell clear*/
+#define ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE_DOORBELL_CLEAR 0x00000008
+ /*ARCMSR_HBAMU_MESSAGE_FIRMWARE_OK*/
+#define ARCMSR_HBCMU_MESSAGE_FIRMWARE_OK 0x80000000
/*
*******************************************************************************
** ARECA SCSI COMMAND DESCRIPTOR BLOCK size 0x1F8 (504)
@@ -290,7 +353,7 @@ struct ARCMSR_CDB
#define ARCMSR_CDB_FLAG_HEADQ 0x08
#define ARCMSR_CDB_FLAG_ORDEREDQ 0x10
- uint8_t Reserved1;
+ uint8_t msgPages;
uint32_t Context;
uint32_t DataLength;
uint8_t Cdb[16];
@@ -303,8 +366,8 @@ struct ARCMSR_CDB
uint8_t SenseData[15];
union
{
- struct SG32ENTRY sg32entry[ARCMSR_MAX_SG_ENTRIES];
- struct SG64ENTRY sg64entry[ARCMSR_MAX_SG_ENTRIES];
+ struct SG32ENTRY sg32entry[1];
+ struct SG64ENTRY sg64entry[1];
} u;
};
/*
@@ -344,15 +407,89 @@ struct MessageUnit_B
uint32_t done_qbuffer[ARCMSR_MAX_HBB_POSTQUEUE];
uint32_t postq_index;
uint32_t doneq_index;
- uint32_t __iomem *drv2iop_doorbell_reg;
- uint32_t __iomem *drv2iop_doorbell_mask_reg;
- uint32_t __iomem *iop2drv_doorbell_reg;
- uint32_t __iomem *iop2drv_doorbell_mask_reg;
- uint32_t __iomem *msgcode_rwbuffer_reg;
- uint32_t __iomem *ioctl_wbuffer_reg;
- uint32_t __iomem *ioctl_rbuffer_reg;
+ uint32_t __iomem *drv2iop_doorbell;
+ uint32_t __iomem *drv2iop_doorbell_mask;
+ uint32_t __iomem *iop2drv_doorbell;
+ uint32_t __iomem *iop2drv_doorbell_mask;
+ uint32_t __iomem *message_rwbuffer;
+ uint32_t __iomem *message_wbuffer;
+ uint32_t __iomem *message_rbuffer;
+};
+/*
+*********************************************************************
+** LSI
+*********************************************************************
+*/
+struct MessageUnit_C{
+ uint32_t message_unit_status; /*0000 0003*/
+ uint32_t slave_error_attribute; /*0004 0007*/
+ uint32_t slave_error_address; /*0008 000B*/
+ uint32_t posted_outbound_doorbell; /*000C 000F*/
+ uint32_t master_error_attribute; /*0010 0013*/
+ uint32_t master_error_address_low; /*0014 0017*/
+ uint32_t master_error_address_high; /*0018 001B*/
+ uint32_t hcb_size; /*001C 001F*/
+ uint32_t inbound_doorbell; /*0020 0023*/
+ uint32_t diagnostic_rw_data; /*0024 0027*/
+ uint32_t diagnostic_rw_address_low; /*0028 002B*/
+ uint32_t diagnostic_rw_address_high; /*002C 002F*/
+ uint32_t host_int_status; /*0030 0033*/
+ uint32_t host_int_mask; /*0034 0037*/
+ uint32_t dcr_data; /*0038 003B*/
+ uint32_t dcr_address; /*003C 003F*/
+ uint32_t inbound_queueport; /*0040 0043*/
+ uint32_t outbound_queueport; /*0044 0047*/
+ uint32_t hcb_pci_address_low; /*0048 004B*/
+ uint32_t hcb_pci_address_high; /*004C 004F*/
+ uint32_t iop_int_status; /*0050 0053*/
+ uint32_t iop_int_mask; /*0054 0057*/
+ uint32_t iop_inbound_queue_port; /*0058 005B*/
+ uint32_t iop_outbound_queue_port; /*005C 005F*/
+ uint32_t inbound_free_list_index; /*0060 0063*/
+ uint32_t inbound_post_list_index; /*0064 0067*/
+ uint32_t outbound_free_list_index; /*0068 006B*/
+ uint32_t outbound_post_list_index; /*006C 006F*/
+ uint32_t inbound_doorbell_clear; /*0070 0073*/
+ uint32_t i2o_message_unit_control; /*0074 0077*/
+ uint32_t last_used_message_source_address_low; /*0078 007B*/
+ uint32_t last_used_message_source_address_high; /*007C 007F*/
+ uint32_t pull_mode_data_byte_count[4]; /*0080 008F*/
+ uint32_t message_dest_address_index; /*0090 0093*/
+ uint32_t done_queue_not_empty_int_counter_timer; /*0094 0097*/
+ uint32_t utility_A_int_counter_timer; /*0098 009B*/
+ uint32_t outbound_doorbell; /*009C 009F*/
+ uint32_t outbound_doorbell_clear; /*00A0 00A3*/
+ uint32_t message_source_address_index; /*00A4 00A7*/
+ uint32_t message_done_queue_index; /*00A8 00AB*/
+ uint32_t reserved0; /*00AC 00AF*/
+ uint32_t inbound_msgaddr0; /*00B0 00B3*/
+ uint32_t inbound_msgaddr1; /*00B4 00B7*/
+ uint32_t outbound_msgaddr0; /*00B8 00BB*/
+ uint32_t outbound_msgaddr1; /*00BC 00BF*/
+ uint32_t inbound_queueport_low; /*00C0 00C3*/
+ uint32_t inbound_queueport_high; /*00C4 00C7*/
+ uint32_t outbound_queueport_low; /*00C8 00CB*/
+ uint32_t outbound_queueport_high; /*00CC 00CF*/
+ uint32_t iop_inbound_queue_port_low; /*00D0 00D3*/
+ uint32_t iop_inbound_queue_port_high; /*00D4 00D7*/
+ uint32_t iop_outbound_queue_port_low; /*00D8 00DB*/
+ uint32_t iop_outbound_queue_port_high; /*00DC 00DF*/
+ uint32_t message_dest_queue_port_low; /*00E0 00E3*/
+ uint32_t message_dest_queue_port_high; /*00E4 00E7*/
+ uint32_t last_used_message_dest_address_low; /*00E8 00EB*/
+ uint32_t last_used_message_dest_address_high; /*00EC 00EF*/
+ uint32_t message_done_queue_base_address_low; /*00F0 00F3*/
+ uint32_t message_done_queue_base_address_high; /*00F4 00F7*/
+ uint32_t host_diagnostic; /*00F8 00FB*/
+ uint32_t write_sequence; /*00FC 00FF*/
+ uint32_t reserved1[34]; /*0100 0187*/
+ uint32_t reserved2[1950]; /*0188 1FFF*/
+ uint32_t message_wbuffer[32]; /*2000 207F*/
+ uint32_t reserved3[32]; /*2080 20FF*/
+ uint32_t message_rbuffer[32]; /*2100 217F*/
+ uint32_t reserved4[32]; /*2180 21FF*/
+ uint32_t msgcode_rwbuffer[256]; /*2200 23FF*/
};
-
/*
*******************************************************************************
** Adapter Control Block
@@ -370,14 +507,20 @@ struct AdapterControlBlock
unsigned long vir2phy_offset;
/* Offset is used in making arc cdb physical to virtual calculations */
uint32_t outbound_int_enable;
-
+ uint32_t cdb_phyaddr_hi32;
+ uint32_t reg_mu_acc_handle0;
+ spinlock_t eh_lock;
+ spinlock_t ccblist_lock;
union {
- struct MessageUnit_A __iomem * pmuA;
- struct MessageUnit_B * pmuB;
+ struct MessageUnit_A __iomem *pmuA;
+ struct MessageUnit_B *pmuB;
+ struct MessageUnit_C __iomem *pmuC;
};
/* message unit ATU inbound base address0 */
-
+ void __iomem *mem_base0;
+ void __iomem *mem_base1;
uint32_t acb_flags;
+ u16 dev_id;
uint8_t adapter_index;
#define ACB_F_SCSISTOPADAPTER 0x0001
#define ACB_F_MSG_STOP_BGRB 0x0002
@@ -392,8 +535,11 @@ struct AdapterControlBlock
/* message clear rqbuffer */
#define ACB_F_MESSAGE_WQBUFFER_READED 0x0040
#define ACB_F_BUS_RESET 0x0080
+ #define ACB_F_BUS_HANG_ON 0x0800/* need hardware reset bus */
+
#define ACB_F_IOP_INITED 0x0100
/* iop init */
+ #define ACB_F_ABORT 0x0200
#define ACB_F_FIRMWARE_TRAP 0x0400
struct CommandControlBlock * pccb_pool[ARCMSR_MAX_FREECCB_NUM];
/* used for memory free */
@@ -408,7 +554,8 @@ struct AdapterControlBlock
/* dma_coherent used for memory free */
dma_addr_t dma_coherent_handle;
/* dma_coherent_handle used for memory free */
-
+ dma_addr_t dma_coherent_handle_hbb_mu;
+ unsigned int uncache_size;
uint8_t rqbuffer[ARCMSR_MAX_QBUFFER];
/* data collection buffer for read from 80331 */
int32_t rqbuf_firstindex;
@@ -432,14 +579,18 @@ struct AdapterControlBlock
uint32_t firm_numbers_queue;
uint32_t firm_sdram_size;
uint32_t firm_hd_channels;
- char firm_model[12];
- char firm_version[20];
+ uint32_t firm_cfg_version;
+ char firm_model[12];
+ char firm_version[20];
char device_map[20]; /*21,84-99*/
struct work_struct arcmsr_do_message_isr_bh;
struct timer_list eternal_timer;
- unsigned short fw_state;
+ unsigned short fw_flag;
+ #define FW_NORMAL 0x0000
+ #define FW_BOG 0x0001
+ #define FW_DEADLOCK 0x0010
atomic_t rq_map_token;
- int ante_token_value;
+ atomic_t ante_token_value;
};/* HW_DEVICE_EXTENSION */
/*
*******************************************************************************
@@ -447,67 +598,33 @@ struct AdapterControlBlock
** this CCB length must be 32 bytes boundary
*******************************************************************************
*/
-struct CommandControlBlock
-{
- struct ARCMSR_CDB arcmsr_cdb;
- /*
- ** 0-503 (size of CDB = 504):
- ** arcmsr messenger scsi command descriptor size 504 bytes
- */
- uint32_t cdb_shifted_phyaddr;
- /* 504-507 */
- uint32_t reserved1;
- /* 508-511 */
-#if BITS_PER_LONG == 64
+struct CommandControlBlock{
+ /*x32:sizeof struct_CCB=(32+60)byte, x64:sizeof struct_CCB=(64+60)byte*/
+ struct list_head list; /*x32: 8byte, x64: 16byte*/
+ struct scsi_cmnd *pcmd; /*8 bytes pointer of linux scsi command */
+ struct AdapterControlBlock *acb; /*x32: 4byte, x64: 8byte*/
+ uint32_t cdb_phyaddr_pattern; /*x32: 4byte, x64: 4byte*/
+ uint32_t arc_cdb_size; /*x32:4byte,x64:4byte*/
+ uint16_t ccb_flags; /*x32: 2byte, x64: 2byte*/
+ #define CCB_FLAG_READ 0x0000
+ #define CCB_FLAG_WRITE 0x0001
+ #define CCB_FLAG_ERROR 0x0002
+ #define CCB_FLAG_FLUSHCACHE 0x0004
+ #define CCB_FLAG_MASTER_ABORTED 0x0008
+ uint16_t startdone; /*x32:2byte,x32:2byte*/
+ #define ARCMSR_CCB_DONE 0x0000
+ #define ARCMSR_CCB_START 0x55AA
+ #define ARCMSR_CCB_ABORTED 0xAA55
+ #define ARCMSR_CCB_ILLEGAL 0xFFFF
+ #if BITS_PER_LONG == 64
/* ======================512+64 bytes======================== */
- struct list_head list;
- /* 512-527 16 bytes next/prev ptrs for ccb lists */
- struct scsi_cmnd * pcmd;
- /* 528-535 8 bytes pointer of linux scsi command */
- struct AdapterControlBlock * acb;
- /* 536-543 8 bytes pointer of acb */
-
- uint16_t ccb_flags;
- /* 544-545 */
- #define CCB_FLAG_READ 0x0000
- #define CCB_FLAG_WRITE 0x0001
- #define CCB_FLAG_ERROR 0x0002
- #define CCB_FLAG_FLUSHCACHE 0x0004
- #define CCB_FLAG_MASTER_ABORTED 0x0008
- uint16_t startdone;
- /* 546-547 */
- #define ARCMSR_CCB_DONE 0x0000
- #define ARCMSR_CCB_START 0x55AA
- #define ARCMSR_CCB_ABORTED 0xAA55
- #define ARCMSR_CCB_ILLEGAL 0xFFFF
- uint32_t reserved2[7];
- /* 548-551 552-555 556-559 560-563 564-567 568-571 572-575 */
-#else
+ uint32_t reserved[5]; /*24 byte*/
+ #else
/* ======================512+32 bytes======================== */
- struct list_head list;
- /* 512-519 8 bytes next/prev ptrs for ccb lists */
- struct scsi_cmnd * pcmd;
- /* 520-523 4 bytes pointer of linux scsi command */
- struct AdapterControlBlock * acb;
- /* 524-527 4 bytes pointer of acb */
-
- uint16_t ccb_flags;
- /* 528-529 */
- #define CCB_FLAG_READ 0x0000
- #define CCB_FLAG_WRITE 0x0001
- #define CCB_FLAG_ERROR 0x0002
- #define CCB_FLAG_FLUSHCACHE 0x0004
- #define CCB_FLAG_MASTER_ABORTED 0x0008
- uint16_t startdone;
- /* 530-531 */
- #define ARCMSR_CCB_DONE 0x0000
- #define ARCMSR_CCB_START 0x55AA
- #define ARCMSR_CCB_ABORTED 0xAA55
- #define ARCMSR_CCB_ILLEGAL 0xFFFF
- uint32_t reserved2[3];
- /* 532-535 536-539 540-543 */
-#endif
- /* ========================================================== */
+ uint32_t reserved; /*8 byte*/
+ #endif
+ /* ======================================================= */
+ struct ARCMSR_CDB arcmsr_cdb;
};
/*
*******************************************************************************
diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c
index ffa54792bb3..95a895dd4f1 100644
--- a/drivers/scsi/arcmsr/arcmsr_hba.c
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c
@@ -58,7 +58,6 @@
#include <linux/timer.h>
#include <linux/pci.h>
#include <linux/aer.h>
-#include <linux/slab.h>
#include <asm/dma.h>
#include <asm/io.h>
#include <asm/system.h>
@@ -71,20 +70,13 @@
#include <scsi/scsi_transport.h>
#include <scsi/scsicam.h>
#include "arcmsr.h"
-
-#ifdef CONFIG_SCSI_ARCMSR_RESET
- static int sleeptime = 20;
- static int retrycount = 12;
- module_param(sleeptime, int, S_IRUGO|S_IWUSR);
- MODULE_PARM_DESC(sleeptime, "The waiting period for FW ready while bus reset");
- module_param(retrycount, int, S_IRUGO|S_IWUSR);
- MODULE_PARM_DESC(retrycount, "The retry count for FW ready while bus reset");
-#endif
-MODULE_AUTHOR("Erich Chen <support@areca.com.tw>");
-MODULE_DESCRIPTION("ARECA (ARC11xx/12xx/13xx/16xx) SATA/SAS RAID Host Bus Adapter");
+MODULE_AUTHOR("Nick Cheng <support@areca.com.tw>");
+MODULE_DESCRIPTION("ARECA (ARC11xx/12xx/16xx/1880) SATA/SAS RAID Host Bus Adapter");
MODULE_LICENSE("Dual BSD/GPL");
MODULE_VERSION(ARCMSR_DRIVER_VERSION);
-
+static int sleeptime = 10;
+static int retrycount = 30;
+wait_queue_head_t wait_q;
static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb,
struct scsi_cmnd *cmd);
static int arcmsr_iop_confirm(struct AdapterControlBlock *acb);
@@ -107,10 +99,12 @@ static void arcmsr_flush_hbb_cache(struct AdapterControlBlock *acb);
static void arcmsr_request_device_map(unsigned long pacb);
static void arcmsr_request_hba_device_map(struct AdapterControlBlock *acb);
static void arcmsr_request_hbb_device_map(struct AdapterControlBlock *acb);
+static void arcmsr_request_hbc_device_map(struct AdapterControlBlock *acb);
static void arcmsr_message_isr_bh_fn(struct work_struct *work);
-static void *arcmsr_get_firmware_spec(struct AdapterControlBlock *acb, int mode);
+static bool arcmsr_get_firmware_spec(struct AdapterControlBlock *acb);
static void arcmsr_start_adapter_bgrb(struct AdapterControlBlock *acb);
-
+static void arcmsr_hbc_message_isr(struct AdapterControlBlock *pACB);
+static void arcmsr_hardware_reset(struct AdapterControlBlock *acb);
static const char *arcmsr_info(struct Scsi_Host *);
static irqreturn_t arcmsr_interrupt(struct AdapterControlBlock *acb);
static int arcmsr_adjust_disk_queue_depth(struct scsi_device *sdev,
@@ -127,18 +121,18 @@ static int arcmsr_adjust_disk_queue_depth(struct scsi_device *sdev,
static struct scsi_host_template arcmsr_scsi_host_template = {
.module = THIS_MODULE,
- .name = "ARCMSR ARECA SATA/SAS RAID Host Bus Adapter"
- ARCMSR_DRIVER_VERSION,
+ .name = "ARCMSR ARECA SATA/SAS RAID Controller"
+ ARCMSR_DRIVER_VERSION,
.info = arcmsr_info,
.queuecommand = arcmsr_queue_command,
- .eh_abort_handler = arcmsr_abort,
+ .eh_abort_handler = arcmsr_abort,
.eh_bus_reset_handler = arcmsr_bus_reset,
.bios_param = arcmsr_bios_param,
.change_queue_depth = arcmsr_adjust_disk_queue_depth,
- .can_queue = ARCMSR_MAX_OUTSTANDING_CMD,
- .this_id = ARCMSR_SCSI_INITIATOR_ID,
- .sg_tablesize = ARCMSR_MAX_SG_ENTRIES,
- .max_sectors = ARCMSR_MAX_XFER_SECTORS,
+ .can_queue = ARCMSR_MAX_FREECCB_NUM,
+ .this_id = ARCMSR_SCSI_INITIATOR_ID,
+ .sg_tablesize = ARCMSR_DEFAULT_SG_ENTRIES,
+ .max_sectors = ARCMSR_MAX_XFER_SECTORS_C,
.cmd_per_lun = ARCMSR_MAX_CMD_PERLUN,
.use_clustering = ENABLE_CLUSTERING,
.shost_attrs = arcmsr_host_attrs,
@@ -162,26 +156,125 @@ static struct pci_device_id arcmsr_device_id_table[] = {
{PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1381)},
{PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1680)},
{PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1681)},
+ {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1880)},
{0, 0}, /* Terminating entry */
};
MODULE_DEVICE_TABLE(pci, arcmsr_device_id_table);
static struct pci_driver arcmsr_pci_driver = {
.name = "arcmsr",
- .id_table = arcmsr_device_id_table,
+ .id_table = arcmsr_device_id_table,
.probe = arcmsr_probe,
.remove = arcmsr_remove,
.shutdown = arcmsr_shutdown,
};
+/*
+****************************************************************************
+****************************************************************************
+*/
+int arcmsr_sleep_for_bus_reset(struct scsi_cmnd *cmd)
+{
+ struct Scsi_Host *shost = NULL;
+ int i, isleep;
+ shost = cmd->device->host;
+ isleep = sleeptime / 10;
+ if (isleep > 0) {
+ for (i = 0; i < isleep; i++) {
+ msleep(10000);
+ }
+ }
+
+ isleep = sleeptime % 10;
+ if (isleep > 0) {
+ msleep(isleep*1000);
+ }
+ printk(KERN_NOTICE "wake-up\n");
+ return 0;
+}
+
+static void arcmsr_free_hbb_mu(struct AdapterControlBlock *acb)
+{
+ switch (acb->adapter_type) {
+ case ACB_ADAPTER_TYPE_A:
+ case ACB_ADAPTER_TYPE_C:
+ break;
+ case ACB_ADAPTER_TYPE_B:{
+ dma_free_coherent(&acb->pdev->dev,
+ sizeof(struct MessageUnit_B),
+ acb->pmuB, acb->dma_coherent_handle_hbb_mu);
+ }
+ }
+}
+
+static bool arcmsr_remap_pciregion(struct AdapterControlBlock *acb)
+{
+ struct pci_dev *pdev = acb->pdev;
+ switch (acb->adapter_type){
+ case ACB_ADAPTER_TYPE_A:{
+ acb->pmuA = ioremap(pci_resource_start(pdev,0), pci_resource_len(pdev,0));
+ if (!acb->pmuA) {
+ printk(KERN_NOTICE "arcmsr%d: memory mapping region fail \n", acb->host->host_no);
+ return false;
+ }
+ break;
+ }
+ case ACB_ADAPTER_TYPE_B:{
+ void __iomem *mem_base0, *mem_base1;
+ mem_base0 = ioremap(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0));
+ if (!mem_base0) {
+ printk(KERN_NOTICE "arcmsr%d: memory mapping region fail \n", acb->host->host_no);
+ return false;
+ }
+ mem_base1 = ioremap(pci_resource_start(pdev, 2), pci_resource_len(pdev, 2));
+ if (!mem_base1) {
+ iounmap(mem_base0);
+ printk(KERN_NOTICE "arcmsr%d: memory mapping region fail \n", acb->host->host_no);
+ return false;
+ }
+ acb->mem_base0 = mem_base0;
+ acb->mem_base1 = mem_base1;
+ break;
+ }
+ case ACB_ADAPTER_TYPE_C:{
+ acb->pmuC = ioremap_nocache(pci_resource_start(pdev, 1), pci_resource_len(pdev, 1));
+ if (!acb->pmuC) {
+ printk(KERN_NOTICE "arcmsr%d: memory mapping region fail \n", acb->host->host_no);
+ return false;
+ }
+ if (readl(&acb->pmuC->outbound_doorbell) & ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE) {
+ writel(ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE_DOORBELL_CLEAR, &acb->pmuC->outbound_doorbell_clear);/*clear interrupt*/
+ return true;
+ }
+ break;
+ }
+ }
+ return true;
+}
+
+static void arcmsr_unmap_pciregion(struct AdapterControlBlock *acb)
+{
+ switch (acb->adapter_type) {
+ case ACB_ADAPTER_TYPE_A:{
+ iounmap(acb->pmuA);
+ }
+ break;
+ case ACB_ADAPTER_TYPE_B:{
+ iounmap(acb->mem_base0);
+ iounmap(acb->mem_base1);
+ }
+
+ break;
+ case ACB_ADAPTER_TYPE_C:{
+ iounmap(acb->pmuC);
+ }
+ }
+}
static irqreturn_t arcmsr_do_interrupt(int irq, void *dev_id)
{
irqreturn_t handle_state;
struct AdapterControlBlock *acb = dev_id;
- spin_lock(acb->host->host_lock);
handle_state = arcmsr_interrupt(acb);
- spin_unlock(acb->host->host_lock);
-
return handle_state;
}
@@ -218,181 +311,228 @@ static void arcmsr_define_adapter_type(struct AdapterControlBlock *acb)
struct pci_dev *pdev = acb->pdev;
u16 dev_id;
pci_read_config_word(pdev, PCI_DEVICE_ID, &dev_id);
+ acb->dev_id = dev_id;
switch (dev_id) {
- case 0x1201 : {
+ case 0x1880: {
+ acb->adapter_type = ACB_ADAPTER_TYPE_C;
+ }
+ break;
+ case 0x1201: {
acb->adapter_type = ACB_ADAPTER_TYPE_B;
}
break;
- default : acb->adapter_type = ACB_ADAPTER_TYPE_A;
+ default: acb->adapter_type = ACB_ADAPTER_TYPE_A;
}
-}
+}
-static int arcmsr_alloc_ccb_pool(struct AdapterControlBlock *acb)
+static uint8_t arcmsr_hba_wait_msgint_ready(struct AdapterControlBlock *acb)
{
+ struct MessageUnit_A __iomem *reg = acb->pmuA;
+ uint32_t Index;
+ uint8_t Retries = 0x00;
+ do {
+ for (Index = 0; Index < 100; Index++) {
+ if (readl(&reg->outbound_intstatus) &
+ ARCMSR_MU_OUTBOUND_MESSAGE0_INT) {
+ writel(ARCMSR_MU_OUTBOUND_MESSAGE0_INT,
+ &reg->outbound_intstatus);
+ return true;
+ }
+ msleep(10);
+ }/*max 1 seconds*/
- switch (acb->adapter_type) {
-
- case ACB_ADAPTER_TYPE_A: {
- struct pci_dev *pdev = acb->pdev;
- void *dma_coherent;
- dma_addr_t dma_coherent_handle, dma_addr;
- struct CommandControlBlock *ccb_tmp;
- int i, j;
+ } while (Retries++ < 20);/*max 20 sec*/
+ return false;
+}
- acb->pmuA = ioremap(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0));
- if (!acb->pmuA) {
- printk(KERN_NOTICE "arcmsr%d: memory mapping region fail \n",
- acb->host->host_no);
- return -ENOMEM;
- }
+static uint8_t arcmsr_hbb_wait_msgint_ready(struct AdapterControlBlock *acb)
+{
+ struct MessageUnit_B *reg = acb->pmuB;
+ uint32_t Index;
+ uint8_t Retries = 0x00;
+ do {
+ for (Index = 0; Index < 100; Index++) {
+ if (readl(reg->iop2drv_doorbell)
+ & ARCMSR_IOP2DRV_MESSAGE_CMD_DONE) {
+ writel(ARCMSR_MESSAGE_INT_CLEAR_PATTERN
+ , reg->iop2drv_doorbell);
+ writel(ARCMSR_DRV2IOP_END_OF_INTERRUPT, reg->drv2iop_doorbell);
+ return true;
+ }
+ msleep(10);
+ }/*max 1 seconds*/
- dma_coherent = dma_alloc_coherent(&pdev->dev,
- ARCMSR_MAX_FREECCB_NUM *
- sizeof (struct CommandControlBlock) + 0x20,
- &dma_coherent_handle, GFP_KERNEL);
+ } while (Retries++ < 20);/*max 20 sec*/
+ return false;
+}
- if (!dma_coherent) {
- iounmap(acb->pmuA);
- return -ENOMEM;
+static uint8_t arcmsr_hbc_wait_msgint_ready(struct AdapterControlBlock *pACB)
+{
+ struct MessageUnit_C *phbcmu = (struct MessageUnit_C *)pACB->pmuC;
+ unsigned char Retries = 0x00;
+ uint32_t Index;
+ do {
+ for (Index = 0; Index < 100; Index++) {
+ if (readl(&phbcmu->outbound_doorbell) & ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE) {
+ writel(ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE_DOORBELL_CLEAR, &phbcmu->outbound_doorbell_clear);/*clear interrupt*/
+ return true;
+ }
+ /* one us delay */
+ msleep(10);
+ } /*max 1 seconds*/
+ } while (Retries++ < 20); /*max 20 sec*/
+ return false;
+}
+static void arcmsr_flush_hba_cache(struct AdapterControlBlock *acb)
+{
+ struct MessageUnit_A __iomem *reg = acb->pmuA;
+ int retry_count = 30;
+ writel(ARCMSR_INBOUND_MESG0_FLUSH_CACHE, &reg->inbound_msgaddr0);
+ do {
+ if (arcmsr_hba_wait_msgint_ready(acb))
+ break;
+ else {
+ retry_count--;
+ printk(KERN_NOTICE "arcmsr%d: wait 'flush adapter cache' \
+ timeout, retry count down = %d \n", acb->host->host_no, retry_count);
}
+ } while (retry_count != 0);
+}
- acb->dma_coherent = dma_coherent;
- acb->dma_coherent_handle = dma_coherent_handle;
-
- if (((unsigned long)dma_coherent & 0x1F)) {
- dma_coherent = dma_coherent +
- (0x20 - ((unsigned long)dma_coherent & 0x1F));
- dma_coherent_handle = dma_coherent_handle +
- (0x20 - ((unsigned long)dma_coherent_handle & 0x1F));
+static void arcmsr_flush_hbb_cache(struct AdapterControlBlock *acb)
+{
+ struct MessageUnit_B *reg = acb->pmuB;
+ int retry_count = 30;
+ writel(ARCMSR_MESSAGE_FLUSH_CACHE, reg->drv2iop_doorbell);
+ do {
+ if (arcmsr_hbb_wait_msgint_ready(acb))
+ break;
+ else {
+ retry_count--;
+ printk(KERN_NOTICE "arcmsr%d: wait 'flush adapter cache' \
+ timeout,retry count down = %d \n", acb->host->host_no, retry_count);
}
+ } while (retry_count != 0);
+}
- dma_addr = dma_coherent_handle;
- ccb_tmp = (struct CommandControlBlock *)dma_coherent;
- for (i = 0; i < ARCMSR_MAX_FREECCB_NUM; i++) {
- ccb_tmp->cdb_shifted_phyaddr = dma_addr >> 5;
- ccb_tmp->acb = acb;
- acb->pccb_pool[i] = ccb_tmp;
- list_add_tail(&ccb_tmp->list, &acb->ccb_free_list);
- dma_addr = dma_addr + sizeof(struct CommandControlBlock);
- ccb_tmp++;
+static void arcmsr_flush_hbc_cache(struct AdapterControlBlock *pACB)
+{
+ struct MessageUnit_C *reg = (struct MessageUnit_C *)pACB->pmuC;
+ int retry_count = 30;/* enlarge wait flush adapter cache time: 10 minute */
+ writel(ARCMSR_INBOUND_MESG0_FLUSH_CACHE, &reg->inbound_msgaddr0);
+ writel(ARCMSR_HBCMU_DRV2IOP_MESSAGE_CMD_DONE, &reg->inbound_doorbell);
+ do {
+ if (arcmsr_hbc_wait_msgint_ready(pACB)) {
+ break;
+ } else {
+ retry_count--;
+ printk(KERN_NOTICE "arcmsr%d: wait 'flush adapter cache' \
+ timeout,retry count down = %d \n", pACB->host->host_no, retry_count);
}
+ } while (retry_count != 0);
+ return;
+}
+static void arcmsr_flush_adapter_cache(struct AdapterControlBlock *acb)
+{
+ switch (acb->adapter_type) {
- acb->vir2phy_offset = (unsigned long)ccb_tmp -(unsigned long)dma_addr;
- for (i = 0; i < ARCMSR_MAX_TARGETID; i++)
- for (j = 0; j < ARCMSR_MAX_TARGETLUN; j++)
- acb->devstate[i][j] = ARECA_RAID_GONE;
+ case ACB_ADAPTER_TYPE_A: {
+ arcmsr_flush_hba_cache(acb);
}
break;
case ACB_ADAPTER_TYPE_B: {
-
- struct pci_dev *pdev = acb->pdev;
- struct MessageUnit_B *reg;
- void __iomem *mem_base0, *mem_base1;
- void *dma_coherent;
- dma_addr_t dma_coherent_handle, dma_addr;
- struct CommandControlBlock *ccb_tmp;
- int i, j;
-
- dma_coherent = dma_alloc_coherent(&pdev->dev,
- ((ARCMSR_MAX_FREECCB_NUM *
- sizeof(struct CommandControlBlock) + 0x20) +
- sizeof(struct MessageUnit_B)),
- &dma_coherent_handle, GFP_KERNEL);
- if (!dma_coherent)
- return -ENOMEM;
-
- acb->dma_coherent = dma_coherent;
- acb->dma_coherent_handle = dma_coherent_handle;
-
- if (((unsigned long)dma_coherent & 0x1F)) {
- dma_coherent = dma_coherent +
- (0x20 - ((unsigned long)dma_coherent & 0x1F));
- dma_coherent_handle = dma_coherent_handle +
- (0x20 - ((unsigned long)dma_coherent_handle & 0x1F));
- }
-
- dma_addr = dma_coherent_handle;
- ccb_tmp = (struct CommandControlBlock *)dma_coherent;
- for (i = 0; i < ARCMSR_MAX_FREECCB_NUM; i++) {
- ccb_tmp->cdb_shifted_phyaddr = dma_addr >> 5;
- ccb_tmp->acb = acb;
- acb->pccb_pool[i] = ccb_tmp;
- list_add_tail(&ccb_tmp->list, &acb->ccb_free_list);
- dma_addr = dma_addr + sizeof(struct CommandControlBlock);
- ccb_tmp++;
- }
-
- reg = (struct MessageUnit_B *)(dma_coherent +
- ARCMSR_MAX_FREECCB_NUM * sizeof(struct CommandControlBlock));
- acb->pmuB = reg;
- mem_base0 = ioremap(pci_resource_start(pdev, 0),
- pci_resource_len(pdev, 0));
- if (!mem_base0)
- goto out;
-
- mem_base1 = ioremap(pci_resource_start(pdev, 2),
- pci_resource_len(pdev, 2));
- if (!mem_base1) {
- iounmap(mem_base0);
- goto out;
- }
-
- reg->drv2iop_doorbell_reg = mem_base0 + ARCMSR_DRV2IOP_DOORBELL;
- reg->drv2iop_doorbell_mask_reg = mem_base0 +
- ARCMSR_DRV2IOP_DOORBELL_MASK;
- reg->iop2drv_doorbell_reg = mem_base0 + ARCMSR_IOP2DRV_DOORBELL;
- reg->iop2drv_doorbell_mask_reg = mem_base0 +
- ARCMSR_IOP2DRV_DOORBELL_MASK;
- reg->ioctl_wbuffer_reg = mem_base1 + ARCMSR_IOCTL_WBUFFER;
- reg->ioctl_rbuffer_reg = mem_base1 + ARCMSR_IOCTL_RBUFFER;
- reg->msgcode_rwbuffer_reg = mem_base1 + ARCMSR_MSGCODE_RWBUFFER;
-
- acb->vir2phy_offset = (unsigned long)ccb_tmp -(unsigned long)dma_addr;
- for (i = 0; i < ARCMSR_MAX_TARGETID; i++)
- for (j = 0; j < ARCMSR_MAX_TARGETLUN; j++)
- acb->devstate[i][j] = ARECA_RAID_GOOD;
+ arcmsr_flush_hbb_cache(acb);
}
break;
+ case ACB_ADAPTER_TYPE_C: {
+ arcmsr_flush_hbc_cache(acb);
+ }
}
- return 0;
-
-out:
- dma_free_coherent(&acb->pdev->dev,
- (ARCMSR_MAX_FREECCB_NUM * sizeof(struct CommandControlBlock) + 0x20 +
- sizeof(struct MessageUnit_B)), acb->dma_coherent, acb->dma_coherent_handle);
- return -ENOMEM;
}
-static void arcmsr_message_isr_bh_fn(struct work_struct *work)
+
+static int arcmsr_alloc_ccb_pool(struct AdapterControlBlock *acb)
{
- struct AdapterControlBlock *acb = container_of(work, struct AdapterControlBlock, arcmsr_do_message_isr_bh);
+ struct pci_dev *pdev = acb->pdev;
+ void *dma_coherent;
+ dma_addr_t dma_coherent_handle;
+ struct CommandControlBlock *ccb_tmp;
+ int i = 0, j = 0;
+ dma_addr_t cdb_phyaddr;
+ unsigned long roundup_ccbsize = 0, offset;
+ unsigned long max_xfer_len;
+ unsigned long max_sg_entrys;
+ uint32_t firm_config_version;
+ for (i = 0; i < ARCMSR_MAX_TARGETID; i++)
+ for (j = 0; j < ARCMSR_MAX_TARGETLUN; j++)
+ acb->devstate[i][j] = ARECA_RAID_GONE;
+
+ max_xfer_len = ARCMSR_MAX_XFER_LEN;
+ max_sg_entrys = ARCMSR_DEFAULT_SG_ENTRIES;
+ firm_config_version = acb->firm_cfg_version;
+ if((firm_config_version & 0xFF) >= 3){
+ max_xfer_len = (ARCMSR_CDB_SG_PAGE_LENGTH << ((firm_config_version >> 8) & 0xFF)) * 1024;/* max 4M byte */
+ max_sg_entrys = (max_xfer_len/4096);
+ }
+ acb->host->max_sectors = max_xfer_len/512;
+ acb->host->sg_tablesize = max_sg_entrys;
+ roundup_ccbsize = roundup(sizeof(struct CommandControlBlock) + (max_sg_entrys - 1) * sizeof(struct SG64ENTRY), 32);
+ acb->uncache_size = roundup_ccbsize * ARCMSR_MAX_FREECCB_NUM + 32;
+ dma_coherent = dma_alloc_coherent(&pdev->dev, acb->uncache_size, &dma_coherent_handle, GFP_KERNEL);
+ if(!dma_coherent){
+ printk(KERN_NOTICE "arcmsr%d: dma_alloc_coherent got error \n", acb->host->host_no);
+ return -ENOMEM;
+ }
+ acb->dma_coherent = dma_coherent;
+ acb->dma_coherent_handle = dma_coherent_handle;
+ memset(dma_coherent, 0, acb->uncache_size);
+ offset = roundup((unsigned long)dma_coherent, 32) - (unsigned long)dma_coherent;
+ dma_coherent_handle = dma_coherent_handle + offset;
+ dma_coherent = (struct CommandControlBlock *)dma_coherent + offset;
+ ccb_tmp = dma_coherent;
+ acb->vir2phy_offset = (unsigned long)dma_coherent - (unsigned long)dma_coherent_handle;
+ for(i = 0; i < ARCMSR_MAX_FREECCB_NUM; i++){
+ cdb_phyaddr = dma_coherent_handle + offsetof(struct CommandControlBlock, arcmsr_cdb);
+ ccb_tmp->cdb_phyaddr_pattern = ((acb->adapter_type == ACB_ADAPTER_TYPE_C) ? cdb_phyaddr : (cdb_phyaddr >> 5));
+ acb->pccb_pool[i] = ccb_tmp;
+ ccb_tmp->acb = acb;
+ INIT_LIST_HEAD(&ccb_tmp->list);
+ list_add_tail(&ccb_tmp->list, &acb->ccb_free_list);
+ ccb_tmp = (struct CommandControlBlock *)((unsigned long)ccb_tmp + roundup_ccbsize);
+ dma_coherent_handle = dma_coherent_handle + roundup_ccbsize;
+ }
+ return 0;
+}
+static void arcmsr_message_isr_bh_fn(struct work_struct *work)
+{
+ struct AdapterControlBlock *acb = container_of(work,struct AdapterControlBlock, arcmsr_do_message_isr_bh);
switch (acb->adapter_type) {
case ACB_ADAPTER_TYPE_A: {
struct MessageUnit_A __iomem *reg = acb->pmuA;
char *acb_dev_map = (char *)acb->device_map;
- uint32_t __iomem *signature = (uint32_t __iomem *) (&reg->message_rwbuffer[0]);
- char __iomem *devicemap = (char __iomem *) (&reg->message_rwbuffer[21]);
+ uint32_t __iomem *signature = (uint32_t __iomem*) (&reg->message_rwbuffer[0]);
+ char __iomem *devicemap = (char __iomem*) (&reg->message_rwbuffer[21]);
int target, lun;
struct scsi_device *psdev;
char diff;
atomic_inc(&acb->rq_map_token);
if (readl(signature) == ARCMSR_SIGNATURE_GET_CONFIG) {
- for (target = 0; target < ARCMSR_MAX_TARGETID - 1; target++) {
+ for(target = 0; target < ARCMSR_MAX_TARGETID -1; target++) {
diff = (*acb_dev_map)^readb(devicemap);
if (diff != 0) {
char temp;
*acb_dev_map = readb(devicemap);
- temp = *acb_dev_map;
- for (lun = 0; lun < ARCMSR_MAX_TARGETLUN; lun++) {
- if ((temp & 0x01) == 1 && (diff & 0x01) == 1) {
+ temp =*acb_dev_map;
+ for(lun = 0; lun < ARCMSR_MAX_TARGETLUN; lun++) {
+ if((temp & 0x01)==1 && (diff & 0x01) == 1) {
scsi_add_device(acb->host, 0, target, lun);
- } else if ((temp & 0x01) == 0 && (diff & 0x01) == 1) {
+ }else if((temp & 0x01) == 0 && (diff & 0x01) == 1) {
psdev = scsi_device_lookup(acb->host, 0, target, lun);
- if (psdev != NULL) {
+ if (psdev != NULL ) {
scsi_remove_device(psdev);
scsi_device_put(psdev);
}
@@ -411,8 +551,45 @@ static void arcmsr_message_isr_bh_fn(struct work_struct *work)
case ACB_ADAPTER_TYPE_B: {
struct MessageUnit_B *reg = acb->pmuB;
char *acb_dev_map = (char *)acb->device_map;
- uint32_t __iomem *signature = (uint32_t __iomem *)(&reg->msgcode_rwbuffer_reg[0]);
- char __iomem *devicemap = (char __iomem *)(&reg->msgcode_rwbuffer_reg[21]);
+ uint32_t __iomem *signature = (uint32_t __iomem*)(&reg->message_rwbuffer[0]);
+ char __iomem *devicemap = (char __iomem*)(&reg->message_rwbuffer[21]);
+ int target, lun;
+ struct scsi_device *psdev;
+ char diff;
+
+ atomic_inc(&acb->rq_map_token);
+ if (readl(signature) == ARCMSR_SIGNATURE_GET_CONFIG) {
+ for(target = 0; target < ARCMSR_MAX_TARGETID -1; target++) {
+ diff = (*acb_dev_map)^readb(devicemap);
+ if (diff != 0) {
+ char temp;
+ *acb_dev_map = readb(devicemap);
+ temp =*acb_dev_map;
+ for(lun = 0; lun < ARCMSR_MAX_TARGETLUN; lun++) {
+ if((temp & 0x01)==1 && (diff & 0x01) == 1) {
+ scsi_add_device(acb->host, 0, target, lun);
+ }else if((temp & 0x01) == 0 && (diff & 0x01) == 1) {
+ psdev = scsi_device_lookup(acb->host, 0, target, lun);
+ if (psdev != NULL ) {
+ scsi_remove_device(psdev);
+ scsi_device_put(psdev);
+ }
+ }
+ temp >>= 1;
+ diff >>= 1;
+ }
+ }
+ devicemap++;
+ acb_dev_map++;
+ }
+ }
+ }
+ break;
+ case ACB_ADAPTER_TYPE_C: {
+ struct MessageUnit_C *reg = acb->pmuC;
+ char *acb_dev_map = (char *)acb->device_map;
+ uint32_t __iomem *signature = (uint32_t __iomem *)(&reg->msgcode_rwbuffer[0]);
+ char __iomem *devicemap = (char __iomem *)(&reg->msgcode_rwbuffer[21]);
int target, lun;
struct scsi_device *psdev;
char diff;
@@ -447,185 +624,152 @@ static void arcmsr_message_isr_bh_fn(struct work_struct *work)
}
}
-static int arcmsr_probe(struct pci_dev *pdev,
- const struct pci_device_id *id)
+static int arcmsr_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
struct Scsi_Host *host;
struct AdapterControlBlock *acb;
- uint8_t bus, dev_fun;
+ uint8_t bus,dev_fun;
int error;
-
error = pci_enable_device(pdev);
- if (error)
- goto out;
- pci_set_master(pdev);
-
- host = scsi_host_alloc(&arcmsr_scsi_host_template,
- sizeof(struct AdapterControlBlock));
- if (!host) {
- error = -ENOMEM;
- goto out_disable_device;
+ if(error){
+ return -ENODEV;
+ }
+ host = scsi_host_alloc(&arcmsr_scsi_host_template, sizeof(struct AdapterControlBlock));
+ if(!host){
+ goto pci_disable_dev;
}
- acb = (struct AdapterControlBlock *)host->hostdata;
- memset(acb, 0, sizeof (struct AdapterControlBlock));
-
error = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
- if (error) {
+ if(error){
error = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
- if (error) {
+ if(error){
printk(KERN_WARNING
"scsi%d: No suitable DMA mask available\n",
host->host_no);
- goto out_host_put;
+ goto scsi_host_release;
}
}
+ init_waitqueue_head(&wait_q);
bus = pdev->bus->number;
dev_fun = pdev->devfn;
- acb->host = host;
+ acb = (struct AdapterControlBlock *) host->hostdata;
+ memset(acb,0,sizeof(struct AdapterControlBlock));
acb->pdev = pdev;
- host->max_sectors = ARCMSR_MAX_XFER_SECTORS;
+ acb->host = host;
host->max_lun = ARCMSR_MAX_TARGETLUN;
- host->max_id = ARCMSR_MAX_TARGETID;/*16:8*/
- host->max_cmd_len = 16; /*this is issue of 64bit LBA, over 2T byte*/
- host->sg_tablesize = ARCMSR_MAX_SG_ENTRIES;
- host->can_queue = ARCMSR_MAX_FREECCB_NUM; /* max simultaneous cmds */
- host->cmd_per_lun = ARCMSR_MAX_CMD_PERLUN;
+ host->max_id = ARCMSR_MAX_TARGETID; /*16:8*/
+ host->max_cmd_len = 16; /*this is issue of 64bit LBA ,over 2T byte*/
+ host->can_queue = ARCMSR_MAX_FREECCB_NUM; /* max simultaneous cmds */
+ host->cmd_per_lun = ARCMSR_MAX_CMD_PERLUN;
host->this_id = ARCMSR_SCSI_INITIATOR_ID;
host->unique_id = (bus << 8) | dev_fun;
- host->irq = pdev->irq;
+ pci_set_drvdata(pdev, host);
+ pci_set_master(pdev);
error = pci_request_regions(pdev, "arcmsr");
- if (error) {
- goto out_host_put;
+ if(error){
+ goto scsi_host_release;
}
- arcmsr_define_adapter_type(acb);
-
+ spin_lock_init(&acb->eh_lock);
+ spin_lock_init(&acb->ccblist_lock);
acb->acb_flags |= (ACB_F_MESSAGE_WQBUFFER_CLEARED |
- ACB_F_MESSAGE_RQBUFFER_CLEARED |
- ACB_F_MESSAGE_WQBUFFER_READED);
+ ACB_F_MESSAGE_RQBUFFER_CLEARED |
+ ACB_F_MESSAGE_WQBUFFER_READED);
acb->acb_flags &= ~ACB_F_SCSISTOPADAPTER;
INIT_LIST_HEAD(&acb->ccb_free_list);
- INIT_WORK(&acb->arcmsr_do_message_isr_bh, arcmsr_message_isr_bh_fn);
+ arcmsr_define_adapter_type(acb);
+ error = arcmsr_remap_pciregion(acb);
+ if(!error){
+ goto pci_release_regs;
+ }
+ error = arcmsr_get_firmware_spec(acb);
+ if(!error){
+ goto unmap_pci_region;
+ }
error = arcmsr_alloc_ccb_pool(acb);
- if (error)
- goto out_release_regions;
-
+ if(error){
+ goto free_hbb_mu;
+ }
arcmsr_iop_init(acb);
- error = request_irq(pdev->irq, arcmsr_do_interrupt,
- IRQF_SHARED, "arcmsr", acb);
- if (error)
- goto out_free_ccb_pool;
-
- pci_set_drvdata(pdev, host);
- if (strncmp(acb->firm_version, "V1.42", 5) >= 0)
- host->max_sectors= ARCMSR_MAX_XFER_SECTORS_B;
-
error = scsi_add_host(host, &pdev->dev);
- if (error)
- goto out_free_irq;
-
- error = arcmsr_alloc_sysfs_attr(acb);
- if (error)
- goto out_free_sysfs;
-
- scsi_scan_host(host);
- #ifdef CONFIG_SCSI_ARCMSR_AER
- pci_enable_pcie_error_reporting(pdev);
- #endif
+ if(error){
+ goto RAID_controller_stop;
+ }
+ error = request_irq(pdev->irq, arcmsr_do_interrupt, IRQF_SHARED, "arcmsr", acb);
+ if(error){
+ goto scsi_host_remove;
+ }
+ host->irq = pdev->irq;
+ scsi_scan_host(host);
+ INIT_WORK(&acb->arcmsr_do_message_isr_bh, arcmsr_message_isr_bh_fn);
atomic_set(&acb->rq_map_token, 16);
- acb->fw_state = true;
+ atomic_set(&acb->ante_token_value, 16);
+ acb->fw_flag = FW_NORMAL;
init_timer(&acb->eternal_timer);
- acb->eternal_timer.expires = jiffies + msecs_to_jiffies(10*HZ);
+ acb->eternal_timer.expires = jiffies + msecs_to_jiffies(6 * HZ);
acb->eternal_timer.data = (unsigned long) acb;
acb->eternal_timer.function = &arcmsr_request_device_map;
add_timer(&acb->eternal_timer);
-
+ if(arcmsr_alloc_sysfs_attr(acb))
+ goto out_free_sysfs;
return 0;
- out_free_sysfs:
- out_free_irq:
- free_irq(pdev->irq, acb);
- out_free_ccb_pool:
+out_free_sysfs:
+scsi_host_remove:
+ scsi_remove_host(host);
+RAID_controller_stop:
+ arcmsr_stop_adapter_bgrb(acb);
+ arcmsr_flush_adapter_cache(acb);
arcmsr_free_ccb_pool(acb);
- out_release_regions:
+free_hbb_mu:
+ arcmsr_free_hbb_mu(acb);
+unmap_pci_region:
+ arcmsr_unmap_pciregion(acb);
+pci_release_regs:
pci_release_regions(pdev);
- out_host_put:
+scsi_host_release:
scsi_host_put(host);
- out_disable_device:
+pci_disable_dev:
pci_disable_device(pdev);
- out:
- return error;
-}
-
-static uint8_t arcmsr_hba_wait_msgint_ready(struct AdapterControlBlock *acb)
-{
- struct MessageUnit_A __iomem *reg = acb->pmuA;
- uint32_t Index;
- uint8_t Retries = 0x00;
-
- do {
- for (Index = 0; Index < 100; Index++) {
- if (readl(&reg->outbound_intstatus) &
- ARCMSR_MU_OUTBOUND_MESSAGE0_INT) {
- writel(ARCMSR_MU_OUTBOUND_MESSAGE0_INT,
- &reg->outbound_intstatus);
- return 0x00;
- }
- msleep(10);
- }/*max 1 seconds*/
-
- } while (Retries++ < 20);/*max 20 sec*/
- return 0xff;
-}
-
-static uint8_t arcmsr_hbb_wait_msgint_ready(struct AdapterControlBlock *acb)
-{
- struct MessageUnit_B *reg = acb->pmuB;
- uint32_t Index;
- uint8_t Retries = 0x00;
-
- do {
- for (Index = 0; Index < 100; Index++) {
- if (readl(reg->iop2drv_doorbell_reg)
- & ARCMSR_IOP2DRV_MESSAGE_CMD_DONE) {
- writel(ARCMSR_MESSAGE_INT_CLEAR_PATTERN
- , reg->iop2drv_doorbell_reg);
- writel(ARCMSR_DRV2IOP_END_OF_INTERRUPT, reg->drv2iop_doorbell_reg);
- return 0x00;
- }
- msleep(10);
- }/*max 1 seconds*/
-
- } while (Retries++ < 20);/*max 20 sec*/
- return 0xff;
+ return -ENODEV;
}
static uint8_t arcmsr_abort_hba_allcmd(struct AdapterControlBlock *acb)
{
struct MessageUnit_A __iomem *reg = acb->pmuA;
-
writel(ARCMSR_INBOUND_MESG0_ABORT_CMD, &reg->inbound_msgaddr0);
- if (arcmsr_hba_wait_msgint_ready(acb)) {
+ if (!arcmsr_hba_wait_msgint_ready(acb)) {
printk(KERN_NOTICE
"arcmsr%d: wait 'abort all outstanding command' timeout \n"
, acb->host->host_no);
- return 0xff;
+ return false;
}
- return 0x00;
+ return true;
}
static uint8_t arcmsr_abort_hbb_allcmd(struct AdapterControlBlock *acb)
{
struct MessageUnit_B *reg = acb->pmuB;
- writel(ARCMSR_MESSAGE_ABORT_CMD, reg->drv2iop_doorbell_reg);
- if (arcmsr_hbb_wait_msgint_ready(acb)) {
+ writel(ARCMSR_MESSAGE_ABORT_CMD, reg->drv2iop_doorbell);
+ if (!arcmsr_hbb_wait_msgint_ready(acb)) {
printk(KERN_NOTICE
"arcmsr%d: wait 'abort all outstanding command' timeout \n"
, acb->host->host_no);
- return 0xff;
+ return false;
}
- return 0x00;
+ return true;
+}
+static uint8_t arcmsr_abort_hbc_allcmd(struct AdapterControlBlock *pACB)
+{
+ struct MessageUnit_C *reg = (struct MessageUnit_C *)pACB->pmuC;
+ writel(ARCMSR_INBOUND_MESG0_ABORT_CMD, &reg->inbound_msgaddr0);
+ writel(ARCMSR_HBCMU_DRV2IOP_MESSAGE_CMD_DONE, &reg->inbound_doorbell);
+ if (!arcmsr_hbc_wait_msgint_ready(pACB)) {
+ printk(KERN_NOTICE
+ "arcmsr%d: wait 'abort all outstanding command' timeout \n"
+ , pACB->host->host_no);
+ return false;
+ }
+ return true;
}
-
static uint8_t arcmsr_abort_allcmd(struct AdapterControlBlock *acb)
{
uint8_t rtnval = 0;
@@ -638,10 +782,26 @@ static uint8_t arcmsr_abort_allcmd(struct AdapterControlBlock *acb)
case ACB_ADAPTER_TYPE_B: {
rtnval = arcmsr_abort_hbb_allcmd(acb);
}
+ break;
+
+ case ACB_ADAPTER_TYPE_C: {
+ rtnval = arcmsr_abort_hbc_allcmd(acb);
+ }
}
return rtnval;
}
+static bool arcmsr_hbb_enable_driver_mode(struct AdapterControlBlock *pacb)
+{
+ struct MessageUnit_B *reg = pacb->pmuB;
+ writel(ARCMSR_MESSAGE_START_DRIVER_MODE, reg->drv2iop_doorbell);
+ if (!arcmsr_hbb_wait_msgint_ready(pacb)) {
+ printk(KERN_ERR "arcmsr%d: can't set driver mode. \n", pacb->host->host_no);
+ return false;
+ }
+ return true;
+}
+
static void arcmsr_pci_unmap_dma(struct CommandControlBlock *ccb)
{
struct scsi_cmnd *pcmd = ccb->pcmd;
@@ -649,75 +809,25 @@ static void arcmsr_pci_unmap_dma(struct CommandControlBlock *ccb)
scsi_dma_unmap(pcmd);
}
-static void arcmsr_ccb_complete(struct CommandControlBlock *ccb, int stand_flag)
+static void arcmsr_ccb_complete(struct CommandControlBlock *ccb)
{
struct AdapterControlBlock *acb = ccb->acb;
struct scsi_cmnd *pcmd = ccb->pcmd;
-
+ unsigned long flags;
+ atomic_dec(&acb->ccboutstandingcount);
arcmsr_pci_unmap_dma(ccb);
- if (stand_flag == 1)
- atomic_dec(&acb->ccboutstandingcount);
ccb->startdone = ARCMSR_CCB_DONE;
- ccb->ccb_flags = 0;
+ spin_lock_irqsave(&acb->ccblist_lock, flags);
list_add_tail(&ccb->list, &acb->ccb_free_list);
+ spin_unlock_irqrestore(&acb->ccblist_lock, flags);
pcmd->scsi_done(pcmd);
}
-static void arcmsr_flush_hba_cache(struct AdapterControlBlock *acb)
-{
- struct MessageUnit_A __iomem *reg = acb->pmuA;
- int retry_count = 30;
-
- writel(ARCMSR_INBOUND_MESG0_FLUSH_CACHE, &reg->inbound_msgaddr0);
- do {
- if (!arcmsr_hba_wait_msgint_ready(acb))
- break;
- else {
- retry_count--;
- printk(KERN_NOTICE "arcmsr%d: wait 'flush adapter cache' \
- timeout, retry count down = %d \n", acb->host->host_no, retry_count);
- }
- } while (retry_count != 0);
-}
-
-static void arcmsr_flush_hbb_cache(struct AdapterControlBlock *acb)
-{
- struct MessageUnit_B *reg = acb->pmuB;
- int retry_count = 30;
-
- writel(ARCMSR_MESSAGE_FLUSH_CACHE, reg->drv2iop_doorbell_reg);
- do {
- if (!arcmsr_hbb_wait_msgint_ready(acb))
- break;
- else {
- retry_count--;
- printk(KERN_NOTICE "arcmsr%d: wait 'flush adapter cache' \
- timeout,retry count down = %d \n", acb->host->host_no, retry_count);
- }
- } while (retry_count != 0);
-}
-
-static void arcmsr_flush_adapter_cache(struct AdapterControlBlock *acb)
-{
- switch (acb->adapter_type) {
-
- case ACB_ADAPTER_TYPE_A: {
- arcmsr_flush_hba_cache(acb);
- }
- break;
-
- case ACB_ADAPTER_TYPE_B: {
- arcmsr_flush_hbb_cache(acb);
- }
- }
-}
-
static void arcmsr_report_sense_info(struct CommandControlBlock *ccb)
{
struct scsi_cmnd *pcmd = ccb->pcmd;
struct SENSE_DATA *sensebuffer = (struct SENSE_DATA *)pcmd->sense_buffer;
-
pcmd->result = DID_OK << 16;
if (sensebuffer) {
int sense_data_length =
@@ -733,8 +843,7 @@ static void arcmsr_report_sense_info(struct CommandControlBlock *ccb)
static u32 arcmsr_disable_outbound_ints(struct AdapterControlBlock *acb)
{
u32 orig_mask = 0;
- switch (acb->adapter_type) {
-
+ switch (acb->adapter_type) {
case ACB_ADAPTER_TYPE_A : {
struct MessageUnit_A __iomem *reg = acb->pmuA;
orig_mask = readl(&reg->outbound_intmask);
@@ -742,35 +851,40 @@ static u32 arcmsr_disable_outbound_ints(struct AdapterControlBlock *acb)
&reg->outbound_intmask);
}
break;
-
case ACB_ADAPTER_TYPE_B : {
struct MessageUnit_B *reg = acb->pmuB;
- orig_mask = readl(reg->iop2drv_doorbell_mask_reg);
- writel(0, reg->iop2drv_doorbell_mask_reg);
+ orig_mask = readl(reg->iop2drv_doorbell_mask);
+ writel(0, reg->iop2drv_doorbell_mask);
+ }
+ break;
+ case ACB_ADAPTER_TYPE_C:{
+ struct MessageUnit_C *reg = (struct MessageUnit_C *)acb->pmuC;
+ /* disable all outbound interrupt */
+ orig_mask = readl(&reg->host_int_mask); /* disable outbound message0 int */
+ writel(orig_mask|ARCMSR_HBCMU_ALL_INTMASKENABLE, &reg->host_int_mask);
}
break;
}
return orig_mask;
}
-static void arcmsr_report_ccb_state(struct AdapterControlBlock *acb, \
- struct CommandControlBlock *ccb, uint32_t flag_ccb)
+static void arcmsr_report_ccb_state(struct AdapterControlBlock *acb,
+ struct CommandControlBlock *ccb, bool error)
{
-
uint8_t id, lun;
id = ccb->pcmd->device->id;
lun = ccb->pcmd->device->lun;
- if (!(flag_ccb & ARCMSR_CCBREPLY_FLAG_ERROR)) {
+ if (!error) {
if (acb->devstate[id][lun] == ARECA_RAID_GONE)
acb->devstate[id][lun] = ARECA_RAID_GOOD;
ccb->pcmd->result = DID_OK << 16;
- arcmsr_ccb_complete(ccb, 1);
- } else {
+ arcmsr_ccb_complete(ccb);
+ }else{
switch (ccb->arcmsr_cdb.DeviceStatus) {
case ARCMSR_DEV_SELECT_TIMEOUT: {
acb->devstate[id][lun] = ARECA_RAID_GONE;
ccb->pcmd->result = DID_NO_CONNECT << 16;
- arcmsr_ccb_complete(ccb, 1);
+ arcmsr_ccb_complete(ccb);
}
break;
@@ -779,49 +893,49 @@ static void arcmsr_report_ccb_state(struct AdapterControlBlock *acb, \
case ARCMSR_DEV_INIT_FAIL: {
acb->devstate[id][lun] = ARECA_RAID_GONE;
ccb->pcmd->result = DID_BAD_TARGET << 16;
- arcmsr_ccb_complete(ccb, 1);
+ arcmsr_ccb_complete(ccb);
}
break;
case ARCMSR_DEV_CHECK_CONDITION: {
acb->devstate[id][lun] = ARECA_RAID_GOOD;
arcmsr_report_sense_info(ccb);
- arcmsr_ccb_complete(ccb, 1);
+ arcmsr_ccb_complete(ccb);
}
break;
default:
- printk(KERN_NOTICE
- "arcmsr%d: scsi id = %d lun = %d"
- " isr get command error done, "
- "but got unknown DeviceStatus = 0x%x \n"
- , acb->host->host_no
- , id
- , lun
- , ccb->arcmsr_cdb.DeviceStatus);
- acb->devstate[id][lun] = ARECA_RAID_GONE;
- ccb->pcmd->result = DID_NO_CONNECT << 16;
- arcmsr_ccb_complete(ccb, 1);
+ printk(KERN_NOTICE
+ "arcmsr%d: scsi id = %d lun = %d isr get command error done, \
+ but got unknown DeviceStatus = 0x%x \n"
+ , acb->host->host_no
+ , id
+ , lun
+ , ccb->arcmsr_cdb.DeviceStatus);
+ acb->devstate[id][lun] = ARECA_RAID_GONE;
+ ccb->pcmd->result = DID_NO_CONNECT << 16;
+ arcmsr_ccb_complete(ccb);
break;
}
}
}
-static void arcmsr_drain_donequeue(struct AdapterControlBlock *acb, uint32_t flag_ccb)
+static void arcmsr_drain_donequeue(struct AdapterControlBlock *acb, struct CommandControlBlock *pCCB, bool error)
{
- struct CommandControlBlock *ccb;
-
- ccb = (struct CommandControlBlock *)(acb->vir2phy_offset + (flag_ccb << 5));
- if ((ccb->acb != acb) || (ccb->startdone != ARCMSR_CCB_START)) {
- if (ccb->startdone == ARCMSR_CCB_ABORTED) {
- struct scsi_cmnd *abortcmd = ccb->pcmd;
+ int id, lun;
+ if ((pCCB->acb != acb) || (pCCB->startdone != ARCMSR_CCB_START)) {
+ if (pCCB->startdone == ARCMSR_CCB_ABORTED) {
+ struct scsi_cmnd *abortcmd = pCCB->pcmd;
if (abortcmd) {
+ id = abortcmd->device->id;
+ lun = abortcmd->device->lun;
abortcmd->result |= DID_ABORT << 16;
- arcmsr_ccb_complete(ccb, 1);
- printk(KERN_NOTICE "arcmsr%d: ccb ='0x%p' \
- isr got aborted command \n", acb->host->host_no, ccb);
+ arcmsr_ccb_complete(pCCB);
+ printk(KERN_NOTICE "arcmsr%d: pCCB ='0x%p' isr got aborted command \n",
+ acb->host->host_no, pCCB);
}
+ return;
}
printk(KERN_NOTICE "arcmsr%d: isr get an illegal ccb command \
done acb = '0x%p'"
@@ -829,20 +943,22 @@ static void arcmsr_drain_donequeue(struct AdapterControlBlock *acb, uint32_t fla
" ccboutstandingcount = %d \n"
, acb->host->host_no
, acb
- , ccb
- , ccb->acb
- , ccb->startdone
+ , pCCB
+ , pCCB->acb
+ , pCCB->startdone
, atomic_read(&acb->ccboutstandingcount));
+ return;
}
- else
- arcmsr_report_ccb_state(acb, ccb, flag_ccb);
+ arcmsr_report_ccb_state(acb, pCCB, error);
}
static void arcmsr_done4abort_postqueue(struct AdapterControlBlock *acb)
{
int i = 0;
uint32_t flag_ccb;
-
+ struct ARCMSR_CDB *pARCMSR_CDB;
+ bool error;
+ struct CommandControlBlock *pCCB;
switch (acb->adapter_type) {
case ACB_ADAPTER_TYPE_A: {
@@ -852,9 +968,12 @@ static void arcmsr_done4abort_postqueue(struct AdapterControlBlock *acb)
acb->outbound_int_enable;
/*clear and abort all outbound posted Q*/
writel(outbound_intstatus, &reg->outbound_intstatus);/*clear interrupt*/
- while (((flag_ccb = readl(&reg->outbound_queueport)) != 0xFFFFFFFF)
+ while(((flag_ccb = readl(&reg->outbound_queueport)) != 0xFFFFFFFF)
&& (i++ < ARCMSR_MAX_OUTSTANDING_CMD)) {
- arcmsr_drain_donequeue(acb, flag_ccb);
+ pARCMSR_CDB = (struct ARCMSR_CDB *)(acb->vir2phy_offset + (flag_ccb << 5));/*frame must be 32 bytes aligned*/
+ pCCB = container_of(pARCMSR_CDB, struct CommandControlBlock, arcmsr_cdb);
+ error = (flag_ccb & ARCMSR_CCBREPLY_FLAG_ERROR_MODE0) ? true : false;
+ arcmsr_drain_donequeue(acb, pCCB, error);
}
}
break;
@@ -862,17 +981,37 @@ static void arcmsr_done4abort_postqueue(struct AdapterControlBlock *acb)
case ACB_ADAPTER_TYPE_B: {
struct MessageUnit_B *reg = acb->pmuB;
/*clear all outbound posted Q*/
+ writel(ARCMSR_DOORBELL_INT_CLEAR_PATTERN, &reg->iop2drv_doorbell); /* clear doorbell interrupt */
for (i = 0; i < ARCMSR_MAX_HBB_POSTQUEUE; i++) {
if ((flag_ccb = readl(&reg->done_qbuffer[i])) != 0) {
writel(0, &reg->done_qbuffer[i]);
- arcmsr_drain_donequeue(acb, flag_ccb);
+ pARCMSR_CDB = (struct ARCMSR_CDB *)(acb->vir2phy_offset+(flag_ccb << 5));/*frame must be 32 bytes aligned*/
+ pCCB = container_of(pARCMSR_CDB, struct CommandControlBlock, arcmsr_cdb);
+ error = (flag_ccb & ARCMSR_CCBREPLY_FLAG_ERROR_MODE0) ? true : false;
+ arcmsr_drain_donequeue(acb, pCCB, error);
}
- writel(0, &reg->post_qbuffer[i]);
+ reg->post_qbuffer[i] = 0;
}
reg->doneq_index = 0;
reg->postq_index = 0;
}
break;
+ case ACB_ADAPTER_TYPE_C: {
+ struct MessageUnit_C *reg = acb->pmuC;
+ struct ARCMSR_CDB *pARCMSR_CDB;
+ uint32_t flag_ccb, ccb_cdb_phy;
+ bool error;
+ struct CommandControlBlock *pCCB;
+ while ((readl(&reg->host_int_status) & ARCMSR_HBCMU_OUTBOUND_POSTQUEUE_ISR) && (i++ < ARCMSR_MAX_OUTSTANDING_CMD)) {
+ /*need to do*/
+ flag_ccb = readl(&reg->outbound_queueport_low);
+ ccb_cdb_phy = (flag_ccb & 0xFFFFFFF0);
+ pARCMSR_CDB = (struct ARCMSR_CDB *)(acb->vir2phy_offset+ccb_cdb_phy);/*frame must be 32 bytes aligned*/
+ pCCB = container_of(pARCMSR_CDB, struct CommandControlBlock, arcmsr_cdb);
+ error = (flag_ccb & ARCMSR_CCBREPLY_FLAG_ERROR_MODE1) ? true : false;
+ arcmsr_drain_donequeue(acb, pCCB, error);
+ }
+ }
}
}
static void arcmsr_remove(struct pci_dev *pdev)
@@ -887,11 +1026,11 @@ static void arcmsr_remove(struct pci_dev *pdev)
del_timer_sync(&acb->eternal_timer);
arcmsr_disable_outbound_ints(acb);
arcmsr_stop_adapter_bgrb(acb);
- arcmsr_flush_adapter_cache(acb);
+ arcmsr_flush_adapter_cache(acb);
acb->acb_flags |= ACB_F_SCSISTOPADAPTER;
acb->acb_flags &= ~ACB_F_IOP_INITED;
- for (poll_count = 0; poll_count < ARCMSR_MAX_OUTSTANDING_CMD; poll_count++) {
+ for (poll_count = 0; poll_count < ARCMSR_MAX_OUTSTANDING_CMD; poll_count++){
if (!atomic_read(&acb->ccboutstandingcount))
break;
arcmsr_interrupt(acb);/* FIXME: need spinlock */
@@ -908,17 +1047,16 @@ static void arcmsr_remove(struct pci_dev *pdev)
if (ccb->startdone == ARCMSR_CCB_START) {
ccb->startdone = ARCMSR_CCB_ABORTED;
ccb->pcmd->result = DID_ABORT << 16;
- arcmsr_ccb_complete(ccb, 1);
+ arcmsr_ccb_complete(ccb);
}
}
}
-
free_irq(pdev->irq, acb);
arcmsr_free_ccb_pool(acb);
+ arcmsr_free_hbb_mu(acb);
+ arcmsr_unmap_pciregion(acb);
pci_release_regions(pdev);
-
scsi_host_put(host);
-
pci_disable_device(pdev);
pci_set_drvdata(pdev, NULL);
}
@@ -938,7 +1076,6 @@ static void arcmsr_shutdown(struct pci_dev *pdev)
static int arcmsr_module_init(void)
{
int error = 0;
-
error = pci_register_driver(&arcmsr_pci_driver);
return error;
}
@@ -954,10 +1091,9 @@ static void arcmsr_enable_outbound_ints(struct AdapterControlBlock *acb,
u32 intmask_org)
{
u32 mask;
-
switch (acb->adapter_type) {
- case ACB_ADAPTER_TYPE_A : {
+ case ACB_ADAPTER_TYPE_A: {
struct MessageUnit_A __iomem *reg = acb->pmuA;
mask = intmask_org & ~(ARCMSR_MU_OUTBOUND_POSTQUEUE_INTMASKENABLE |
ARCMSR_MU_OUTBOUND_DOORBELL_INTMASKENABLE|
@@ -967,15 +1103,22 @@ static void arcmsr_enable_outbound_ints(struct AdapterControlBlock *acb,
}
break;
- case ACB_ADAPTER_TYPE_B : {
+ case ACB_ADAPTER_TYPE_B: {
struct MessageUnit_B *reg = acb->pmuB;
mask = intmask_org | (ARCMSR_IOP2DRV_DATA_WRITE_OK |
ARCMSR_IOP2DRV_DATA_READ_OK |
ARCMSR_IOP2DRV_CDB_DONE |
ARCMSR_IOP2DRV_MESSAGE_CMD_DONE);
- writel(mask, reg->iop2drv_doorbell_mask_reg);
+ writel(mask, reg->iop2drv_doorbell_mask);
acb->outbound_int_enable = (intmask_org | mask) & 0x0000000f;
}
+ break;
+ case ACB_ADAPTER_TYPE_C: {
+ struct MessageUnit_C *reg = acb->pmuC;
+ mask = ~(ARCMSR_HBCMU_UTILITY_A_ISR_MASK | ARCMSR_HBCMU_OUTBOUND_DOORBELL_ISR_MASK|ARCMSR_HBCMU_OUTBOUND_POSTQUEUE_ISR_MASK);
+ writel(intmask_org & mask, &reg->host_int_mask);
+ acb->outbound_int_enable = ~(intmask_org & mask) & 0x0000000f;
+ }
}
}
@@ -986,80 +1129,70 @@ static int arcmsr_build_ccb(struct AdapterControlBlock *acb,
int8_t *psge = (int8_t *)&arcmsr_cdb->u;
__le32 address_lo, address_hi;
int arccdbsize = 0x30;
+ __le32 length = 0;
+ int i;
+ struct scatterlist *sg;
int nseg;
-
ccb->pcmd = pcmd;
memset(arcmsr_cdb, 0, sizeof(struct ARCMSR_CDB));
- arcmsr_cdb->Bus = 0;
arcmsr_cdb->TargetID = pcmd->device->id;
arcmsr_cdb->LUN = pcmd->device->lun;
arcmsr_cdb->Function = 1;
- arcmsr_cdb->CdbLength = (uint8_t)pcmd->cmd_len;
- arcmsr_cdb->Context = (unsigned long)arcmsr_cdb;
+ arcmsr_cdb->Context = 0;
memcpy(arcmsr_cdb->Cdb, pcmd->cmnd, pcmd->cmd_len);
nseg = scsi_dma_map(pcmd);
- if (nseg > ARCMSR_MAX_SG_ENTRIES)
+ if (unlikely(nseg > acb->host->sg_tablesize || nseg < 0))
return FAILED;
- BUG_ON(nseg < 0);
-
- if (nseg) {
- __le32 length;
- int i, cdb_sgcount = 0;
- struct scatterlist *sg;
-
- /* map stor port SG list to our iop SG List. */
- scsi_for_each_sg(pcmd, sg, nseg, i) {
- /* Get the physical address of the current data pointer */
- length = cpu_to_le32(sg_dma_len(sg));
- address_lo = cpu_to_le32(dma_addr_lo32(sg_dma_address(sg)));
- address_hi = cpu_to_le32(dma_addr_hi32(sg_dma_address(sg)));
- if (address_hi == 0) {
- struct SG32ENTRY *pdma_sg = (struct SG32ENTRY *)psge;
-
- pdma_sg->address = address_lo;
- pdma_sg->length = length;
- psge += sizeof (struct SG32ENTRY);
- arccdbsize += sizeof (struct SG32ENTRY);
- } else {
- struct SG64ENTRY *pdma_sg = (struct SG64ENTRY *)psge;
+ scsi_for_each_sg(pcmd, sg, nseg, i) {
+ /* Get the physical address of the current data pointer */
+ length = cpu_to_le32(sg_dma_len(sg));
+ address_lo = cpu_to_le32(dma_addr_lo32(sg_dma_address(sg)));
+ address_hi = cpu_to_le32(dma_addr_hi32(sg_dma_address(sg)));
+ if (address_hi == 0) {
+ struct SG32ENTRY *pdma_sg = (struct SG32ENTRY *)psge;
+
+ pdma_sg->address = address_lo;
+ pdma_sg->length = length;
+ psge += sizeof (struct SG32ENTRY);
+ arccdbsize += sizeof (struct SG32ENTRY);
+ } else {
+ struct SG64ENTRY *pdma_sg = (struct SG64ENTRY *)psge;
- pdma_sg->addresshigh = address_hi;
- pdma_sg->address = address_lo;
- pdma_sg->length = length|cpu_to_le32(IS_SG64_ADDR);
- psge += sizeof (struct SG64ENTRY);
- arccdbsize += sizeof (struct SG64ENTRY);
- }
- cdb_sgcount++;
+ pdma_sg->addresshigh = address_hi;
+ pdma_sg->address = address_lo;
+ pdma_sg->length = length|cpu_to_le32(IS_SG64_ADDR);
+ psge += sizeof (struct SG64ENTRY);
+ arccdbsize += sizeof (struct SG64ENTRY);
}
- arcmsr_cdb->sgcount = (uint8_t)cdb_sgcount;
- arcmsr_cdb->DataLength = scsi_bufflen(pcmd);
- if ( arccdbsize > 256)
- arcmsr_cdb->Flags |= ARCMSR_CDB_FLAG_SGL_BSIZE;
}
- if (pcmd->sc_data_direction == DMA_TO_DEVICE ) {
+ arcmsr_cdb->sgcount = (uint8_t)nseg;
+ arcmsr_cdb->DataLength = scsi_bufflen(pcmd);
+ arcmsr_cdb->msgPages = arccdbsize/0x100 + (arccdbsize % 0x100 ? 1 : 0);
+ if ( arccdbsize > 256)
+ arcmsr_cdb->Flags |= ARCMSR_CDB_FLAG_SGL_BSIZE;
+ if (pcmd->cmnd[0]|WRITE_6 || pcmd->cmnd[0]|WRITE_10 || pcmd->cmnd[0]|WRITE_12 ){
arcmsr_cdb->Flags |= ARCMSR_CDB_FLAG_WRITE;
- ccb->ccb_flags |= CCB_FLAG_WRITE;
}
+ ccb->arc_cdb_size = arccdbsize;
return SUCCESS;
}
static void arcmsr_post_ccb(struct AdapterControlBlock *acb, struct CommandControlBlock *ccb)
{
- uint32_t cdb_shifted_phyaddr = ccb->cdb_shifted_phyaddr;
+ uint32_t cdb_phyaddr_pattern = ccb->cdb_phyaddr_pattern;
struct ARCMSR_CDB *arcmsr_cdb = (struct ARCMSR_CDB *)&ccb->arcmsr_cdb;
atomic_inc(&acb->ccboutstandingcount);
ccb->startdone = ARCMSR_CCB_START;
-
switch (acb->adapter_type) {
case ACB_ADAPTER_TYPE_A: {
struct MessageUnit_A __iomem *reg = acb->pmuA;
if (arcmsr_cdb->Flags & ARCMSR_CDB_FLAG_SGL_BSIZE)
- writel(cdb_shifted_phyaddr | ARCMSR_CCBPOST_FLAG_SGL_BSIZE,
+ writel(cdb_phyaddr_pattern | ARCMSR_CCBPOST_FLAG_SGL_BSIZE,
&reg->inbound_queueport);
else {
- writel(cdb_shifted_phyaddr, &reg->inbound_queueport);
+ writel(cdb_phyaddr_pattern, &reg->inbound_queueport);
}
}
break;
@@ -1071,18 +1204,30 @@ static void arcmsr_post_ccb(struct AdapterControlBlock *acb, struct CommandContr
ending_index = ((index + 1) % ARCMSR_MAX_HBB_POSTQUEUE);
writel(0, &reg->post_qbuffer[ending_index]);
if (arcmsr_cdb->Flags & ARCMSR_CDB_FLAG_SGL_BSIZE) {
- writel(cdb_shifted_phyaddr | ARCMSR_CCBPOST_FLAG_SGL_BSIZE,\
+ writel(cdb_phyaddr_pattern | ARCMSR_CCBPOST_FLAG_SGL_BSIZE,\
&reg->post_qbuffer[index]);
- }
- else {
- writel(cdb_shifted_phyaddr, &reg->post_qbuffer[index]);
+ } else {
+ writel(cdb_phyaddr_pattern, &reg->post_qbuffer[index]);
}
index++;
index %= ARCMSR_MAX_HBB_POSTQUEUE;/*if last index number set it to 0 */
reg->postq_index = index;
- writel(ARCMSR_DRV2IOP_CDB_POSTED, reg->drv2iop_doorbell_reg);
+ writel(ARCMSR_DRV2IOP_CDB_POSTED, reg->drv2iop_doorbell);
}
break;
+ case ACB_ADAPTER_TYPE_C: {
+ struct MessageUnit_C *phbcmu = (struct MessageUnit_C *)acb->pmuC;
+ uint32_t ccb_post_stamp, arc_cdb_size;
+
+ arc_cdb_size = (ccb->arc_cdb_size > 0x300) ? 0x300 : ccb->arc_cdb_size;
+ ccb_post_stamp = (cdb_phyaddr_pattern | ((arc_cdb_size - 1) >> 6) | 1);
+ if (acb->cdb_phyaddr_hi32) {
+ writel(acb->cdb_phyaddr_hi32, &phbcmu->inbound_queueport_high);
+ writel(ccb_post_stamp, &phbcmu->inbound_queueport_low);
+ } else {
+ writel(ccb_post_stamp, &phbcmu->inbound_queueport_low);
+ }
+ }
}
}
@@ -1091,8 +1236,7 @@ static void arcmsr_stop_hba_bgrb(struct AdapterControlBlock *acb)
struct MessageUnit_A __iomem *reg = acb->pmuA;
acb->acb_flags &= ~ACB_F_MSG_START_BGRB;
writel(ARCMSR_INBOUND_MESG0_STOP_BGRB, &reg->inbound_msgaddr0);
-
- if (arcmsr_hba_wait_msgint_ready(acb)) {
+ if (!arcmsr_hba_wait_msgint_ready(acb)) {
printk(KERN_NOTICE
"arcmsr%d: wait 'stop adapter background rebulid' timeout \n"
, acb->host->host_no);
@@ -1103,15 +1247,28 @@ static void arcmsr_stop_hbb_bgrb(struct AdapterControlBlock *acb)
{
struct MessageUnit_B *reg = acb->pmuB;
acb->acb_flags &= ~ACB_F_MSG_START_BGRB;
- writel(ARCMSR_MESSAGE_STOP_BGRB, reg->drv2iop_doorbell_reg);
+ writel(ARCMSR_MESSAGE_STOP_BGRB, reg->drv2iop_doorbell);
- if (arcmsr_hbb_wait_msgint_ready(acb)) {
+ if (!arcmsr_hbb_wait_msgint_ready(acb)) {
printk(KERN_NOTICE
"arcmsr%d: wait 'stop adapter background rebulid' timeout \n"
, acb->host->host_no);
}
}
+static void arcmsr_stop_hbc_bgrb(struct AdapterControlBlock *pACB)
+{
+ struct MessageUnit_C *reg = (struct MessageUnit_C *)pACB->pmuC;
+ pACB->acb_flags &= ~ACB_F_MSG_START_BGRB;
+ writel(ARCMSR_INBOUND_MESG0_STOP_BGRB, &reg->inbound_msgaddr0);
+ writel(ARCMSR_HBCMU_DRV2IOP_MESSAGE_CMD_DONE, &reg->inbound_doorbell);
+ if (!arcmsr_hbc_wait_msgint_ready(pACB)) {
+ printk(KERN_NOTICE
+ "arcmsr%d: wait 'stop adapter background rebulid' timeout \n"
+ , pACB->host->host_no);
+ }
+ return;
+}
static void arcmsr_stop_adapter_bgrb(struct AdapterControlBlock *acb)
{
switch (acb->adapter_type) {
@@ -1124,30 +1281,15 @@ static void arcmsr_stop_adapter_bgrb(struct AdapterControlBlock *acb)
arcmsr_stop_hbb_bgrb(acb);
}
break;
+ case ACB_ADAPTER_TYPE_C: {
+ arcmsr_stop_hbc_bgrb(acb);
+ }
}
}
static void arcmsr_free_ccb_pool(struct AdapterControlBlock *acb)
{
- switch (acb->adapter_type) {
- case ACB_ADAPTER_TYPE_A: {
- iounmap(acb->pmuA);
- dma_free_coherent(&acb->pdev->dev,
- ARCMSR_MAX_FREECCB_NUM * sizeof (struct CommandControlBlock) + 0x20,
- acb->dma_coherent,
- acb->dma_coherent_handle);
- break;
- }
- case ACB_ADAPTER_TYPE_B: {
- struct MessageUnit_B *reg = acb->pmuB;
- iounmap((u8 *)reg->drv2iop_doorbell_reg - ARCMSR_DRV2IOP_DOORBELL);
- iounmap((u8 *)reg->ioctl_wbuffer_reg - ARCMSR_IOCTL_WBUFFER);
- dma_free_coherent(&acb->pdev->dev,
- (ARCMSR_MAX_FREECCB_NUM * sizeof(struct CommandControlBlock) + 0x20 +
- sizeof(struct MessageUnit_B)), acb->dma_coherent, acb->dma_coherent_handle);
- }
- }
-
+ dma_free_coherent(&acb->pdev->dev, acb->uncache_size, acb->dma_coherent, acb->dma_coherent_handle);
}
void arcmsr_iop_message_read(struct AdapterControlBlock *acb)
@@ -1161,9 +1303,13 @@ void arcmsr_iop_message_read(struct AdapterControlBlock *acb)
case ACB_ADAPTER_TYPE_B: {
struct MessageUnit_B *reg = acb->pmuB;
- writel(ARCMSR_DRV2IOP_DATA_READ_OK, reg->drv2iop_doorbell_reg);
+ writel(ARCMSR_DRV2IOP_DATA_READ_OK, reg->drv2iop_doorbell);
}
break;
+ case ACB_ADAPTER_TYPE_C: {
+ struct MessageUnit_C __iomem *reg = acb->pmuC;
+ writel(ARCMSR_HBCMU_DRV2IOP_DATA_READ_OK, &reg->inbound_doorbell);
+ }
}
}
@@ -1186,7 +1332,16 @@ static void arcmsr_iop_message_wrote(struct AdapterControlBlock *acb)
** push inbound doorbell tell iop, driver data write ok
** and wait reply on next hwinterrupt for next Qbuffer post
*/
- writel(ARCMSR_DRV2IOP_DATA_WRITE_OK, reg->drv2iop_doorbell_reg);
+ writel(ARCMSR_DRV2IOP_DATA_WRITE_OK, reg->drv2iop_doorbell);
+ }
+ break;
+ case ACB_ADAPTER_TYPE_C: {
+ struct MessageUnit_C __iomem *reg = acb->pmuC;
+ /*
+ ** push inbound doorbell tell iop, driver data write ok
+ ** and wait reply on next hwinterrupt for next Qbuffer post
+ */
+ writel(ARCMSR_HBCMU_DRV2IOP_DATA_WRITE_OK, &reg->inbound_doorbell);
}
break;
}
@@ -1195,7 +1350,6 @@ static void arcmsr_iop_message_wrote(struct AdapterControlBlock *acb)
struct QBUFFER __iomem *arcmsr_get_iop_rqbuffer(struct AdapterControlBlock *acb)
{
struct QBUFFER __iomem *qbuffer = NULL;
-
switch (acb->adapter_type) {
case ACB_ADAPTER_TYPE_A: {
@@ -1206,9 +1360,13 @@ struct QBUFFER __iomem *arcmsr_get_iop_rqbuffer(struct AdapterControlBlock *acb)
case ACB_ADAPTER_TYPE_B: {
struct MessageUnit_B *reg = acb->pmuB;
- qbuffer = (struct QBUFFER __iomem *)reg->ioctl_rbuffer_reg;
+ qbuffer = (struct QBUFFER __iomem *)reg->message_rbuffer;
}
break;
+ case ACB_ADAPTER_TYPE_C: {
+ struct MessageUnit_C *phbcmu = (struct MessageUnit_C *)acb->pmuC;
+ qbuffer = (struct QBUFFER __iomem *)&phbcmu->message_rbuffer;
+ }
}
return qbuffer;
}
@@ -1216,7 +1374,6 @@ struct QBUFFER __iomem *arcmsr_get_iop_rqbuffer(struct AdapterControlBlock *acb)
static struct QBUFFER __iomem *arcmsr_get_iop_wqbuffer(struct AdapterControlBlock *acb)
{
struct QBUFFER __iomem *pqbuffer = NULL;
-
switch (acb->adapter_type) {
case ACB_ADAPTER_TYPE_A: {
@@ -1227,9 +1384,14 @@ static struct QBUFFER __iomem *arcmsr_get_iop_wqbuffer(struct AdapterControlBloc
case ACB_ADAPTER_TYPE_B: {
struct MessageUnit_B *reg = acb->pmuB;
- pqbuffer = (struct QBUFFER __iomem *)reg->ioctl_wbuffer_reg;
+ pqbuffer = (struct QBUFFER __iomem *)reg->message_wbuffer;
}
break;
+ case ACB_ADAPTER_TYPE_C: {
+ struct MessageUnit_C *reg = (struct MessageUnit_C *)acb->pmuC;
+ pqbuffer = (struct QBUFFER __iomem *)&reg->message_wbuffer;
+ }
+
}
return pqbuffer;
}
@@ -1240,19 +1402,18 @@ static void arcmsr_iop2drv_data_wrote_handle(struct AdapterControlBlock *acb)
struct QBUFFER *pQbuffer;
uint8_t __iomem *iop_data;
int32_t my_empty_len, iop_len, rqbuf_firstindex, rqbuf_lastindex;
-
rqbuf_lastindex = acb->rqbuf_lastindex;
rqbuf_firstindex = acb->rqbuf_firstindex;
prbuffer = arcmsr_get_iop_rqbuffer(acb);
iop_data = (uint8_t __iomem *)prbuffer->data;
iop_len = prbuffer->data_len;
- my_empty_len = (rqbuf_firstindex - rqbuf_lastindex -1)&(ARCMSR_MAX_QBUFFER -1);
+ my_empty_len = (rqbuf_firstindex - rqbuf_lastindex - 1) & (ARCMSR_MAX_QBUFFER - 1);
if (my_empty_len >= iop_len)
{
while (iop_len > 0) {
pQbuffer = (struct QBUFFER *)&acb->rqbuffer[rqbuf_lastindex];
- memcpy(pQbuffer, iop_data,1);
+ memcpy(pQbuffer, iop_data, 1);
rqbuf_lastindex++;
rqbuf_lastindex %= ARCMSR_MAX_QBUFFER;
iop_data++;
@@ -1303,25 +1464,52 @@ static void arcmsr_hba_doorbell_isr(struct AdapterControlBlock *acb)
{
uint32_t outbound_doorbell;
struct MessageUnit_A __iomem *reg = acb->pmuA;
-
outbound_doorbell = readl(&reg->outbound_doorbell);
writel(outbound_doorbell, &reg->outbound_doorbell);
if (outbound_doorbell & ARCMSR_OUTBOUND_IOP331_DATA_WRITE_OK) {
arcmsr_iop2drv_data_wrote_handle(acb);
}
- if (outbound_doorbell & ARCMSR_OUTBOUND_IOP331_DATA_READ_OK) {
+ if (outbound_doorbell & ARCMSR_OUTBOUND_IOP331_DATA_READ_OK) {
arcmsr_iop2drv_data_read_handle(acb);
}
}
-
+static void arcmsr_hbc_doorbell_isr(struct AdapterControlBlock *pACB)
+{
+ uint32_t outbound_doorbell;
+ struct MessageUnit_C *reg = (struct MessageUnit_C *)pACB->pmuC;
+ /*
+ *******************************************************************
+ ** Maybe here we need to check wrqbuffer_lock is lock or not
+ ** DOORBELL: din! don!
+ ** check if there are any mail need to pack from firmware
+ *******************************************************************
+ */
+ outbound_doorbell = readl(&reg->outbound_doorbell);
+ writel(outbound_doorbell, &reg->outbound_doorbell_clear);/*clear interrupt*/
+ if (outbound_doorbell & ARCMSR_HBCMU_IOP2DRV_DATA_WRITE_OK) {
+ arcmsr_iop2drv_data_wrote_handle(pACB);
+ }
+ if (outbound_doorbell & ARCMSR_HBCMU_IOP2DRV_DATA_READ_OK) {
+ arcmsr_iop2drv_data_read_handle(pACB);
+ }
+ if (outbound_doorbell & ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE) {
+ arcmsr_hbc_message_isr(pACB); /* messenger of "driver to iop commands" */
+ }
+ return;
+}
static void arcmsr_hba_postqueue_isr(struct AdapterControlBlock *acb)
{
uint32_t flag_ccb;
struct MessageUnit_A __iomem *reg = acb->pmuA;
-
+ struct ARCMSR_CDB *pARCMSR_CDB;
+ struct CommandControlBlock *pCCB;
+ bool error;
while ((flag_ccb = readl(&reg->outbound_queueport)) != 0xFFFFFFFF) {
- arcmsr_drain_donequeue(acb, flag_ccb);
+ pARCMSR_CDB = (struct ARCMSR_CDB *)(acb->vir2phy_offset + (flag_ccb << 5));/*frame must be 32 bytes aligned*/
+ pCCB = container_of(pARCMSR_CDB, struct CommandControlBlock, arcmsr_cdb);
+ error = (flag_ccb & ARCMSR_CCBREPLY_FLAG_ERROR_MODE0) ? true : false;
+ arcmsr_drain_donequeue(acb, pCCB, error);
}
}
@@ -1330,29 +1518,62 @@ static void arcmsr_hbb_postqueue_isr(struct AdapterControlBlock *acb)
uint32_t index;
uint32_t flag_ccb;
struct MessageUnit_B *reg = acb->pmuB;
-
+ struct ARCMSR_CDB *pARCMSR_CDB;
+ struct CommandControlBlock *pCCB;
+ bool error;
index = reg->doneq_index;
-
while ((flag_ccb = readl(&reg->done_qbuffer[index])) != 0) {
writel(0, &reg->done_qbuffer[index]);
- arcmsr_drain_donequeue(acb, flag_ccb);
+ pARCMSR_CDB = (struct ARCMSR_CDB *)(acb->vir2phy_offset+(flag_ccb << 5));/*frame must be 32 bytes aligned*/
+ pCCB = container_of(pARCMSR_CDB, struct CommandControlBlock, arcmsr_cdb);
+ error = (flag_ccb & ARCMSR_CCBREPLY_FLAG_ERROR_MODE0) ? true : false;
+ arcmsr_drain_donequeue(acb, pCCB, error);
index++;
index %= ARCMSR_MAX_HBB_POSTQUEUE;
reg->doneq_index = index;
}
}
+
+static void arcmsr_hbc_postqueue_isr(struct AdapterControlBlock *acb)
+{
+ struct MessageUnit_C *phbcmu;
+ struct ARCMSR_CDB *arcmsr_cdb;
+ struct CommandControlBlock *ccb;
+ uint32_t flag_ccb, ccb_cdb_phy, throttling = 0;
+ int error;
+
+ phbcmu = (struct MessageUnit_C *)acb->pmuC;
+ /* areca cdb command done */
+ /* Use correct offset and size for syncing */
+
+ while (readl(&phbcmu->host_int_status) &
+ ARCMSR_HBCMU_OUTBOUND_POSTQUEUE_ISR){
+ /* check if command done with no error*/
+ flag_ccb = readl(&phbcmu->outbound_queueport_low);
+ ccb_cdb_phy = (flag_ccb & 0xFFFFFFF0);/*frame must be 32 bytes aligned*/
+ arcmsr_cdb = (struct ARCMSR_CDB *)(acb->vir2phy_offset + ccb_cdb_phy);
+ ccb = container_of(arcmsr_cdb, struct CommandControlBlock, arcmsr_cdb);
+ error = (flag_ccb & ARCMSR_CCBREPLY_FLAG_ERROR_MODE1) ? true : false;
+ /* check if command done with no error */
+ arcmsr_drain_donequeue(acb, ccb, error);
+ if (throttling == ARCMSR_HBC_ISR_THROTTLING_LEVEL) {
+ writel(ARCMSR_HBCMU_DRV2IOP_POSTQUEUE_THROTTLING, &phbcmu->inbound_doorbell);
+ break;
+ }
+ throttling++;
+ }
+}
/*
**********************************************************************************
** Handle a message interrupt
**
-** The only message interrupt we expect is in response to a query for the current adapter config.
+** The only message interrupt we expect is in response to a query for the current adapter config.
** We want this in order to compare the drivemap so that we can detect newly-attached drives.
**********************************************************************************
*/
static void arcmsr_hba_message_isr(struct AdapterControlBlock *acb)
{
struct MessageUnit_A *reg = acb->pmuA;
-
/*clear interrupt and message state*/
writel(ARCMSR_MU_OUTBOUND_MESSAGE0_INT, &reg->outbound_intstatus);
schedule_work(&acb->arcmsr_do_message_isr_bh);
@@ -1362,16 +1583,32 @@ static void arcmsr_hbb_message_isr(struct AdapterControlBlock *acb)
struct MessageUnit_B *reg = acb->pmuB;
/*clear interrupt and message state*/
- writel(ARCMSR_MESSAGE_INT_CLEAR_PATTERN, reg->iop2drv_doorbell_reg);
+ writel(ARCMSR_MESSAGE_INT_CLEAR_PATTERN, reg->iop2drv_doorbell);
+ schedule_work(&acb->arcmsr_do_message_isr_bh);
+}
+/*
+**********************************************************************************
+** Handle a message interrupt
+**
+** The only message interrupt we expect is in response to a query for the
+** current adapter config.
+** We want this in order to compare the drivemap so that we can detect newly-attached drives.
+**********************************************************************************
+*/
+static void arcmsr_hbc_message_isr(struct AdapterControlBlock *acb)
+{
+ struct MessageUnit_C *reg = acb->pmuC;
+ /*clear interrupt and message state*/
+ writel(ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE_DOORBELL_CLEAR, &reg->outbound_doorbell_clear);
schedule_work(&acb->arcmsr_do_message_isr_bh);
}
+
static int arcmsr_handle_hba_isr(struct AdapterControlBlock *acb)
{
uint32_t outbound_intstatus;
struct MessageUnit_A __iomem *reg = acb->pmuA;
-
outbound_intstatus = readl(&reg->outbound_intstatus) &
- acb->outbound_int_enable;
+ acb->outbound_int_enable;
if (!(outbound_intstatus & ARCMSR_MU_OUTBOUND_HANDLE_INT)) {
return 1;
}
@@ -1382,7 +1619,7 @@ static int arcmsr_handle_hba_isr(struct AdapterControlBlock *acb)
if (outbound_intstatus & ARCMSR_MU_OUTBOUND_POSTQUEUE_INT) {
arcmsr_hba_postqueue_isr(acb);
}
- if (outbound_intstatus & ARCMSR_MU_OUTBOUND_MESSAGE0_INT) {
+ if(outbound_intstatus & ARCMSR_MU_OUTBOUND_MESSAGE0_INT) {
/* messenger of "driver to iop commands" */
arcmsr_hba_message_isr(acb);
}
@@ -1393,18 +1630,17 @@ static int arcmsr_handle_hbb_isr(struct AdapterControlBlock *acb)
{
uint32_t outbound_doorbell;
struct MessageUnit_B *reg = acb->pmuB;
-
- outbound_doorbell = readl(reg->iop2drv_doorbell_reg) &
- acb->outbound_int_enable;
+ outbound_doorbell = readl(reg->iop2drv_doorbell) &
+ acb->outbound_int_enable;
if (!outbound_doorbell)
return 1;
- writel(~outbound_doorbell, reg->iop2drv_doorbell_reg);
+ writel(~outbound_doorbell, reg->iop2drv_doorbell);
/*in case the last action of doorbell interrupt clearance is cached,
this action can push HW to write down the clear bit*/
- readl(reg->iop2drv_doorbell_reg);
- writel(ARCMSR_DRV2IOP_END_OF_INTERRUPT, reg->drv2iop_doorbell_reg);
- if (outbound_doorbell & ARCMSR_IOP2DRV_DATA_WRITE_OK) {
+ readl(reg->iop2drv_doorbell);
+ writel(ARCMSR_DRV2IOP_END_OF_INTERRUPT, reg->drv2iop_doorbell);
+ if (outbound_doorbell & ARCMSR_IOP2DRV_DATA_WRITE_OK) {
arcmsr_iop2drv_data_wrote_handle(acb);
}
if (outbound_doorbell & ARCMSR_IOP2DRV_DATA_READ_OK) {
@@ -1413,14 +1649,37 @@ static int arcmsr_handle_hbb_isr(struct AdapterControlBlock *acb)
if (outbound_doorbell & ARCMSR_IOP2DRV_CDB_DONE) {
arcmsr_hbb_postqueue_isr(acb);
}
- if (outbound_doorbell & ARCMSR_IOP2DRV_MESSAGE_CMD_DONE) {
+ if(outbound_doorbell & ARCMSR_IOP2DRV_MESSAGE_CMD_DONE) {
/* messenger of "driver to iop commands" */
arcmsr_hbb_message_isr(acb);
}
-
return 0;
}
+static int arcmsr_handle_hbc_isr(struct AdapterControlBlock *pACB)
+{
+ uint32_t host_interrupt_status;
+ struct MessageUnit_C *phbcmu = (struct MessageUnit_C *)pACB->pmuC;
+ /*
+ *********************************************
+ ** check outbound intstatus
+ *********************************************
+ */
+ host_interrupt_status = readl(&phbcmu->host_int_status);
+ if (!host_interrupt_status) {
+ /*it must be share irq*/
+ return 1;
+ }
+ /* MU ioctl transfer doorbell interrupts*/
+ if (host_interrupt_status & ARCMSR_HBCMU_OUTBOUND_DOORBELL_ISR) {
+ arcmsr_hbc_doorbell_isr(pACB); /* messenger of "ioctl message read write" */
+ }
+ /* MU post queue interrupts*/
+ if (host_interrupt_status & ARCMSR_HBCMU_OUTBOUND_POSTQUEUE_ISR) {
+ arcmsr_hbc_postqueue_isr(pACB); /* messenger of "scsi commands" */
+ }
+ return 0;
+}
static irqreturn_t arcmsr_interrupt(struct AdapterControlBlock *acb)
{
switch (acb->adapter_type) {
@@ -1437,6 +1696,11 @@ static irqreturn_t arcmsr_interrupt(struct AdapterControlBlock *acb)
}
}
break;
+ case ACB_ADAPTER_TYPE_C: {
+ if (arcmsr_handle_hbc_isr(acb)) {
+ return IRQ_NONE;
+ }
+ }
}
return IRQ_HANDLED;
}
@@ -1463,7 +1727,6 @@ void arcmsr_post_ioctldata2iop(struct AdapterControlBlock *acb)
struct QBUFFER __iomem *pwbuffer;
uint8_t __iomem *iop_data;
int32_t allxfer_len = 0;
-
pwbuffer = arcmsr_get_iop_wqbuffer(acb);
iop_data = (uint8_t __iomem *)pwbuffer->data;
if (acb->acb_flags & ACB_F_MESSAGE_WQBUFFER_READED) {
@@ -1496,7 +1759,6 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb,
(uint32_t ) cmd->cmnd[7] << 8 |
(uint32_t ) cmd->cmnd[8];
/* 4 bytes: Areca io control code */
-
sg = scsi_sglist(cmd);
buffer = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
if (scsi_sg_count(cmd) > 1) {
@@ -1522,13 +1784,7 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb,
retvalue = ARCMSR_MESSAGE_FAIL;
goto message_out;
}
-
- if (!acb->fw_state) {
- pcmdmessagefld->cmdmessage.ReturnCode =
- ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON;
- goto message_out;
- }
-
+
ptmpQbuffer = ver_addr;
while ((acb->rqbuf_firstindex != acb->rqbuf_lastindex)
&& (allxfer_len < 1031)) {
@@ -1560,7 +1816,11 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb,
}
memcpy(pcmdmessagefld->messagedatabuffer, ver_addr, allxfer_len);
pcmdmessagefld->cmdmessage.Length = allxfer_len;
- pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK;
+ if(acb->fw_flag == FW_DEADLOCK) {
+ pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON;
+ }else{
+ pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK;
+ }
kfree(ver_addr);
}
break;
@@ -1575,12 +1835,13 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb,
retvalue = ARCMSR_MESSAGE_FAIL;
goto message_out;
}
- if (!acb->fw_state) {
- pcmdmessagefld->cmdmessage.ReturnCode =
+ if(acb->fw_flag == FW_DEADLOCK) {
+ pcmdmessagefld->cmdmessage.ReturnCode =
ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON;
- goto message_out;
+ }else{
+ pcmdmessagefld->cmdmessage.ReturnCode =
+ ARCMSR_MESSAGE_RETURNCODE_OK;
}
-
ptmpuserbuffer = ver_addr;
user_len = pcmdmessagefld->cmdmessage.Length;
memcpy(ptmpuserbuffer, pcmdmessagefld->messagedatabuffer, user_len);
@@ -1633,12 +1894,6 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb,
case ARCMSR_MESSAGE_CLEAR_RQBUFFER: {
uint8_t *pQbuffer = acb->rqbuffer;
- if (!acb->fw_state) {
- pcmdmessagefld->cmdmessage.ReturnCode =
- ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON;
- goto message_out;
- }
-
if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
arcmsr_iop_message_read(acb);
@@ -1647,16 +1902,24 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb,
acb->rqbuf_firstindex = 0;
acb->rqbuf_lastindex = 0;
memset(pQbuffer, 0, ARCMSR_MAX_QBUFFER);
- pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK;
+ if(acb->fw_flag == FW_DEADLOCK) {
+ pcmdmessagefld->cmdmessage.ReturnCode =
+ ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON;
+ }else{
+ pcmdmessagefld->cmdmessage.ReturnCode =
+ ARCMSR_MESSAGE_RETURNCODE_OK;
+ }
}
break;
case ARCMSR_MESSAGE_CLEAR_WQBUFFER: {
uint8_t *pQbuffer = acb->wqbuffer;
- if (!acb->fw_state) {
+ if(acb->fw_flag == FW_DEADLOCK) {
pcmdmessagefld->cmdmessage.ReturnCode =
ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON;
- goto message_out;
+ }else{
+ pcmdmessagefld->cmdmessage.ReturnCode =
+ ARCMSR_MESSAGE_RETURNCODE_OK;
}
if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
@@ -1669,18 +1932,11 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb,
acb->wqbuf_firstindex = 0;
acb->wqbuf_lastindex = 0;
memset(pQbuffer, 0, ARCMSR_MAX_QBUFFER);
- pcmdmessagefld->cmdmessage.ReturnCode =
- ARCMSR_MESSAGE_RETURNCODE_OK;
}
break;
case ARCMSR_MESSAGE_CLEAR_ALLQBUFFER: {
uint8_t *pQbuffer;
- if (!acb->fw_state) {
- pcmdmessagefld->cmdmessage.ReturnCode =
- ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON;
- goto message_out;
- }
if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
@@ -1698,47 +1954,52 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb,
memset(pQbuffer, 0, sizeof(struct QBUFFER));
pQbuffer = acb->wqbuffer;
memset(pQbuffer, 0, sizeof(struct QBUFFER));
- pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK;
+ if(acb->fw_flag == FW_DEADLOCK) {
+ pcmdmessagefld->cmdmessage.ReturnCode =
+ ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON;
+ }else{
+ pcmdmessagefld->cmdmessage.ReturnCode =
+ ARCMSR_MESSAGE_RETURNCODE_OK;
+ }
}
break;
case ARCMSR_MESSAGE_RETURN_CODE_3F: {
- if (!acb->fw_state) {
+ if(acb->fw_flag == FW_DEADLOCK) {
pcmdmessagefld->cmdmessage.ReturnCode =
ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON;
- goto message_out;
- }
- pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_3F;
+ }else{
+ pcmdmessagefld->cmdmessage.ReturnCode =
+ ARCMSR_MESSAGE_RETURNCODE_3F;
}
break;
-
+ }
case ARCMSR_MESSAGE_SAY_HELLO: {
int8_t *hello_string = "Hello! I am ARCMSR";
- if (!acb->fw_state) {
+ if(acb->fw_flag == FW_DEADLOCK) {
pcmdmessagefld->cmdmessage.ReturnCode =
ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON;
- goto message_out;
+ }else{
+ pcmdmessagefld->cmdmessage.ReturnCode =
+ ARCMSR_MESSAGE_RETURNCODE_OK;
}
memcpy(pcmdmessagefld->messagedatabuffer, hello_string
, (int16_t)strlen(hello_string));
- pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK;
}
break;
case ARCMSR_MESSAGE_SAY_GOODBYE:
- if (!acb->fw_state) {
+ if(acb->fw_flag == FW_DEADLOCK) {
pcmdmessagefld->cmdmessage.ReturnCode =
ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON;
- goto message_out;
}
arcmsr_iop_parking(acb);
break;
case ARCMSR_MESSAGE_FLUSH_ADAPTER_CACHE:
- if (!acb->fw_state) {
+ if(acb->fw_flag == FW_DEADLOCK) {
pcmdmessagefld->cmdmessage.ReturnCode =
ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON;
- goto message_out;
}
arcmsr_flush_adapter_cache(acb);
break;
@@ -1756,11 +2017,16 @@ static struct CommandControlBlock *arcmsr_get_freeccb(struct AdapterControlBlock
{
struct list_head *head = &acb->ccb_free_list;
struct CommandControlBlock *ccb = NULL;
-
+ unsigned long flags;
+ spin_lock_irqsave(&acb->ccblist_lock, flags);
if (!list_empty(head)) {
ccb = list_entry(head->next, struct CommandControlBlock, list);
- list_del(head->next);
+ list_del_init(&ccb->list);
+ }else{
+ spin_unlock_irqrestore(&acb->ccblist_lock, flags);
+ return 0;
}
+ spin_unlock_irqrestore(&acb->ccblist_lock, flags);
return ccb;
}
@@ -1826,83 +2092,29 @@ static int arcmsr_queue_command(struct scsi_cmnd *cmd,
cmd->scsi_done = done;
cmd->host_scribble = NULL;
cmd->result = 0;
-
- if ((scsicmd == SYNCHRONIZE_CACHE) || (scsicmd == SEND_DIAGNOSTIC)) {
- if (acb->devstate[target][lun] == ARECA_RAID_GONE) {
- cmd->result = (DID_NO_CONNECT << 16);
+ if ((scsicmd == SYNCHRONIZE_CACHE) ||(scsicmd == SEND_DIAGNOSTIC)){
+ if(acb->devstate[target][lun] == ARECA_RAID_GONE) {
+ cmd->result = (DID_NO_CONNECT << 16);
}
cmd->scsi_done(cmd);
return 0;
}
-
- if (acb->acb_flags & ACB_F_BUS_RESET) {
- switch (acb->adapter_type) {
- case ACB_ADAPTER_TYPE_A: {
- struct MessageUnit_A __iomem *reg = acb->pmuA;
- uint32_t intmask_org, outbound_doorbell;
-
- if ((readl(&reg->outbound_msgaddr1) &
- ARCMSR_OUTBOUND_MESG1_FIRMWARE_OK) == 0) {
- printk(KERN_NOTICE "arcmsr%d: bus reset and return busy\n",
- acb->host->host_no);
- return SCSI_MLQUEUE_HOST_BUSY;
- }
-
- acb->acb_flags &= ~ACB_F_FIRMWARE_TRAP;
- printk(KERN_NOTICE "arcmsr%d: hardware bus reset and reset ok\n",
- acb->host->host_no);
- /* disable all outbound interrupt */
- intmask_org = arcmsr_disable_outbound_ints(acb);
- arcmsr_get_firmware_spec(acb, 1);
- /*start background rebuild*/
- arcmsr_start_adapter_bgrb(acb);
- /* clear Qbuffer if door bell ringed */
- outbound_doorbell = readl(&reg->outbound_doorbell);
- /*clear interrupt */
- writel(outbound_doorbell, &reg->outbound_doorbell);
- writel(ARCMSR_INBOUND_DRIVER_DATA_READ_OK,
- &reg->inbound_doorbell);
- /* enable outbound Post Queue,outbound doorbell Interrupt */
- arcmsr_enable_outbound_ints(acb, intmask_org);
- acb->acb_flags |= ACB_F_IOP_INITED;
- acb->acb_flags &= ~ACB_F_BUS_RESET;
- }
- break;
- case ACB_ADAPTER_TYPE_B: {
- }
- }
- }
-
if (target == 16) {
/* virtual device for iop message transfer */
arcmsr_handle_virtual_command(acb, cmd);
return 0;
}
- if (acb->devstate[target][lun] == ARECA_RAID_GONE) {
- uint8_t block_cmd;
-
- block_cmd = cmd->cmnd[0] & 0x0f;
- if (block_cmd == 0x08 || block_cmd == 0x0a) {
- printk(KERN_NOTICE
- "arcmsr%d: block 'read/write'"
- "command with gone raid volume"
- " Cmd = %2x, TargetId = %d, Lun = %d \n"
- , acb->host->host_no
- , cmd->cmnd[0]
- , target, lun);
- cmd->result = (DID_NO_CONNECT << 16);
- cmd->scsi_done(cmd);
- return 0;
- }
- }
if (atomic_read(&acb->ccboutstandingcount) >=
ARCMSR_MAX_OUTSTANDING_CMD)
return SCSI_MLQUEUE_HOST_BUSY;
-
+ if ((scsicmd == SCSI_CMD_ARECA_SPECIFIC)) {
+ printk(KERN_NOTICE "Receiveing SCSI_CMD_ARECA_SPECIFIC command..\n");
+ return 0;
+ }
ccb = arcmsr_get_freeccb(acb);
if (!ccb)
return SCSI_MLQUEUE_HOST_BUSY;
- if ( arcmsr_build_ccb( acb, ccb, cmd ) == FAILED ) {
+ if (arcmsr_build_ccb( acb, ccb, cmd ) == FAILED) {
cmd->result = (DID_ERROR << 16) | (RESERVATION_CONFLICT << 1);
cmd->scsi_done(cmd);
return 0;
@@ -1911,7 +2123,7 @@ static int arcmsr_queue_command(struct scsi_cmnd *cmd,
return 0;
}
-static void *arcmsr_get_hba_config(struct AdapterControlBlock *acb, int mode)
+static bool arcmsr_get_hba_config(struct AdapterControlBlock *acb)
{
struct MessageUnit_A __iomem *reg = acb->pmuA;
char *acb_firm_model = acb->firm_model;
@@ -1919,19 +2131,16 @@ static void *arcmsr_get_hba_config(struct AdapterControlBlock *acb, int mode)
char *acb_device_map = acb->device_map;
char __iomem *iop_firm_model = (char __iomem *)(&reg->message_rwbuffer[15]);
char __iomem *iop_firm_version = (char __iomem *)(&reg->message_rwbuffer[17]);
- char __iomem *iop_device_map = (char __iomem *) (&reg->message_rwbuffer[21]);
+ char __iomem *iop_device_map = (char __iomem *)(&reg->message_rwbuffer[21]);
int count;
-
writel(ARCMSR_INBOUND_MESG0_GET_CONFIG, &reg->inbound_msgaddr0);
- if (arcmsr_hba_wait_msgint_ready(acb)) {
+ if (!arcmsr_hba_wait_msgint_ready(acb)) {
printk(KERN_NOTICE "arcmsr%d: wait 'get adapter firmware \
miscellaneous data' timeout \n", acb->host->host_no);
- return NULL;
+ return false;
}
-
- if (mode == 1) {
count = 8;
- while (count) {
+ while (count){
*acb_firm_model = readb(iop_firm_model);
acb_firm_model++;
iop_firm_model++;
@@ -1939,138 +2148,213 @@ static void *arcmsr_get_hba_config(struct AdapterControlBlock *acb, int mode)
}
count = 16;
- while (count) {
+ while (count){
*acb_firm_version = readb(iop_firm_version);
acb_firm_version++;
iop_firm_version++;
count--;
}
- count = 16;
- while (count) {
- *acb_device_map = readb(iop_device_map);
- acb_device_map++;
- iop_device_map++;
- count--;
- }
-
- printk(KERN_INFO "ARECA RAID ADAPTER%d: FIRMWARE VERSION %s \n"
- , acb->host->host_no
- , acb->firm_version);
- acb->signature = readl(&reg->message_rwbuffer[0]);
+ count=16;
+ while(count){
+ *acb_device_map = readb(iop_device_map);
+ acb_device_map++;
+ iop_device_map++;
+ count--;
+ }
+ printk(KERN_NOTICE "Areca RAID Controller%d: F/W %s & Model %s\n",
+ acb->host->host_no,
+ acb->firm_version,
+ acb->firm_model);
+ acb->signature = readl(&reg->message_rwbuffer[0]);
acb->firm_request_len = readl(&reg->message_rwbuffer[1]);
acb->firm_numbers_queue = readl(&reg->message_rwbuffer[2]);
acb->firm_sdram_size = readl(&reg->message_rwbuffer[3]);
acb->firm_hd_channels = readl(&reg->message_rwbuffer[4]);
+ acb->firm_cfg_version = readl(&reg->message_rwbuffer[25]); /*firm_cfg_version,25,100-103*/
+ return true;
}
- return reg->message_rwbuffer;
-}
-static void __iomem *arcmsr_get_hbb_config(struct AdapterControlBlock *acb, int mode)
+static bool arcmsr_get_hbb_config(struct AdapterControlBlock *acb)
{
struct MessageUnit_B *reg = acb->pmuB;
- uint32_t __iomem *lrwbuffer = reg->msgcode_rwbuffer_reg;
+ struct pci_dev *pdev = acb->pdev;
+ void *dma_coherent;
+ dma_addr_t dma_coherent_handle;
char *acb_firm_model = acb->firm_model;
char *acb_firm_version = acb->firm_version;
char *acb_device_map = acb->device_map;
- char __iomem *iop_firm_model = (char __iomem *)(&lrwbuffer[15]);
+ char __iomem *iop_firm_model;
/*firm_model,15,60-67*/
- char __iomem *iop_firm_version = (char __iomem *)(&lrwbuffer[17]);
+ char __iomem *iop_firm_version;
/*firm_version,17,68-83*/
- char __iomem *iop_device_map = (char __iomem *) (&lrwbuffer[21]);
+ char __iomem *iop_device_map;
/*firm_version,21,84-99*/
int count;
-
- writel(ARCMSR_MESSAGE_GET_CONFIG, reg->drv2iop_doorbell_reg);
- if (arcmsr_hbb_wait_msgint_ready(acb)) {
+ dma_coherent = dma_alloc_coherent(&pdev->dev, sizeof(struct MessageUnit_B), &dma_coherent_handle, GFP_KERNEL);
+ if (!dma_coherent){
+ printk(KERN_NOTICE "arcmsr%d: dma_alloc_coherent got error for hbb mu\n", acb->host->host_no);
+ return false;
+ }
+ acb->dma_coherent_handle_hbb_mu = dma_coherent_handle;
+ reg = (struct MessageUnit_B *)dma_coherent;
+ acb->pmuB = reg;
+ reg->drv2iop_doorbell= (uint32_t __iomem *)((unsigned long)acb->mem_base0 + ARCMSR_DRV2IOP_DOORBELL);
+ reg->drv2iop_doorbell_mask = (uint32_t __iomem *)((unsigned long)acb->mem_base0 + ARCMSR_DRV2IOP_DOORBELL_MASK);
+ reg->iop2drv_doorbell = (uint32_t __iomem *)((unsigned long)acb->mem_base0 + ARCMSR_IOP2DRV_DOORBELL);
+ reg->iop2drv_doorbell_mask = (uint32_t __iomem *)((unsigned long)acb->mem_base0 + ARCMSR_IOP2DRV_DOORBELL_MASK);
+ reg->message_wbuffer = (uint32_t __iomem *)((unsigned long)acb->mem_base1 + ARCMSR_MESSAGE_WBUFFER);
+ reg->message_rbuffer = (uint32_t __iomem *)((unsigned long)acb->mem_base1 + ARCMSR_MESSAGE_RBUFFER);
+ reg->message_rwbuffer = (uint32_t __iomem *)((unsigned long)acb->mem_base1 + ARCMSR_MESSAGE_RWBUFFER);
+ iop_firm_model = (char __iomem *)(&reg->message_rwbuffer[15]); /*firm_model,15,60-67*/
+ iop_firm_version = (char __iomem *)(&reg->message_rwbuffer[17]); /*firm_version,17,68-83*/
+ iop_device_map = (char __iomem *)(&reg->message_rwbuffer[21]); /*firm_version,21,84-99*/
+
+ writel(ARCMSR_MESSAGE_GET_CONFIG, reg->drv2iop_doorbell);
+ if (!arcmsr_hbb_wait_msgint_ready(acb)) {
printk(KERN_NOTICE "arcmsr%d: wait 'get adapter firmware \
miscellaneous data' timeout \n", acb->host->host_no);
- return NULL;
+ return false;
}
-
- if (mode == 1) {
count = 8;
- while (count)
- {
+ while (count){
*acb_firm_model = readb(iop_firm_model);
acb_firm_model++;
iop_firm_model++;
count--;
}
-
count = 16;
- while (count)
- {
+ while (count){
*acb_firm_version = readb(iop_firm_version);
acb_firm_version++;
iop_firm_version++;
count--;
}
- count = 16;
- while (count) {
- *acb_device_map = readb(iop_device_map);
- acb_device_map++;
- iop_device_map++;
- count--;
- }
-
- printk(KERN_INFO "ARECA RAID ADAPTER%d: FIRMWARE VERSION %s \n",
- acb->host->host_no,
- acb->firm_version);
+ count = 16;
+ while(count){
+ *acb_device_map = readb(iop_device_map);
+ acb_device_map++;
+ iop_device_map++;
+ count--;
+ }
+
+ printk(KERN_NOTICE "Areca RAID Controller%d: F/W %s & Model %s\n",
+ acb->host->host_no,
+ acb->firm_version,
+ acb->firm_model);
- acb->signature = readl(lrwbuffer++);
- /*firm_signature,1,00-03*/
- acb->firm_request_len = readl(lrwbuffer++);
+ acb->signature = readl(&reg->message_rwbuffer[1]);
+ /*firm_signature,1,00-03*/
+ acb->firm_request_len = readl(&reg->message_rwbuffer[2]);
/*firm_request_len,1,04-07*/
- acb->firm_numbers_queue = readl(lrwbuffer++);
+ acb->firm_numbers_queue = readl(&reg->message_rwbuffer[3]);
/*firm_numbers_queue,2,08-11*/
- acb->firm_sdram_size = readl(lrwbuffer++);
+ acb->firm_sdram_size = readl(&reg->message_rwbuffer[4]);
/*firm_sdram_size,3,12-15*/
- acb->firm_hd_channels = readl(lrwbuffer);
+ acb->firm_hd_channels = readl(&reg->message_rwbuffer[5]);
/*firm_ide_channels,4,16-19*/
+ acb->firm_cfg_version = readl(&reg->message_rwbuffer[25]); /*firm_cfg_version,25,100-103*/
+ /*firm_ide_channels,4,16-19*/
+ return true;
}
- return reg->msgcode_rwbuffer_reg;
-}
-static void *arcmsr_get_firmware_spec(struct AdapterControlBlock *acb, int mode)
-{
- void *rtnval = 0;
- switch (acb->adapter_type) {
- case ACB_ADAPTER_TYPE_A: {
- rtnval = arcmsr_get_hba_config(acb, mode);
- }
- break;
- case ACB_ADAPTER_TYPE_B: {
- rtnval = arcmsr_get_hbb_config(acb, mode);
+static bool arcmsr_get_hbc_config(struct AdapterControlBlock *pACB)
+{
+ uint32_t intmask_org, Index, firmware_state = 0;
+ struct MessageUnit_C *reg = pACB->pmuC;
+ char *acb_firm_model = pACB->firm_model;
+ char *acb_firm_version = pACB->firm_version;
+ char *iop_firm_model = (char *)(&reg->msgcode_rwbuffer[15]); /*firm_model,15,60-67*/
+ char *iop_firm_version = (char *)(&reg->msgcode_rwbuffer[17]); /*firm_version,17,68-83*/
+ int count;
+ /* disable all outbound interrupt */
+ intmask_org = readl(&reg->host_int_mask); /* disable outbound message0 int */
+ writel(intmask_org|ARCMSR_HBCMU_ALL_INTMASKENABLE, &reg->host_int_mask);
+ /* wait firmware ready */
+ do {
+ firmware_state = readl(&reg->outbound_msgaddr1);
+ } while ((firmware_state & ARCMSR_HBCMU_MESSAGE_FIRMWARE_OK) == 0);
+ /* post "get config" instruction */
+ writel(ARCMSR_INBOUND_MESG0_GET_CONFIG, &reg->inbound_msgaddr0);
+ writel(ARCMSR_HBCMU_DRV2IOP_MESSAGE_CMD_DONE, &reg->inbound_doorbell);
+ /* wait message ready */
+ for (Index = 0; Index < 2000; Index++) {
+ if (readl(&reg->outbound_doorbell) & ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE) {
+ writel(ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE_DOORBELL_CLEAR, &reg->outbound_doorbell_clear);/*clear interrupt*/
+ break;
}
- break;
+ udelay(10);
+ } /*max 1 seconds*/
+ if (Index >= 2000) {
+ printk(KERN_NOTICE "arcmsr%d: wait 'get adapter firmware \
+ miscellaneous data' timeout \n", pACB->host->host_no);
+ return false;
}
- return rtnval;
+ count = 8;
+ while (count) {
+ *acb_firm_model = readb(iop_firm_model);
+ acb_firm_model++;
+ iop_firm_model++;
+ count--;
+ }
+ count = 16;
+ while (count) {
+ *acb_firm_version = readb(iop_firm_version);
+ acb_firm_version++;
+ iop_firm_version++;
+ count--;
+ }
+ printk(KERN_NOTICE "Areca RAID Controller%d: F/W %s & Model %s\n",
+ pACB->host->host_no,
+ pACB->firm_version,
+ pACB->firm_model);
+ pACB->firm_request_len = readl(&reg->msgcode_rwbuffer[1]); /*firm_request_len,1,04-07*/
+ pACB->firm_numbers_queue = readl(&reg->msgcode_rwbuffer[2]); /*firm_numbers_queue,2,08-11*/
+ pACB->firm_sdram_size = readl(&reg->msgcode_rwbuffer[3]); /*firm_sdram_size,3,12-15*/
+ pACB->firm_hd_channels = readl(&reg->msgcode_rwbuffer[4]); /*firm_ide_channels,4,16-19*/
+ pACB->firm_cfg_version = readl(&reg->msgcode_rwbuffer[25]); /*firm_cfg_version,25,100-103*/
+ /*all interrupt service will be enable at arcmsr_iop_init*/
+ return true;
+}
+static bool arcmsr_get_firmware_spec(struct AdapterControlBlock *acb)
+{
+ if (acb->adapter_type == ACB_ADAPTER_TYPE_A)
+ return arcmsr_get_hba_config(acb);
+ else if (acb->adapter_type == ACB_ADAPTER_TYPE_B)
+ return arcmsr_get_hbb_config(acb);
+ else
+ return arcmsr_get_hbc_config(acb);
}
-static void arcmsr_polling_hba_ccbdone(struct AdapterControlBlock *acb,
+static int arcmsr_polling_hba_ccbdone(struct AdapterControlBlock *acb,
struct CommandControlBlock *poll_ccb)
{
struct MessageUnit_A __iomem *reg = acb->pmuA;
struct CommandControlBlock *ccb;
+ struct ARCMSR_CDB *arcmsr_cdb;
uint32_t flag_ccb, outbound_intstatus, poll_ccb_done = 0, poll_count = 0;
-
+ int rtn;
+ bool error;
polling_hba_ccb_retry:
poll_count++;
outbound_intstatus = readl(&reg->outbound_intstatus) & acb->outbound_int_enable;
writel(outbound_intstatus, &reg->outbound_intstatus);/*clear interrupt*/
while (1) {
if ((flag_ccb = readl(&reg->outbound_queueport)) == 0xFFFFFFFF) {
- if (poll_ccb_done)
+ if (poll_ccb_done){
+ rtn = SUCCESS;
break;
- else {
+ }else {
msleep(25);
- if (poll_count > 100)
+ if (poll_count > 100){
+ rtn = FAILED;
break;
+ }
goto polling_hba_ccb_retry;
}
}
- ccb = (struct CommandControlBlock *)(acb->vir2phy_offset + (flag_ccb << 5));
+ arcmsr_cdb = (struct ARCMSR_CDB *)(acb->vir2phy_offset + (flag_ccb << 5));
+ ccb = container_of(arcmsr_cdb, struct CommandControlBlock, arcmsr_cdb);
poll_ccb_done = (ccb == poll_ccb) ? 1:0;
if ((ccb->acb != acb) || (ccb->startdone != ARCMSR_CCB_START)) {
if ((ccb->startdone == ARCMSR_CCB_ABORTED) || (ccb == poll_ccb)) {
@@ -2081,8 +2365,7 @@ static void arcmsr_polling_hba_ccbdone(struct AdapterControlBlock *acb,
, ccb->pcmd->device->lun
, ccb);
ccb->pcmd->result = DID_ABORT << 16;
- arcmsr_ccb_complete(ccb, 1);
- poll_ccb_done = 1;
+ arcmsr_ccb_complete(ccb);
continue;
}
printk(KERN_NOTICE "arcmsr%d: polling get an illegal ccb"
@@ -2093,86 +2376,156 @@ static void arcmsr_polling_hba_ccbdone(struct AdapterControlBlock *acb,
, atomic_read(&acb->ccboutstandingcount));
continue;
}
- arcmsr_report_ccb_state(acb, ccb, flag_ccb);
+ error = (flag_ccb & ARCMSR_CCBREPLY_FLAG_ERROR_MODE0) ? true : false;
+ arcmsr_report_ccb_state(acb, ccb, error);
}
+ return rtn;
}
-static void arcmsr_polling_hbb_ccbdone(struct AdapterControlBlock *acb,
+static int arcmsr_polling_hbb_ccbdone(struct AdapterControlBlock *acb,
struct CommandControlBlock *poll_ccb)
{
- struct MessageUnit_B *reg = acb->pmuB;
- struct CommandControlBlock *ccb;
- uint32_t flag_ccb, poll_ccb_done = 0, poll_count = 0;
- int index;
-
+ struct MessageUnit_B *reg = acb->pmuB;
+ struct ARCMSR_CDB *arcmsr_cdb;
+ struct CommandControlBlock *ccb;
+ uint32_t flag_ccb, poll_ccb_done = 0, poll_count = 0;
+ int index, rtn;
+ bool error;
polling_hbb_ccb_retry:
- poll_count++;
- /* clear doorbell interrupt */
- writel(ARCMSR_DOORBELL_INT_CLEAR_PATTERN, reg->iop2drv_doorbell_reg);
- while (1) {
- index = reg->doneq_index;
- if ((flag_ccb = readl(&reg->done_qbuffer[index])) == 0) {
- if (poll_ccb_done)
+ poll_count++;
+ /* clear doorbell interrupt */
+ writel(ARCMSR_DOORBELL_INT_CLEAR_PATTERN, reg->iop2drv_doorbell);
+ while(1){
+ index = reg->doneq_index;
+ if ((flag_ccb = readl(&reg->done_qbuffer[index])) == 0) {
+ if (poll_ccb_done){
+ rtn = SUCCESS;
+ break;
+ }else {
+ msleep(25);
+ if (poll_count > 100){
+ rtn = FAILED;
break;
- else {
- msleep(25);
- if (poll_count > 100)
- break;
- goto polling_hbb_ccb_retry;
}
+ goto polling_hbb_ccb_retry;
+ }
+ }
+ writel(0, &reg->done_qbuffer[index]);
+ index++;
+ /*if last index number set it to 0 */
+ index %= ARCMSR_MAX_HBB_POSTQUEUE;
+ reg->doneq_index = index;
+ /* check if command done with no error*/
+ arcmsr_cdb = (struct ARCMSR_CDB *)(acb->vir2phy_offset + (flag_ccb << 5));
+ ccb = container_of(arcmsr_cdb, struct CommandControlBlock, arcmsr_cdb);
+ poll_ccb_done = (ccb == poll_ccb) ? 1:0;
+ if ((ccb->acb != acb) || (ccb->startdone != ARCMSR_CCB_START)) {
+ if ((ccb->startdone == ARCMSR_CCB_ABORTED) || (ccb == poll_ccb)) {
+ printk(KERN_NOTICE "arcmsr%d: scsi id = %d lun = %d ccb = '0x%p'"
+ " poll command abort successfully \n"
+ ,acb->host->host_no
+ ,ccb->pcmd->device->id
+ ,ccb->pcmd->device->lun
+ ,ccb);
+ ccb->pcmd->result = DID_ABORT << 16;
+ arcmsr_ccb_complete(ccb);
+ continue;
}
- writel(0, &reg->done_qbuffer[index]);
- index++;
- /*if last index number set it to 0 */
- index %= ARCMSR_MAX_HBB_POSTQUEUE;
- reg->doneq_index = index;
- /* check ifcommand done with no error*/
- ccb = (struct CommandControlBlock *)\
- (acb->vir2phy_offset + (flag_ccb << 5));/*frame must be 32 bytes aligned*/
- poll_ccb_done = (ccb == poll_ccb) ? 1:0;
- if ((ccb->acb != acb) || (ccb->startdone != ARCMSR_CCB_START)) {
- if ((ccb->startdone == ARCMSR_CCB_ABORTED) || (ccb == poll_ccb)) {
- printk(KERN_NOTICE "arcmsr%d: \
- scsi id = %d lun = %d ccb = '0x%p' poll command abort successfully \n"
- ,acb->host->host_no
- ,ccb->pcmd->device->id
- ,ccb->pcmd->device->lun
- ,ccb);
- ccb->pcmd->result = DID_ABORT << 16;
- arcmsr_ccb_complete(ccb, 1);
- continue;
+ printk(KERN_NOTICE "arcmsr%d: polling get an illegal ccb"
+ " command done ccb = '0x%p'"
+ "ccboutstandingcount = %d \n"
+ , acb->host->host_no
+ , ccb
+ , atomic_read(&acb->ccboutstandingcount));
+ continue;
+ }
+ error = (flag_ccb & ARCMSR_CCBREPLY_FLAG_ERROR_MODE0) ? true : false;
+ arcmsr_report_ccb_state(acb, ccb, error);
+ }
+ return rtn;
+}
+
+static int arcmsr_polling_hbc_ccbdone(struct AdapterControlBlock *acb, struct CommandControlBlock *poll_ccb)
+{
+ struct MessageUnit_C *reg = (struct MessageUnit_C *)acb->pmuC;
+ uint32_t flag_ccb, ccb_cdb_phy;
+ struct ARCMSR_CDB *arcmsr_cdb;
+ bool error;
+ struct CommandControlBlock *pCCB;
+ uint32_t poll_ccb_done = 0, poll_count = 0;
+ int rtn;
+polling_hbc_ccb_retry:
+ poll_count++;
+ while (1) {
+ if ((readl(&reg->host_int_status) & ARCMSR_HBCMU_OUTBOUND_POSTQUEUE_ISR) == 0) {
+ if (poll_ccb_done) {
+ rtn = SUCCESS;
+ break;
+ } else {
+ msleep(25);
+ if (poll_count > 100) {
+ rtn = FAILED;
+ break;
}
- printk(KERN_NOTICE "arcmsr%d: polling get an illegal ccb"
- " command done ccb = '0x%p'"
- "ccboutstandingcount = %d \n"
+ goto polling_hbc_ccb_retry;
+ }
+ }
+ flag_ccb = readl(&reg->outbound_queueport_low);
+ ccb_cdb_phy = (flag_ccb & 0xFFFFFFF0);
+ arcmsr_cdb = (struct ARCMSR_CDB *)(acb->vir2phy_offset + ccb_cdb_phy);/*frame must be 32 bytes aligned*/
+ pCCB = container_of(arcmsr_cdb, struct CommandControlBlock, arcmsr_cdb);
+ poll_ccb_done = (pCCB == poll_ccb) ? 1 : 0;
+ /* check ifcommand done with no error*/
+ if ((pCCB->acb != acb) || (pCCB->startdone != ARCMSR_CCB_START)) {
+ if (pCCB->startdone == ARCMSR_CCB_ABORTED) {
+ printk(KERN_NOTICE "arcmsr%d: scsi id = %d lun = %d ccb = '0x%p'"
+ " poll command abort successfully \n"
, acb->host->host_no
- , ccb
- , atomic_read(&acb->ccboutstandingcount));
+ , pCCB->pcmd->device->id
+ , pCCB->pcmd->device->lun
+ , pCCB);
+ pCCB->pcmd->result = DID_ABORT << 16;
+ arcmsr_ccb_complete(pCCB);
continue;
}
- arcmsr_report_ccb_state(acb, ccb, flag_ccb);
- } /*drain reply FIFO*/
+ printk(KERN_NOTICE "arcmsr%d: polling get an illegal ccb"
+ " command done ccb = '0x%p'"
+ "ccboutstandingcount = %d \n"
+ , acb->host->host_no
+ , pCCB
+ , atomic_read(&acb->ccboutstandingcount));
+ continue;
+ }
+ error = (flag_ccb & ARCMSR_CCBREPLY_FLAG_ERROR_MODE1) ? true : false;
+ arcmsr_report_ccb_state(acb, pCCB, error);
+ }
+ return rtn;
}
-
-static void arcmsr_polling_ccbdone(struct AdapterControlBlock *acb,
+static int arcmsr_polling_ccbdone(struct AdapterControlBlock *acb,
struct CommandControlBlock *poll_ccb)
{
+ int rtn = 0;
switch (acb->adapter_type) {
case ACB_ADAPTER_TYPE_A: {
- arcmsr_polling_hba_ccbdone(acb,poll_ccb);
+ rtn = arcmsr_polling_hba_ccbdone(acb, poll_ccb);
}
break;
case ACB_ADAPTER_TYPE_B: {
- arcmsr_polling_hbb_ccbdone(acb,poll_ccb);
+ rtn = arcmsr_polling_hbb_ccbdone(acb, poll_ccb);
+ }
+ break;
+ case ACB_ADAPTER_TYPE_C: {
+ rtn = arcmsr_polling_hbc_ccbdone(acb, poll_ccb);
}
}
+ return rtn;
}
static int arcmsr_iop_confirm(struct AdapterControlBlock *acb)
{
- uint32_t cdb_phyaddr, ccb_phyaddr_hi32;
+ uint32_t cdb_phyaddr, cdb_phyaddr_hi32;
dma_addr_t dma_coherent_handle;
/*
********************************************************************
@@ -2182,7 +2535,8 @@ static int arcmsr_iop_confirm(struct AdapterControlBlock *acb)
*/
dma_coherent_handle = acb->dma_coherent_handle;
cdb_phyaddr = (uint32_t)(dma_coherent_handle);
- ccb_phyaddr_hi32 = (uint32_t)((cdb_phyaddr >> 16) >> 16);
+ cdb_phyaddr_hi32 = (uint32_t)((cdb_phyaddr >> 16) >> 16);
+ acb->cdb_phyaddr_hi32 = cdb_phyaddr_hi32;
/*
***********************************************************************
** if adapter type B, set window of "post command Q"
@@ -2191,16 +2545,16 @@ static int arcmsr_iop_confirm(struct AdapterControlBlock *acb)
switch (acb->adapter_type) {
case ACB_ADAPTER_TYPE_A: {
- if (ccb_phyaddr_hi32 != 0) {
+ if (cdb_phyaddr_hi32 != 0) {
struct MessageUnit_A __iomem *reg = acb->pmuA;
uint32_t intmask_org;
intmask_org = arcmsr_disable_outbound_ints(acb);
writel(ARCMSR_SIGNATURE_SET_CONFIG, \
&reg->message_rwbuffer[0]);
- writel(ccb_phyaddr_hi32, &reg->message_rwbuffer[1]);
+ writel(cdb_phyaddr_hi32, &reg->message_rwbuffer[1]);
writel(ARCMSR_INBOUND_MESG0_SET_CONFIG, \
&reg->inbound_msgaddr0);
- if (arcmsr_hba_wait_msgint_ready(acb)) {
+ if (!arcmsr_hba_wait_msgint_ready(acb)) {
printk(KERN_NOTICE "arcmsr%d: ""set ccb high \
part physical address timeout\n",
acb->host->host_no);
@@ -2220,19 +2574,18 @@ static int arcmsr_iop_confirm(struct AdapterControlBlock *acb)
intmask_org = arcmsr_disable_outbound_ints(acb);
reg->postq_index = 0;
reg->doneq_index = 0;
- writel(ARCMSR_MESSAGE_SET_POST_WINDOW, reg->drv2iop_doorbell_reg);
- if (arcmsr_hbb_wait_msgint_ready(acb)) {
+ writel(ARCMSR_MESSAGE_SET_POST_WINDOW, reg->drv2iop_doorbell);
+ if (!arcmsr_hbb_wait_msgint_ready(acb)) {
printk(KERN_NOTICE "arcmsr%d:can not set diver mode\n", \
acb->host->host_no);
return 1;
}
- post_queue_phyaddr = cdb_phyaddr + ARCMSR_MAX_FREECCB_NUM * \
- sizeof(struct CommandControlBlock) + offsetof(struct MessageUnit_B, post_qbuffer) ;
- rwbuffer = reg->msgcode_rwbuffer_reg;
+ post_queue_phyaddr = acb->dma_coherent_handle_hbb_mu;
+ rwbuffer = reg->message_rwbuffer;
/* driver "set config" signature */
writel(ARCMSR_SIGNATURE_SET_CONFIG, rwbuffer++);
/* normal should be zero */
- writel(ccb_phyaddr_hi32, rwbuffer++);
+ writel(cdb_phyaddr_hi32, rwbuffer++);
/* postQ size (256 + 8)*4 */
writel(post_queue_phyaddr, rwbuffer++);
/* doneQ size (256 + 8)*4 */
@@ -2240,22 +2593,37 @@ static int arcmsr_iop_confirm(struct AdapterControlBlock *acb)
/* ccb maxQ size must be --> [(256 + 8)*4]*/
writel(1056, rwbuffer);
- writel(ARCMSR_MESSAGE_SET_CONFIG, reg->drv2iop_doorbell_reg);
- if (arcmsr_hbb_wait_msgint_ready(acb)) {
+ writel(ARCMSR_MESSAGE_SET_CONFIG, reg->drv2iop_doorbell);
+ if (!arcmsr_hbb_wait_msgint_ready(acb)) {
printk(KERN_NOTICE "arcmsr%d: 'set command Q window' \
timeout \n",acb->host->host_no);
return 1;
}
-
- writel(ARCMSR_MESSAGE_START_DRIVER_MODE, reg->drv2iop_doorbell_reg);
- if (arcmsr_hbb_wait_msgint_ready(acb)) {
- printk(KERN_NOTICE "arcmsr%d: 'can not set diver mode \n"\
- ,acb->host->host_no);
- return 1;
- }
+ arcmsr_hbb_enable_driver_mode(acb);
arcmsr_enable_outbound_ints(acb, intmask_org);
}
break;
+ case ACB_ADAPTER_TYPE_C: {
+ if (cdb_phyaddr_hi32 != 0) {
+ struct MessageUnit_C *reg = (struct MessageUnit_C *)acb->pmuC;
+
+ if (cdb_phyaddr_hi32 != 0) {
+ unsigned char Retries = 0x00;
+ do {
+ printk(KERN_NOTICE "arcmsr%d: cdb_phyaddr_hi32=0x%x \n", acb->adapter_index, cdb_phyaddr_hi32);
+ } while (Retries++ < 100);
+ }
+ writel(ARCMSR_SIGNATURE_SET_CONFIG, &reg->msgcode_rwbuffer[0]);
+ writel(cdb_phyaddr_hi32, &reg->msgcode_rwbuffer[1]);
+ writel(ARCMSR_INBOUND_MESG0_SET_CONFIG, &reg->inbound_msgaddr0);
+ writel(ARCMSR_HBCMU_DRV2IOP_MESSAGE_CMD_DONE, &reg->inbound_doorbell);
+ if (!arcmsr_hbc_wait_msgint_ready(acb)) {
+ printk(KERN_NOTICE "arcmsr%d: 'set command Q window' \
+ timeout \n", acb->host->host_no);
+ return 1;
+ }
+ }
+ }
}
return 0;
}
@@ -2263,7 +2631,6 @@ static int arcmsr_iop_confirm(struct AdapterControlBlock *acb)
static void arcmsr_wait_firmware_ready(struct AdapterControlBlock *acb)
{
uint32_t firmware_state = 0;
-
switch (acb->adapter_type) {
case ACB_ADAPTER_TYPE_A: {
@@ -2277,62 +2644,81 @@ static void arcmsr_wait_firmware_ready(struct AdapterControlBlock *acb)
case ACB_ADAPTER_TYPE_B: {
struct MessageUnit_B *reg = acb->pmuB;
do {
- firmware_state = readl(reg->iop2drv_doorbell_reg);
+ firmware_state = readl(reg->iop2drv_doorbell);
} while ((firmware_state & ARCMSR_MESSAGE_FIRMWARE_OK) == 0);
- writel(ARCMSR_DRV2IOP_END_OF_INTERRUPT, reg->drv2iop_doorbell_reg);
+ writel(ARCMSR_DRV2IOP_END_OF_INTERRUPT, reg->drv2iop_doorbell);
}
break;
+ case ACB_ADAPTER_TYPE_C: {
+ struct MessageUnit_C *reg = (struct MessageUnit_C *)acb->pmuC;
+ do {
+ firmware_state = readl(&reg->outbound_msgaddr1);
+ } while ((firmware_state & ARCMSR_HBCMU_MESSAGE_FIRMWARE_OK) == 0);
+ }
}
}
static void arcmsr_request_hba_device_map(struct AdapterControlBlock *acb)
{
struct MessageUnit_A __iomem *reg = acb->pmuA;
-
- if (unlikely(atomic_read(&acb->rq_map_token) == 0)) {
- acb->fw_state = false;
+ if (unlikely(atomic_read(&acb->rq_map_token) == 0) || ((acb->acb_flags & ACB_F_BUS_RESET) != 0 ) || ((acb->acb_flags & ACB_F_ABORT) != 0 )){
+ return;
} else {
- /*to prevent rq_map_token from changing by other interrupt, then
- avoid the dead-lock*/
- acb->fw_state = true;
- atomic_dec(&acb->rq_map_token);
- if (!(acb->fw_state) ||
- (acb->ante_token_value == atomic_read(&acb->rq_map_token))) {
+ acb->fw_flag = FW_NORMAL;
+ if (atomic_read(&acb->ante_token_value) == atomic_read(&acb->rq_map_token)){
atomic_set(&acb->rq_map_token, 16);
}
- acb->ante_token_value = atomic_read(&acb->rq_map_token);
+ atomic_set(&acb->ante_token_value, atomic_read(&acb->rq_map_token));
+ if (atomic_dec_and_test(&acb->rq_map_token))
+ return;
writel(ARCMSR_INBOUND_MESG0_GET_CONFIG, &reg->inbound_msgaddr0);
+ mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ));
}
- mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6000));
return;
}
static void arcmsr_request_hbb_device_map(struct AdapterControlBlock *acb)
{
struct MessageUnit_B __iomem *reg = acb->pmuB;
+ if (unlikely(atomic_read(&acb->rq_map_token) == 0) || ((acb->acb_flags & ACB_F_BUS_RESET) != 0 ) || ((acb->acb_flags & ACB_F_ABORT) != 0 )){
+ return;
+ } else {
+ acb->fw_flag = FW_NORMAL;
+ if (atomic_read(&acb->ante_token_value) == atomic_read(&acb->rq_map_token)) {
+ atomic_set(&acb->rq_map_token,16);
+ }
+ atomic_set(&acb->ante_token_value, atomic_read(&acb->rq_map_token));
+ if(atomic_dec_and_test(&acb->rq_map_token))
+ return;
+ writel(ARCMSR_MESSAGE_GET_CONFIG, reg->drv2iop_doorbell);
+ mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ));
+ }
+ return;
+}
- if (unlikely(atomic_read(&acb->rq_map_token) == 0)) {
- acb->fw_state = false;
+static void arcmsr_request_hbc_device_map(struct AdapterControlBlock *acb)
+{
+ struct MessageUnit_C __iomem *reg = acb->pmuC;
+ if (unlikely(atomic_read(&acb->rq_map_token) == 0) || ((acb->acb_flags & ACB_F_BUS_RESET) != 0) || ((acb->acb_flags & ACB_F_ABORT) != 0)) {
+ return;
} else {
- /*to prevent rq_map_token from changing by other interrupt, then
- avoid the dead-lock*/
- acb->fw_state = true;
- atomic_dec(&acb->rq_map_token);
- if (!(acb->fw_state) ||
- (acb->ante_token_value == atomic_read(&acb->rq_map_token))) {
+ acb->fw_flag = FW_NORMAL;
+ if (atomic_read(&acb->ante_token_value) == atomic_read(&acb->rq_map_token)) {
atomic_set(&acb->rq_map_token, 16);
}
- acb->ante_token_value = atomic_read(&acb->rq_map_token);
- writel(ARCMSR_MESSAGE_GET_CONFIG, reg->drv2iop_doorbell_reg);
+ atomic_set(&acb->ante_token_value, atomic_read(&acb->rq_map_token));
+ if (atomic_dec_and_test(&acb->rq_map_token))
+ return;
+ writel(ARCMSR_INBOUND_MESG0_GET_CONFIG, &reg->inbound_msgaddr0);
+ writel(ARCMSR_HBCMU_DRV2IOP_MESSAGE_CMD_DONE, &reg->inbound_doorbell);
+ mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ));
}
- mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6000));
return;
}
static void arcmsr_request_device_map(unsigned long pacb)
{
struct AdapterControlBlock *acb = (struct AdapterControlBlock *)pacb;
-
switch (acb->adapter_type) {
case ACB_ADAPTER_TYPE_A: {
arcmsr_request_hba_device_map(acb);
@@ -2342,6 +2728,9 @@ static void arcmsr_request_device_map(unsigned long pacb)
arcmsr_request_hbb_device_map(acb);
}
break;
+ case ACB_ADAPTER_TYPE_C: {
+ arcmsr_request_hbc_device_map(acb);
+ }
}
}
@@ -2350,7 +2739,7 @@ static void arcmsr_start_hba_bgrb(struct AdapterControlBlock *acb)
struct MessageUnit_A __iomem *reg = acb->pmuA;
acb->acb_flags |= ACB_F_MSG_START_BGRB;
writel(ARCMSR_INBOUND_MESG0_START_BGRB, &reg->inbound_msgaddr0);
- if (arcmsr_hba_wait_msgint_ready(acb)) {
+ if (!arcmsr_hba_wait_msgint_ready(acb)) {
printk(KERN_NOTICE "arcmsr%d: wait 'start adapter background \
rebulid' timeout \n", acb->host->host_no);
}
@@ -2360,13 +2749,25 @@ static void arcmsr_start_hbb_bgrb(struct AdapterControlBlock *acb)
{
struct MessageUnit_B *reg = acb->pmuB;
acb->acb_flags |= ACB_F_MSG_START_BGRB;
- writel(ARCMSR_MESSAGE_START_BGRB, reg->drv2iop_doorbell_reg);
- if (arcmsr_hbb_wait_msgint_ready(acb)) {
+ writel(ARCMSR_MESSAGE_START_BGRB, reg->drv2iop_doorbell);
+ if (!arcmsr_hbb_wait_msgint_ready(acb)) {
printk(KERN_NOTICE "arcmsr%d: wait 'start adapter background \
rebulid' timeout \n",acb->host->host_no);
}
}
+static void arcmsr_start_hbc_bgrb(struct AdapterControlBlock *pACB)
+{
+ struct MessageUnit_C *phbcmu = (struct MessageUnit_C *)pACB->pmuC;
+ pACB->acb_flags |= ACB_F_MSG_START_BGRB;
+ writel(ARCMSR_INBOUND_MESG0_START_BGRB, &phbcmu->inbound_msgaddr0);
+ writel(ARCMSR_HBCMU_DRV2IOP_MESSAGE_CMD_DONE, &phbcmu->inbound_doorbell);
+ if (!arcmsr_hbc_wait_msgint_ready(pACB)) {
+ printk(KERN_NOTICE "arcmsr%d: wait 'start adapter background \
+ rebulid' timeout \n", pACB->host->host_no);
+ }
+ return;
+}
static void arcmsr_start_adapter_bgrb(struct AdapterControlBlock *acb)
{
switch (acb->adapter_type) {
@@ -2376,6 +2777,8 @@ static void arcmsr_start_adapter_bgrb(struct AdapterControlBlock *acb)
case ACB_ADAPTER_TYPE_B:
arcmsr_start_hbb_bgrb(acb);
break;
+ case ACB_ADAPTER_TYPE_C:
+ arcmsr_start_hbc_bgrb(acb);
}
}
@@ -2396,11 +2799,19 @@ static void arcmsr_clear_doorbell_queue_buffer(struct AdapterControlBlock *acb)
case ACB_ADAPTER_TYPE_B: {
struct MessageUnit_B *reg = acb->pmuB;
/*clear interrupt and message state*/
- writel(ARCMSR_MESSAGE_INT_CLEAR_PATTERN, reg->iop2drv_doorbell_reg);
- writel(ARCMSR_DRV2IOP_DATA_READ_OK, reg->drv2iop_doorbell_reg);
+ writel(ARCMSR_MESSAGE_INT_CLEAR_PATTERN, reg->iop2drv_doorbell);
+ writel(ARCMSR_DRV2IOP_DATA_READ_OK, reg->drv2iop_doorbell);
/* let IOP know data has been read */
}
break;
+ case ACB_ADAPTER_TYPE_C: {
+ struct MessageUnit_C *reg = (struct MessageUnit_C *)acb->pmuC;
+ uint32_t outbound_doorbell;
+ /* empty doorbell Qbuffer if door bell ringed */
+ outbound_doorbell = readl(&reg->outbound_doorbell);
+ writel(outbound_doorbell, &reg->outbound_doorbell_clear);
+ writel(ARCMSR_HBCMU_DRV2IOP_DATA_READ_OK, &reg->inbound_doorbell);
+ }
}
}
@@ -2412,13 +2823,15 @@ static void arcmsr_enable_eoi_mode(struct AdapterControlBlock *acb)
case ACB_ADAPTER_TYPE_B:
{
struct MessageUnit_B *reg = acb->pmuB;
- writel(ARCMSR_MESSAGE_ACTIVE_EOI_MODE, reg->drv2iop_doorbell_reg);
- if(arcmsr_hbb_wait_msgint_ready(acb)) {
+ writel(ARCMSR_MESSAGE_ACTIVE_EOI_MODE, reg->drv2iop_doorbell);
+ if (!arcmsr_hbb_wait_msgint_ready(acb)) {
printk(KERN_NOTICE "ARCMSR IOP enables EOI_MODE TIMEOUT");
return;
}
}
break;
+ case ACB_ADAPTER_TYPE_C:
+ return;
}
return;
}
@@ -2426,15 +2839,33 @@ static void arcmsr_enable_eoi_mode(struct AdapterControlBlock *acb)
static void arcmsr_hardware_reset(struct AdapterControlBlock *acb)
{
uint8_t value[64];
- int i;
-
+ int i, count = 0;
+ struct MessageUnit_A __iomem *pmuA = acb->pmuA;
+ struct MessageUnit_C __iomem *pmuC = acb->pmuC;
+ u32 temp = 0;
/* backup pci config data */
+ printk(KERN_NOTICE "arcmsr%d: executing hw bus reset .....\n", acb->host->host_no);
for (i = 0; i < 64; i++) {
pci_read_config_byte(acb->pdev, i, &value[i]);
}
/* hardware reset signal */
- pci_write_config_byte(acb->pdev, 0x84, 0x20);
- msleep(1000);
+ if ((acb->dev_id == 0x1680)) {
+ writel(ARCMSR_ARC1680_BUS_RESET, &pmuA->reserved1[0]);
+ } else if ((acb->dev_id == 0x1880)) {
+ do {
+ count++;
+ writel(0xF, &pmuC->write_sequence);
+ writel(0x4, &pmuC->write_sequence);
+ writel(0xB, &pmuC->write_sequence);
+ writel(0x2, &pmuC->write_sequence);
+ writel(0x7, &pmuC->write_sequence);
+ writel(0xD, &pmuC->write_sequence);
+ } while ((((temp = readl(&pmuC->host_diagnostic)) | ARCMSR_ARC1880_DiagWrite_ENABLE) == 0) && (count < 5));
+ writel(ARCMSR_ARC1880_RESET_ADAPTER, &pmuC->host_diagnostic);
+ } else {
+ pci_write_config_byte(acb->pdev, 0x84, 0x20);
+ }
+ msleep(2000);
/* write back pci config data */
for (i = 0; i < 64; i++) {
pci_write_config_byte(acb->pdev, i, value[i]);
@@ -2442,50 +2873,13 @@ static void arcmsr_hardware_reset(struct AdapterControlBlock *acb)
msleep(1000);
return;
}
-/*
-****************************************************************************
-****************************************************************************
-*/
-#ifdef CONFIG_SCSI_ARCMSR_RESET
- int arcmsr_sleep_for_bus_reset(struct scsi_cmnd *cmd)
- {
- struct Scsi_Host *shost = NULL;
- spinlock_t *host_lock = NULL;
- int i, isleep;
-
- shost = cmd->device->host;
- host_lock = shost->host_lock;
-
- printk(KERN_NOTICE "Host %d bus reset over, sleep %d seconds (busy %d, can queue %d) ...........\n",
- shost->host_no, sleeptime, shost->host_busy, shost->can_queue);
- isleep = sleeptime / 10;
- spin_unlock_irq(host_lock);
- if (isleep > 0) {
- for (i = 0; i < isleep; i++) {
- msleep(10000);
- printk(KERN_NOTICE "^%d^\n", i);
- }
- }
-
- isleep = sleeptime % 10;
- if (isleep > 0) {
- msleep(isleep * 1000);
- printk(KERN_NOTICE "^v^\n");
- }
- spin_lock_irq(host_lock);
- printk(KERN_NOTICE "***** wake up *****\n");
- return 0;
- }
-#endif
static void arcmsr_iop_init(struct AdapterControlBlock *acb)
{
uint32_t intmask_org;
-
- /* disable all outbound interrupt */
- intmask_org = arcmsr_disable_outbound_ints(acb);
+ /* disable all outbound interrupt */
+ intmask_org = arcmsr_disable_outbound_ints(acb);
arcmsr_wait_firmware_ready(acb);
arcmsr_iop_confirm(acb);
- arcmsr_get_firmware_spec(acb, 1);
/*start background rebuild*/
arcmsr_start_adapter_bgrb(acb);
/* empty doorbell Qbuffer if door bell ringed */
@@ -2502,20 +2896,17 @@ static uint8_t arcmsr_iop_reset(struct AdapterControlBlock *acb)
uint32_t intmask_org;
uint8_t rtnval = 0x00;
int i = 0;
-
if (atomic_read(&acb->ccboutstandingcount) != 0) {
/* disable all outbound interrupt */
intmask_org = arcmsr_disable_outbound_ints(acb);
/* talk to iop 331 outstanding command aborted */
rtnval = arcmsr_abort_allcmd(acb);
- /* wait for 3 sec for all command aborted*/
- ssleep(3);
/* clear all outbound posted Q */
arcmsr_done4abort_postqueue(acb);
for (i = 0; i < ARCMSR_MAX_FREECCB_NUM; i++) {
ccb = acb->pccb_pool[i];
if (ccb->startdone == ARCMSR_CCB_START) {
- arcmsr_ccb_complete(ccb, 1);
+ arcmsr_ccb_complete(ccb);
}
}
atomic_set(&acb->ccboutstandingcount, 0);
@@ -2530,94 +2921,190 @@ static int arcmsr_bus_reset(struct scsi_cmnd *cmd)
{
struct AdapterControlBlock *acb =
(struct AdapterControlBlock *)cmd->device->host->hostdata;
- int retry = 0;
-
- if (acb->acb_flags & ACB_F_BUS_RESET)
- return SUCCESS;
-
- printk(KERN_NOTICE "arcmsr%d: bus reset ..... \n", acb->adapter_index);
- acb->acb_flags |= ACB_F_BUS_RESET;
+ uint32_t intmask_org, outbound_doorbell;
+ int retry_count = 0;
+ int rtn = FAILED;
+ acb = (struct AdapterControlBlock *) cmd->device->host->hostdata;
+ printk(KERN_ERR "arcmsr: executing bus reset eh.....num_resets = %d, num_aborts = %d \n", acb->num_resets, acb->num_aborts);
acb->num_resets++;
- while (atomic_read(&acb->ccboutstandingcount) != 0 && retry < 4) {
- arcmsr_interrupt(acb);
- retry++;
- }
- if (arcmsr_iop_reset(acb)) {
- switch (acb->adapter_type) {
- case ACB_ADAPTER_TYPE_A: {
- printk(KERN_NOTICE "arcmsr%d: do hardware bus reset, num_resets = %d num_aborts = %d \n",
- acb->adapter_index, acb->num_resets, acb->num_aborts);
- arcmsr_hardware_reset(acb);
- acb->acb_flags |= ACB_F_FIRMWARE_TRAP;
- acb->acb_flags &= ~ACB_F_IOP_INITED;
- #ifdef CONFIG_SCSI_ARCMSR_RESET
- struct MessageUnit_A __iomem *reg = acb->pmuA;
- uint32_t intmask_org, outbound_doorbell;
- int retry_count = 0;
+ switch(acb->adapter_type){
+ case ACB_ADAPTER_TYPE_A:{
+ if (acb->acb_flags & ACB_F_BUS_RESET){
+ long timeout;
+ printk(KERN_ERR "arcmsr: there is an bus reset eh proceeding.......\n");
+ timeout = wait_event_timeout(wait_q, (acb->acb_flags & ACB_F_BUS_RESET) == 0, 220*HZ);
+ if (timeout) {
+ return SUCCESS;
+ }
+ }
+ acb->acb_flags |= ACB_F_BUS_RESET;
+ if (!arcmsr_iop_reset(acb)) {
+ struct MessageUnit_A __iomem *reg;
+ reg = acb->pmuA;
+ arcmsr_hardware_reset(acb);
+ acb->acb_flags &= ~ACB_F_IOP_INITED;
sleep_again:
- arcmsr_sleep_for_bus_reset(cmd);
- if ((readl(&reg->outbound_msgaddr1) &
- ARCMSR_OUTBOUND_MESG1_FIRMWARE_OK) == 0) {
- printk(KERN_NOTICE "arcmsr%d: hardware bus reset and return busy, retry=%d \n",
- acb->host->host_no, retry_count);
- if (retry_count > retrycount) {
- printk(KERN_NOTICE "arcmsr%d: hardware bus reset and return busy, retry aborted \n",
- acb->host->host_no);
- return SUCCESS;
+ arcmsr_sleep_for_bus_reset(cmd);
+ if ((readl(&reg->outbound_msgaddr1) & ARCMSR_OUTBOUND_MESG1_FIRMWARE_OK) == 0) {
+ printk(KERN_ERR "arcmsr%d: waiting for hw bus reset return, retry=%d \n", acb->host->host_no, retry_count);
+ if (retry_count > retrycount) {
+ acb->fw_flag = FW_DEADLOCK;
+ printk(KERN_ERR "arcmsr%d: waiting for hw bus reset return, RETRY TERMINATED!! \n", acb->host->host_no);
+ return FAILED;
+ }
+ retry_count++;
+ goto sleep_again;
+ }
+ acb->acb_flags |= ACB_F_IOP_INITED;
+ /* disable all outbound interrupt */
+ intmask_org = arcmsr_disable_outbound_ints(acb);
+ arcmsr_get_firmware_spec(acb);
+ arcmsr_start_adapter_bgrb(acb);
+ /* clear Qbuffer if door bell ringed */
+ outbound_doorbell = readl(&reg->outbound_doorbell);
+ writel(outbound_doorbell, &reg->outbound_doorbell); /*clear interrupt */
+ writel(ARCMSR_INBOUND_DRIVER_DATA_READ_OK, &reg->inbound_doorbell);
+ /* enable outbound Post Queue,outbound doorbell Interrupt */
+ arcmsr_enable_outbound_ints(acb, intmask_org);
+ atomic_set(&acb->rq_map_token, 16);
+ atomic_set(&acb->ante_token_value, 16);
+ acb->fw_flag = FW_NORMAL;
+ init_timer(&acb->eternal_timer);
+ acb->eternal_timer.expires = jiffies + msecs_to_jiffies(6*HZ);
+ acb->eternal_timer.data = (unsigned long) acb;
+ acb->eternal_timer.function = &arcmsr_request_device_map;
+ add_timer(&acb->eternal_timer);
+ acb->acb_flags &= ~ACB_F_BUS_RESET;
+ rtn = SUCCESS;
+ printk(KERN_ERR "arcmsr: scsi bus reset eh returns with success\n");
+ } else {
+ acb->acb_flags &= ~ACB_F_BUS_RESET;
+ if (atomic_read(&acb->rq_map_token) == 0) {
+ atomic_set(&acb->rq_map_token, 16);
+ atomic_set(&acb->ante_token_value, 16);
+ acb->fw_flag = FW_NORMAL;
+ init_timer(&acb->eternal_timer);
+ acb->eternal_timer.expires = jiffies + msecs_to_jiffies(6*HZ);
+ acb->eternal_timer.data = (unsigned long) acb;
+ acb->eternal_timer.function = &arcmsr_request_device_map;
+ add_timer(&acb->eternal_timer);
+ } else {
+ atomic_set(&acb->rq_map_token, 16);
+ atomic_set(&acb->ante_token_value, 16);
+ acb->fw_flag = FW_NORMAL;
+ mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6*HZ));
+ }
+ rtn = SUCCESS;
}
- retry_count++;
- goto sleep_again;
+ break;
+ }
+ case ACB_ADAPTER_TYPE_B:{
+ acb->acb_flags |= ACB_F_BUS_RESET;
+ if (!arcmsr_iop_reset(acb)) {
+ acb->acb_flags &= ~ACB_F_BUS_RESET;
+ rtn = FAILED;
+ } else {
+ acb->acb_flags &= ~ACB_F_BUS_RESET;
+ if (atomic_read(&acb->rq_map_token) == 0) {
+ atomic_set(&acb->rq_map_token, 16);
+ atomic_set(&acb->ante_token_value, 16);
+ acb->fw_flag = FW_NORMAL;
+ init_timer(&acb->eternal_timer);
+ acb->eternal_timer.expires = jiffies + msecs_to_jiffies(6*HZ);
+ acb->eternal_timer.data = (unsigned long) acb;
+ acb->eternal_timer.function = &arcmsr_request_device_map;
+ add_timer(&acb->eternal_timer);
+ } else {
+ atomic_set(&acb->rq_map_token, 16);
+ atomic_set(&acb->ante_token_value, 16);
+ acb->fw_flag = FW_NORMAL;
+ mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6*HZ));
+ }
+ rtn = SUCCESS;
}
- acb->acb_flags &= ~ACB_F_FIRMWARE_TRAP;
- acb->acb_flags |= ACB_F_IOP_INITED;
- acb->acb_flags &= ~ACB_F_BUS_RESET;
- printk(KERN_NOTICE "arcmsr%d: hardware bus reset and reset ok \n",
- acb->host->host_no);
- /* disable all outbound interrupt */
- intmask_org = arcmsr_disable_outbound_ints(acb);
- arcmsr_get_firmware_spec(acb, 1);
- /*start background rebuild*/
- arcmsr_start_adapter_bgrb(acb);
- /* clear Qbuffer if door bell ringed */
- outbound_doorbell = readl(&reg->outbound_doorbell);
- writel(outbound_doorbell, &reg->outbound_doorbell); /*clear interrupt */
- writel(ARCMSR_INBOUND_DRIVER_DATA_READ_OK, &reg->inbound_doorbell);
- /* enable outbound Post Queue,outbound doorbell Interrupt */
- arcmsr_enable_outbound_ints(acb, intmask_org);
- atomic_set(&acb->rq_map_token, 16);
- init_timer(&acb->eternal_timer);
- acb->eternal_timer.expires = jiffies + msecs_to_jiffies(20*HZ);
- acb->eternal_timer.data = (unsigned long) acb;
- acb->eternal_timer.function = &arcmsr_request_device_map;
- add_timer(&acb->eternal_timer);
- #endif
+ break;
}
+ case ACB_ADAPTER_TYPE_C:{
+ if (acb->acb_flags & ACB_F_BUS_RESET) {
+ long timeout;
+ printk(KERN_ERR "arcmsr: there is an bus reset eh proceeding.......\n");
+ timeout = wait_event_timeout(wait_q, (acb->acb_flags & ACB_F_BUS_RESET) == 0, 220*HZ);
+ if (timeout) {
+ return SUCCESS;
+ }
+ }
+ acb->acb_flags |= ACB_F_BUS_RESET;
+ if (!arcmsr_iop_reset(acb)) {
+ struct MessageUnit_C __iomem *reg;
+ reg = acb->pmuC;
+ arcmsr_hardware_reset(acb);
+ acb->acb_flags &= ~ACB_F_IOP_INITED;
+sleep:
+ arcmsr_sleep_for_bus_reset(cmd);
+ if ((readl(&reg->host_diagnostic) & 0x04) != 0) {
+ printk(KERN_ERR "arcmsr%d: waiting for hw bus reset return, retry=%d \n", acb->host->host_no, retry_count);
+ if (retry_count > retrycount) {
+ acb->fw_flag = FW_DEADLOCK;
+ printk(KERN_ERR "arcmsr%d: waiting for hw bus reset return, RETRY TERMINATED!! \n", acb->host->host_no);
+ return FAILED;
+ }
+ retry_count++;
+ goto sleep;
+ }
+ acb->acb_flags |= ACB_F_IOP_INITED;
+ /* disable all outbound interrupt */
+ intmask_org = arcmsr_disable_outbound_ints(acb);
+ arcmsr_get_firmware_spec(acb);
+ arcmsr_start_adapter_bgrb(acb);
+ /* clear Qbuffer if door bell ringed */
+ outbound_doorbell = readl(&reg->outbound_doorbell);
+ writel(outbound_doorbell, &reg->outbound_doorbell_clear); /*clear interrupt */
+ writel(ARCMSR_HBCMU_DRV2IOP_DATA_READ_OK, &reg->inbound_doorbell);
+ /* enable outbound Post Queue,outbound doorbell Interrupt */
+ arcmsr_enable_outbound_ints(acb, intmask_org);
+ atomic_set(&acb->rq_map_token, 16);
+ atomic_set(&acb->ante_token_value, 16);
+ acb->fw_flag = FW_NORMAL;
+ init_timer(&acb->eternal_timer);
+ acb->eternal_timer.expires = jiffies + msecs_to_jiffies(6 * HZ);
+ acb->eternal_timer.data = (unsigned long) acb;
+ acb->eternal_timer.function = &arcmsr_request_device_map;
+ add_timer(&acb->eternal_timer);
+ acb->acb_flags &= ~ACB_F_BUS_RESET;
+ rtn = SUCCESS;
+ printk(KERN_ERR "arcmsr: scsi bus reset eh returns with success\n");
+ } else {
+ acb->acb_flags &= ~ACB_F_BUS_RESET;
+ if (atomic_read(&acb->rq_map_token) == 0) {
+ atomic_set(&acb->rq_map_token, 16);
+ atomic_set(&acb->ante_token_value, 16);
+ acb->fw_flag = FW_NORMAL;
+ init_timer(&acb->eternal_timer);
+ acb->eternal_timer.expires = jiffies + msecs_to_jiffies(6*HZ);
+ acb->eternal_timer.data = (unsigned long) acb;
+ acb->eternal_timer.function = &arcmsr_request_device_map;
+ add_timer(&acb->eternal_timer);
+ } else {
+ atomic_set(&acb->rq_map_token, 16);
+ atomic_set(&acb->ante_token_value, 16);
+ acb->fw_flag = FW_NORMAL;
+ mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6*HZ));
+ }
+ rtn = SUCCESS;
+ }
break;
- case ACB_ADAPTER_TYPE_B: {
- }
}
- } else {
- acb->acb_flags &= ~ACB_F_BUS_RESET;
}
- return SUCCESS;
+ return rtn;
}
-static void arcmsr_abort_one_cmd(struct AdapterControlBlock *acb,
+static int arcmsr_abort_one_cmd(struct AdapterControlBlock *acb,
struct CommandControlBlock *ccb)
{
- u32 intmask;
-
- ccb->startdone = ARCMSR_CCB_ABORTED;
-
- /*
- ** Wait for 3 sec for all command done.
- */
- ssleep(3);
-
- intmask = arcmsr_disable_outbound_ints(acb);
- arcmsr_polling_ccbdone(acb, ccb);
- arcmsr_enable_outbound_ints(acb, intmask);
+ int rtn;
+ rtn = arcmsr_polling_ccbdone(acb, ccb);
+ return rtn;
}
static int arcmsr_abort(struct scsi_cmnd *cmd)
@@ -2625,10 +3112,11 @@ static int arcmsr_abort(struct scsi_cmnd *cmd)
struct AdapterControlBlock *acb =
(struct AdapterControlBlock *)cmd->device->host->hostdata;
int i = 0;
-
+ int rtn = FAILED;
printk(KERN_NOTICE
"arcmsr%d: abort device command of scsi id = %d lun = %d \n",
acb->host->host_no, cmd->device->id, cmd->device->lun);
+ acb->acb_flags |= ACB_F_ABORT;
acb->num_aborts++;
/*
************************************************
@@ -2637,17 +3125,18 @@ static int arcmsr_abort(struct scsi_cmnd *cmd)
************************************************
*/
if (!atomic_read(&acb->ccboutstandingcount))
- return SUCCESS;
+ return rtn;
for (i = 0; i < ARCMSR_MAX_FREECCB_NUM; i++) {
struct CommandControlBlock *ccb = acb->pccb_pool[i];
if (ccb->startdone == ARCMSR_CCB_START && ccb->pcmd == cmd) {
- arcmsr_abort_one_cmd(acb, ccb);
+ ccb->startdone = ARCMSR_CCB_ABORTED;
+ rtn = arcmsr_abort_one_cmd(acb, ccb);
break;
}
}
-
- return SUCCESS;
+ acb->acb_flags &= ~ACB_F_ABORT;
+ return rtn;
}
static const char *arcmsr_info(struct Scsi_Host *host)
@@ -2657,7 +3146,6 @@ static const char *arcmsr_info(struct Scsi_Host *host)
static char buf[256];
char *type;
int raid6 = 1;
-
switch (acb->pdev->device) {
case PCI_DEVICE_ID_ARECA_1110:
case PCI_DEVICE_ID_ARECA_1200:
@@ -2681,6 +3169,7 @@ static const char *arcmsr_info(struct Scsi_Host *host)
case PCI_DEVICE_ID_ARECA_1381:
case PCI_DEVICE_ID_ARECA_1680:
case PCI_DEVICE_ID_ARECA_1681:
+ case PCI_DEVICE_ID_ARECA_1880:
type = "SAS";
break;
default:
diff --git a/drivers/scsi/be2iscsi/Kconfig b/drivers/scsi/be2iscsi/Kconfig
index 2952fcd008e..84c275fb9f6 100644
--- a/drivers/scsi/be2iscsi/Kconfig
+++ b/drivers/scsi/be2iscsi/Kconfig
@@ -1,6 +1,6 @@
config BE2ISCSI
tristate "ServerEngines' 10Gbps iSCSI - BladeEngine 2"
- depends on PCI && SCSI
+ depends on PCI && SCSI && NET
select SCSI_ISCSI_ATTRS
help
diff --git a/drivers/scsi/be2iscsi/be.h b/drivers/scsi/be2iscsi/be.h
index 136b49cea79..1cb8a5e85c7 100644
--- a/drivers/scsi/be2iscsi/be.h
+++ b/drivers/scsi/be2iscsi/be.h
@@ -128,8 +128,8 @@ struct be_ctrl_info {
#define mcc_timeout 120000 /* 5s timeout */
/* Returns number of pages spanned by the data starting at the given addr */
-#define PAGES_4K_SPANNED(_address, size) \
- ((u32)((((size_t)(_address) & (PAGE_SIZE_4K - 1)) + \
+#define PAGES_4K_SPANNED(_address, size) \
+ ((u32)((((size_t)(_address) & (PAGE_SIZE_4K - 1)) + \
(size) + (PAGE_SIZE_4K - 1)) >> PAGE_SHIFT_4K))
/* Byte offset into the page corresponding to given address */
@@ -137,7 +137,7 @@ struct be_ctrl_info {
((size_t)(addr) & (PAGE_SIZE_4K-1))
/* Returns bit offset within a DWORD of a bitfield */
-#define AMAP_BIT_OFFSET(_struct, field) \
+#define AMAP_BIT_OFFSET(_struct, field) \
(((size_t)&(((_struct *)0)->field))%32)
/* Returns the bit mask of the field that is NOT shifted into location. */
diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c
index cda6642c736..7c7537335c8 100644
--- a/drivers/scsi/be2iscsi/be_cmds.c
+++ b/drivers/scsi/be2iscsi/be_cmds.c
@@ -19,6 +19,86 @@
#include "be_mgmt.h"
#include "be_main.h"
+int beiscsi_pci_soft_reset(struct beiscsi_hba *phba)
+{
+ u32 sreset;
+ u8 *pci_reset_offset = 0;
+ u8 *pci_online0_offset = 0;
+ u8 *pci_online1_offset = 0;
+ u32 pconline0 = 0;
+ u32 pconline1 = 0;
+ u32 i;
+
+ pci_reset_offset = (u8 *)phba->pci_va + BE2_SOFT_RESET;
+ pci_online0_offset = (u8 *)phba->pci_va + BE2_PCI_ONLINE0;
+ pci_online1_offset = (u8 *)phba->pci_va + BE2_PCI_ONLINE1;
+ sreset = readl((void *)pci_reset_offset);
+ sreset |= BE2_SET_RESET;
+ writel(sreset, (void *)pci_reset_offset);
+
+ i = 0;
+ while (sreset & BE2_SET_RESET) {
+ if (i > 64)
+ break;
+ msleep(100);
+ sreset = readl((void *)pci_reset_offset);
+ i++;
+ }
+
+ if (sreset & BE2_SET_RESET) {
+ printk(KERN_ERR "Soft Reset did not deassert\n");
+ return -EIO;
+ }
+ pconline1 = BE2_MPU_IRAM_ONLINE;
+ writel(pconline0, (void *)pci_online0_offset);
+ writel(pconline1, (void *)pci_online1_offset);
+
+ sreset = BE2_SET_RESET;
+ writel(sreset, (void *)pci_reset_offset);
+
+ i = 0;
+ while (sreset & BE2_SET_RESET) {
+ if (i > 64)
+ break;
+ msleep(1);
+ sreset = readl((void *)pci_reset_offset);
+ i++;
+ }
+ if (sreset & BE2_SET_RESET) {
+ printk(KERN_ERR "MPU Online Soft Reset did not deassert\n");
+ return -EIO;
+ }
+ return 0;
+}
+
+int be_chk_reset_complete(struct beiscsi_hba *phba)
+{
+ unsigned int num_loop;
+ u8 *mpu_sem = 0;
+ u32 status;
+
+ num_loop = 1000;
+ mpu_sem = (u8 *)phba->csr_va + MPU_EP_SEMAPHORE;
+ msleep(5000);
+
+ while (num_loop) {
+ status = readl((void *)mpu_sem);
+
+ if ((status & 0x80000000) || (status & 0x0000FFFF) == 0xC000)
+ break;
+ msleep(60);
+ num_loop--;
+ }
+
+ if ((status & 0x80000000) || (!num_loop)) {
+ printk(KERN_ERR "Failed in be_chk_reset_complete"
+ "status = 0x%x\n", status);
+ return -EIO;
+ }
+
+ return 0;
+}
+
void be_mcc_notify(struct beiscsi_hba *phba)
{
struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;
@@ -98,7 +178,7 @@ static int be_mcc_compl_process(struct be_ctrl_info *ctrl,
dev_err(&ctrl->pdev->dev,
"error in cmd completion: status(compl/extd)=%d/%d\n",
compl_status, extd_status);
- return -1;
+ return -EBUSY;
}
return 0;
}
@@ -151,20 +231,20 @@ void beiscsi_async_link_state_process(struct beiscsi_hba *phba,
{
switch (evt->port_link_status) {
case ASYNC_EVENT_LINK_DOWN:
- SE_DEBUG(DBG_LVL_1, "Link Down on Physical Port %d \n",
- evt->physical_port);
+ SE_DEBUG(DBG_LVL_1, "Link Down on Physical Port %d\n",
+ evt->physical_port);
phba->state |= BE_ADAPTER_LINK_DOWN;
iscsi_host_for_each_session(phba->shost,
be2iscsi_fail_session);
break;
case ASYNC_EVENT_LINK_UP:
phba->state = BE_ADAPTER_UP;
- SE_DEBUG(DBG_LVL_1, "Link UP on Physical Port %d \n",
+ SE_DEBUG(DBG_LVL_1, "Link UP on Physical Port %d\n",
evt->physical_port);
break;
default:
SE_DEBUG(DBG_LVL_1, "Unexpected Async Notification %d on"
- "Physical Port %d \n",
+ "Physical Port %d\n",
evt->port_link_status,
evt->physical_port);
}
@@ -199,7 +279,7 @@ int beiscsi_process_mcc(struct beiscsi_hba *phba)
else
SE_DEBUG(DBG_LVL_1,
" Unsupported Async Event, flags"
- " = 0x%08x \n", compl->flags);
+ " = 0x%08x\n", compl->flags);
} else if (compl->flags & CQE_FLAGS_COMPLETED_MASK) {
status = be_mcc_compl_process(ctrl, compl);
@@ -231,7 +311,7 @@ static int be_mcc_wait_compl(struct beiscsi_hba *phba)
}
if (i == mcc_timeout) {
dev_err(&phba->pcidev->dev, "mccq poll timed out\n");
- return -1;
+ return -EBUSY;
}
return 0;
}
@@ -257,7 +337,7 @@ static int be_mbox_db_ready_wait(struct be_ctrl_info *ctrl)
if (cnt > 6000000) {
dev_err(&ctrl->pdev->dev, "mbox_db poll timed out\n");
- return -1;
+ return -EBUSY;
}
if (cnt > 50) {
@@ -286,7 +366,7 @@ int be_mbox_notify(struct be_ctrl_info *ctrl)
status = be_mbox_db_ready_wait(ctrl);
if (status != 0) {
- SE_DEBUG(DBG_LVL_1, " be_mbox_db_ready_wait failed 1\n");
+ SE_DEBUG(DBG_LVL_1, " be_mbox_db_ready_wait failed\n");
return status;
}
val = 0;
@@ -297,19 +377,19 @@ int be_mbox_notify(struct be_ctrl_info *ctrl)
status = be_mbox_db_ready_wait(ctrl);
if (status != 0) {
- SE_DEBUG(DBG_LVL_1, " be_mbox_db_ready_wait failed 2\n");
+ SE_DEBUG(DBG_LVL_1, " be_mbox_db_ready_wait failed\n");
return status;
}
if (be_mcc_compl_is_new(compl)) {
status = be_mcc_compl_process(ctrl, &mbox->compl);
be_mcc_compl_use(compl);
if (status) {
- SE_DEBUG(DBG_LVL_1, "After be_mcc_compl_process \n");
+ SE_DEBUG(DBG_LVL_1, "After be_mcc_compl_process\n");
return status;
}
} else {
dev_err(&ctrl->pdev->dev, "invalid mailbox completion\n");
- return -1;
+ return -EBUSY;
}
return 0;
}
@@ -355,7 +435,7 @@ static int be_mbox_notify_wait(struct beiscsi_hba *phba)
return status;
} else {
dev_err(&phba->pcidev->dev, "invalid mailbox completion\n");
- return -1;
+ return -EBUSY;
}
return 0;
}
@@ -500,7 +580,7 @@ int be_cmd_fw_initialize(struct be_ctrl_info *ctrl)
status = be_mbox_notify(ctrl);
if (status)
- SE_DEBUG(DBG_LVL_1, "be_cmd_fw_initialize Failed \n");
+ SE_DEBUG(DBG_LVL_1, "be_cmd_fw_initialize Failed\n");
spin_unlock(&ctrl->mbox_lock);
return status;
@@ -517,7 +597,7 @@ int beiscsi_cmd_cq_create(struct be_ctrl_info *ctrl,
void *ctxt = &req->context;
int status;
- SE_DEBUG(DBG_LVL_8, "In beiscsi_cmd_cq_create \n");
+ SE_DEBUG(DBG_LVL_8, "In beiscsi_cmd_cq_create\n");
spin_lock(&ctrl->mbox_lock);
memset(wrb, 0, sizeof(*wrb));
@@ -550,7 +630,7 @@ int beiscsi_cmd_cq_create(struct be_ctrl_info *ctrl,
cq->id = le16_to_cpu(resp->cq_id);
cq->created = true;
} else
- SE_DEBUG(DBG_LVL_1, "In be_cmd_cq_create, status=ox%08x \n",
+ SE_DEBUG(DBG_LVL_1, "In be_cmd_cq_create, status=ox%08x\n",
status);
spin_unlock(&ctrl->mbox_lock);
@@ -619,7 +699,7 @@ int beiscsi_cmd_q_destroy(struct be_ctrl_info *ctrl, struct be_queue_info *q,
u8 subsys = 0, opcode = 0;
int status;
- SE_DEBUG(DBG_LVL_8, "In beiscsi_cmd_q_destroy \n");
+ SE_DEBUG(DBG_LVL_8, "In beiscsi_cmd_q_destroy\n");
spin_lock(&ctrl->mbox_lock);
memset(wrb, 0, sizeof(*wrb));
be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
@@ -652,7 +732,7 @@ int beiscsi_cmd_q_destroy(struct be_ctrl_info *ctrl, struct be_queue_info *q,
default:
spin_unlock(&ctrl->mbox_lock);
BUG();
- return -1;
+ return -ENXIO;
}
be_cmd_hdr_prepare(&req->hdr, subsys, opcode, sizeof(*req));
if (queue_type != QTYPE_SGL)
diff --git a/drivers/scsi/be2iscsi/be_cmds.h b/drivers/scsi/be2iscsi/be_cmds.h
index 49fcc787ee8..40641d0845f 100644
--- a/drivers/scsi/be2iscsi/be_cmds.h
+++ b/drivers/scsi/be2iscsi/be_cmds.h
@@ -47,8 +47,8 @@ struct be_mcc_wrb {
#define CQE_FLAGS_VALID_MASK (1 << 31)
#define CQE_FLAGS_ASYNC_MASK (1 << 30)
-#define CQE_FLAGS_COMPLETED_MASK (1 << 28)
-#define CQE_FLAGS_CONSUMED_MASK (1 << 27)
+#define CQE_FLAGS_COMPLETED_MASK (1 << 28)
+#define CQE_FLAGS_CONSUMED_MASK (1 << 27)
/* Completion Status */
#define MCC_STATUS_SUCCESS 0x0
@@ -56,7 +56,7 @@ struct be_mcc_wrb {
#define CQE_STATUS_COMPL_MASK 0xFFFF
#define CQE_STATUS_COMPL_SHIFT 0 /* bits 0 - 15 */
#define CQE_STATUS_EXTD_MASK 0xFFFF
-#define CQE_STATUS_EXTD_SHIFT 0 /* bits 0 - 15 */
+#define CQE_STATUS_EXTD_SHIFT 16 /* bits 0 - 15 */
struct be_mcc_compl {
u32 status; /* dword 0 */
@@ -143,14 +143,14 @@ struct be_mcc_mailbox {
*/
#define OPCODE_COMMON_CQ_CREATE 12
#define OPCODE_COMMON_EQ_CREATE 13
-#define OPCODE_COMMON_MCC_CREATE 21
-#define OPCODE_COMMON_GET_CNTL_ATTRIBUTES 32
+#define OPCODE_COMMON_MCC_CREATE 21
+#define OPCODE_COMMON_GET_CNTL_ATTRIBUTES 32
#define OPCODE_COMMON_GET_FW_VERSION 35
#define OPCODE_COMMON_MODIFY_EQ_DELAY 41
#define OPCODE_COMMON_FIRMWARE_CONFIG 42
-#define OPCODE_COMMON_MCC_DESTROY 53
-#define OPCODE_COMMON_CQ_DESTROY 54
-#define OPCODE_COMMON_EQ_DESTROY 55
+#define OPCODE_COMMON_MCC_DESTROY 53
+#define OPCODE_COMMON_CQ_DESTROY 54
+#define OPCODE_COMMON_EQ_DESTROY 55
#define OPCODE_COMMON_QUERY_FIRMWARE_CONFIG 58
#define OPCODE_COMMON_FUNCTION_RESET 61
@@ -164,9 +164,9 @@ struct be_mcc_mailbox {
#define OPCODE_COMMON_ISCSI_NTWK_GET_NIC_CONFIG 7
#define OPCODE_COMMON_ISCSI_SET_FRAGNUM_BITS_FOR_SGL_CRA 61
#define OPCODE_COMMON_ISCSI_DEFQ_CREATE 64
-#define OPCODE_COMMON_ISCSI_DEFQ_DESTROY 65
+#define OPCODE_COMMON_ISCSI_DEFQ_DESTROY 65
#define OPCODE_COMMON_ISCSI_WRBQ_CREATE 66
-#define OPCODE_COMMON_ISCSI_WRBQ_DESTROY 67
+#define OPCODE_COMMON_ISCSI_WRBQ_DESTROY 67
struct be_cmd_req_hdr {
u8 opcode; /* dword 0 */
@@ -423,7 +423,7 @@ int beiscsi_cmd_mccq_create(struct beiscsi_hba *phba,
struct be_queue_info *cq);
int be_poll_mcc(struct be_ctrl_info *ctrl);
-unsigned char mgmt_check_supported_fw(struct be_ctrl_info *ctrl,
+int mgmt_check_supported_fw(struct be_ctrl_info *ctrl,
struct beiscsi_hba *phba);
unsigned int be_cmd_get_mac_addr(struct beiscsi_hba *phba);
void free_mcc_tag(struct be_ctrl_info *ctrl, unsigned int tag);
@@ -875,7 +875,7 @@ struct be_fw_cfg {
*/
#define UNSOL_HDR_NOTIFY 28 /* Unsolicited header notify.*/
#define UNSOL_DATA_NOTIFY 29 /* Unsolicited data notify.*/
-#define UNSOL_DATA_DIGEST_ERROR_NOTIFY 30 /* Unsolicited data digest
+#define UNSOL_DATA_DIGEST_ERROR_NOTIFY 30 /* Unsolicited data digest
* error notify.
*/
#define DRIVERMSG_NOTIFY 31 /* TCP acknowledge based
@@ -901,6 +901,9 @@ struct be_fw_cfg {
* the cxn
*/
+int beiscsi_pci_soft_reset(struct beiscsi_hba *phba);
+int be_chk_reset_complete(struct beiscsi_hba *phba);
+
void be_wrb_hdr_prepare(struct be_mcc_wrb *wrb, int payload_len,
bool embedded, u8 sge_cnt);
diff --git a/drivers/scsi/be2iscsi/be_iscsi.c b/drivers/scsi/be2iscsi/be_iscsi.c
index c3928cb8b04..6d63e7b312c 100644
--- a/drivers/scsi/be2iscsi/be_iscsi.c
+++ b/drivers/scsi/be2iscsi/be_iscsi.c
@@ -52,7 +52,7 @@ struct iscsi_cls_session *beiscsi_session_create(struct iscsi_endpoint *ep,
SE_DEBUG(DBG_LVL_8, "In beiscsi_session_create\n");
if (!ep) {
- SE_DEBUG(DBG_LVL_1, "beiscsi_session_create: invalid ep \n");
+ SE_DEBUG(DBG_LVL_1, "beiscsi_session_create: invalid ep\n");
return NULL;
}
beiscsi_ep = ep->dd_data;
@@ -157,7 +157,7 @@ static int beiscsi_bindconn_cid(struct beiscsi_hba *phba,
"Connection table already occupied. Detected clash\n");
return -EINVAL;
} else {
- SE_DEBUG(DBG_LVL_8, "phba->conn_table[%d]=%p(beiscsi_conn) \n",
+ SE_DEBUG(DBG_LVL_8, "phba->conn_table[%d]=%p(beiscsi_conn)\n",
cid, beiscsi_conn);
phba->conn_table[cid] = beiscsi_conn;
}
@@ -196,7 +196,7 @@ int beiscsi_conn_bind(struct iscsi_cls_session *cls_session,
if (beiscsi_ep->phba != phba) {
SE_DEBUG(DBG_LVL_8,
- "beiscsi_ep->hba=%p not equal to phba=%p \n",
+ "beiscsi_ep->hba=%p not equal to phba=%p\n",
beiscsi_ep->phba, phba);
return -EEXIST;
}
@@ -204,7 +204,7 @@ int beiscsi_conn_bind(struct iscsi_cls_session *cls_session,
beiscsi_conn->beiscsi_conn_cid = beiscsi_ep->ep_cid;
beiscsi_conn->ep = beiscsi_ep;
beiscsi_ep->conn = beiscsi_conn;
- SE_DEBUG(DBG_LVL_8, "beiscsi_conn=%p conn=%p ep_cid=%d \n",
+ SE_DEBUG(DBG_LVL_8, "beiscsi_conn=%p conn=%p ep_cid=%d\n",
beiscsi_conn, conn, beiscsi_ep->ep_cid);
return beiscsi_bindconn_cid(phba, beiscsi_conn, beiscsi_ep->ep_cid);
}
@@ -230,7 +230,7 @@ int beiscsi_conn_get_param(struct iscsi_cls_conn *cls_conn,
if (!beiscsi_ep) {
SE_DEBUG(DBG_LVL_1,
"In beiscsi_conn_get_param , no beiscsi_ep\n");
- return -1;
+ return -ENODEV;
}
switch (param) {
@@ -277,6 +277,10 @@ int beiscsi_set_param(struct iscsi_cls_conn *cls_conn,
if (session->max_burst > 262144)
session->max_burst = 262144;
break;
+ case ISCSI_PARAM_MAX_XMIT_DLENGTH:
+ if ((conn->max_xmit_dlength > 65536) ||
+ (conn->max_xmit_dlength == 0))
+ conn->max_xmit_dlength = 65536;
default:
return 0;
}
@@ -308,8 +312,8 @@ int beiscsi_get_host_param(struct Scsi_Host *shost,
case ISCSI_HOST_PARAM_HWADDRESS:
tag = be_cmd_get_mac_addr(phba);
if (!tag) {
- SE_DEBUG(DBG_LVL_1, "be_cmd_get_mac_addr Failed \n");
- return -1;
+ SE_DEBUG(DBG_LVL_1, "be_cmd_get_mac_addr Failed\n");
+ return -EAGAIN;
} else
wait_event_interruptible(phba->ctrl.mcc_wait[tag],
phba->ctrl.mcc_numtag[tag]);
@@ -319,10 +323,10 @@ int beiscsi_get_host_param(struct Scsi_Host *shost,
status = phba->ctrl.mcc_numtag[tag] & 0x000000FF;
if (status || extd_status) {
SE_DEBUG(DBG_LVL_1, "be_cmd_get_mac_addr Failed"
- " status = %d extd_status = %d \n",
+ " status = %d extd_status = %d\n",
status, extd_status);
free_mcc_tag(&phba->ctrl, tag);
- return -1;
+ return -EAGAIN;
} else {
wrb = queue_get_wrb(mccq, wrb_num);
free_mcc_tag(&phba->ctrl, tag);
@@ -442,6 +446,31 @@ static int beiscsi_get_cid(struct beiscsi_hba *phba)
}
/**
+ * beiscsi_put_cid - Free the cid
+ * @phba: The phba for which the cid is being freed
+ * @cid: The cid to free
+ */
+static void beiscsi_put_cid(struct beiscsi_hba *phba, unsigned short cid)
+{
+ phba->avlbl_cids++;
+ phba->cid_array[phba->cid_free++] = cid;
+ if (phba->cid_free == phba->params.cxns_per_ctrl)
+ phba->cid_free = 0;
+}
+
+/**
+ * beiscsi_free_ep - free endpoint
+ * @ep: pointer to iscsi endpoint structure
+ */
+static void beiscsi_free_ep(struct beiscsi_endpoint *beiscsi_ep)
+{
+ struct beiscsi_hba *phba = beiscsi_ep->phba;
+
+ beiscsi_put_cid(phba, beiscsi_ep->ep_cid);
+ beiscsi_ep->phba = NULL;
+}
+
+/**
* beiscsi_open_conn - Ask FW to open a TCP connection
* @ep: endpoint to be used
* @src_addr: The source IP address
@@ -459,8 +488,9 @@ static int beiscsi_open_conn(struct iscsi_endpoint *ep,
struct be_mcc_wrb *wrb;
struct tcp_connect_and_offload_out *ptcpcnct_out;
unsigned short status, extd_status;
+ struct be_dma_mem nonemb_cmd;
unsigned int tag, wrb_num;
- int ret = -1;
+ int ret = -ENOMEM;
SE_DEBUG(DBG_LVL_8, "In beiscsi_open_conn\n");
beiscsi_ep->ep_cid = beiscsi_get_cid(phba);
@@ -468,22 +498,39 @@ static int beiscsi_open_conn(struct iscsi_endpoint *ep,
SE_DEBUG(DBG_LVL_1, "No free cid available\n");
return ret;
}
- SE_DEBUG(DBG_LVL_8, "In beiscsi_open_conn, ep_cid=%d ",
+ SE_DEBUG(DBG_LVL_8, "In beiscsi_open_conn, ep_cid=%d\n",
beiscsi_ep->ep_cid);
phba->ep_array[beiscsi_ep->ep_cid -
phba->fw_config.iscsi_cid_start] = ep;
if (beiscsi_ep->ep_cid > (phba->fw_config.iscsi_cid_start +
phba->params.cxns_per_ctrl * 2)) {
SE_DEBUG(DBG_LVL_1, "Failed in allocate iscsi cid\n");
- return ret;
+ beiscsi_put_cid(phba, beiscsi_ep->ep_cid);
+ goto free_ep;
}
beiscsi_ep->cid_vld = 0;
- tag = mgmt_open_connection(phba, dst_addr, beiscsi_ep);
+ nonemb_cmd.va = pci_alloc_consistent(phba->ctrl.pdev,
+ sizeof(struct tcp_connect_and_offload_in),
+ &nonemb_cmd.dma);
+ if (nonemb_cmd.va == NULL) {
+ SE_DEBUG(DBG_LVL_1,
+ "Failed to allocate memory for mgmt_open_connection"
+ "\n");
+ beiscsi_put_cid(phba, beiscsi_ep->ep_cid);
+ return -ENOMEM;
+ }
+ nonemb_cmd.size = sizeof(struct tcp_connect_and_offload_in);
+ memset(nonemb_cmd.va, 0, nonemb_cmd.size);
+ tag = mgmt_open_connection(phba, dst_addr, beiscsi_ep, &nonemb_cmd);
if (!tag) {
SE_DEBUG(DBG_LVL_1,
- "mgmt_open_connection Failed for cid=%d \n",
+ "mgmt_open_connection Failed for cid=%d\n",
beiscsi_ep->ep_cid);
+ beiscsi_put_cid(phba, beiscsi_ep->ep_cid);
+ pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
+ nonemb_cmd.va, nonemb_cmd.dma);
+ return -EAGAIN;
} else {
wait_event_interruptible(phba->ctrl.mcc_wait[tag],
phba->ctrl.mcc_numtag[tag]);
@@ -493,46 +540,31 @@ static int beiscsi_open_conn(struct iscsi_endpoint *ep,
status = phba->ctrl.mcc_numtag[tag] & 0x000000FF;
if (status || extd_status) {
SE_DEBUG(DBG_LVL_1, "mgmt_open_connection Failed"
- " status = %d extd_status = %d \n",
+ " status = %d extd_status = %d\n",
status, extd_status);
+ beiscsi_put_cid(phba, beiscsi_ep->ep_cid);
free_mcc_tag(&phba->ctrl, tag);
- return -1;
+ pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
+ nonemb_cmd.va, nonemb_cmd.dma);
+ goto free_ep;
} else {
wrb = queue_get_wrb(mccq, wrb_num);
free_mcc_tag(&phba->ctrl, tag);
- ptcpcnct_out = embedded_payload(wrb);
+ ptcpcnct_out = embedded_payload(wrb);
beiscsi_ep = ep->dd_data;
beiscsi_ep->fw_handle = ptcpcnct_out->connection_handle;
beiscsi_ep->cid_vld = 1;
SE_DEBUG(DBG_LVL_8, "mgmt_open_connection Success\n");
}
+ beiscsi_put_cid(phba, beiscsi_ep->ep_cid);
+ pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
+ nonemb_cmd.va, nonemb_cmd.dma);
return 0;
-}
-
-/**
- * beiscsi_put_cid - Free the cid
- * @phba: The phba for which the cid is being freed
- * @cid: The cid to free
- */
-static void beiscsi_put_cid(struct beiscsi_hba *phba, unsigned short cid)
-{
- phba->avlbl_cids++;
- phba->cid_array[phba->cid_free++] = cid;
- if (phba->cid_free == phba->params.cxns_per_ctrl)
- phba->cid_free = 0;
-}
-
-/**
- * beiscsi_free_ep - free endpoint
- * @ep: pointer to iscsi endpoint structure
- */
-static void beiscsi_free_ep(struct beiscsi_endpoint *beiscsi_ep)
-{
- struct beiscsi_hba *phba = beiscsi_ep->phba;
- beiscsi_put_cid(phba, beiscsi_ep->ep_cid);
- beiscsi_ep->phba = NULL;
+free_ep:
+ beiscsi_free_ep(beiscsi_ep);
+ return -EBUSY;
}
/**
@@ -552,18 +584,18 @@ beiscsi_ep_connect(struct Scsi_Host *shost, struct sockaddr *dst_addr,
struct iscsi_endpoint *ep;
int ret;
- SE_DEBUG(DBG_LVL_8, "In beiscsi_ep_connect \n");
+ SE_DEBUG(DBG_LVL_8, "In beiscsi_ep_connect\n");
if (shost)
phba = iscsi_host_priv(shost);
else {
ret = -ENXIO;
- SE_DEBUG(DBG_LVL_1, "shost is NULL \n");
+ SE_DEBUG(DBG_LVL_1, "shost is NULL\n");
return ERR_PTR(ret);
}
if (phba->state != BE_ADAPTER_UP) {
ret = -EBUSY;
- SE_DEBUG(DBG_LVL_1, "The Adapter state is Not UP \n");
+ SE_DEBUG(DBG_LVL_1, "The Adapter state is Not UP\n");
return ERR_PTR(ret);
}
@@ -576,16 +608,16 @@ beiscsi_ep_connect(struct Scsi_Host *shost, struct sockaddr *dst_addr,
beiscsi_ep = ep->dd_data;
beiscsi_ep->phba = phba;
beiscsi_ep->openiscsi_ep = ep;
- if (beiscsi_open_conn(ep, NULL, dst_addr, non_blocking)) {
- SE_DEBUG(DBG_LVL_1, "Failed in beiscsi_open_conn \n");
- ret = -ENOMEM;
+ ret = beiscsi_open_conn(ep, NULL, dst_addr, non_blocking);
+ if (ret) {
+ SE_DEBUG(DBG_LVL_1, "Failed in beiscsi_open_conn\n");
goto free_ep;
}
return ep;
free_ep:
- beiscsi_free_ep(beiscsi_ep);
+ iscsi_destroy_endpoint(ep);
return ERR_PTR(ret);
}
@@ -620,9 +652,9 @@ static int beiscsi_close_conn(struct beiscsi_endpoint *beiscsi_ep, int flag)
tag = mgmt_upload_connection(phba, beiscsi_ep->ep_cid, flag);
if (!tag) {
- SE_DEBUG(DBG_LVL_8, "upload failed for cid 0x%x",
+ SE_DEBUG(DBG_LVL_8, "upload failed for cid 0x%x\n",
beiscsi_ep->ep_cid);
- ret = -1;
+ ret = -EAGAIN;
} else {
wait_event_interruptible(phba->ctrl.mcc_wait[tag],
phba->ctrl.mcc_numtag[tag]);
@@ -632,30 +664,6 @@ static int beiscsi_close_conn(struct beiscsi_endpoint *beiscsi_ep, int flag)
}
/**
- * beiscsi_ep_disconnect - Tears down the TCP connection
- * @ep: endpoint to be used
- *
- * Tears down the TCP connection
- */
-void beiscsi_ep_disconnect(struct iscsi_endpoint *ep)
-{
- struct beiscsi_conn *beiscsi_conn;
- struct beiscsi_endpoint *beiscsi_ep;
- struct beiscsi_hba *phba;
-
- beiscsi_ep = ep->dd_data;
- phba = beiscsi_ep->phba;
- SE_DEBUG(DBG_LVL_8, "In beiscsi_ep_disconnect for ep_cid = %d\n",
- beiscsi_ep->ep_cid);
-
- if (beiscsi_ep->conn) {
- beiscsi_conn = beiscsi_ep->conn;
- iscsi_suspend_queue(beiscsi_conn->conn);
- }
-
-}
-
-/**
* beiscsi_unbind_conn_to_cid - Unbind the beiscsi_conn from phba conn table
* @phba: The phba instance
* @cid: The cid to free
@@ -666,50 +674,57 @@ static int beiscsi_unbind_conn_to_cid(struct beiscsi_hba *phba,
if (phba->conn_table[cid])
phba->conn_table[cid] = NULL;
else {
- SE_DEBUG(DBG_LVL_8, "Connection table Not occupied. \n");
+ SE_DEBUG(DBG_LVL_8, "Connection table Not occupied.\n");
return -EINVAL;
}
return 0;
}
/**
- * beiscsi_conn_stop - Invalidate and stop the connection
- * @cls_conn: pointer to get iscsi_conn
- * @flag: The type of connection closure
+ * beiscsi_ep_disconnect - Tears down the TCP connection
+ * @ep: endpoint to be used
+ *
+ * Tears down the TCP connection
*/
-void beiscsi_conn_stop(struct iscsi_cls_conn *cls_conn, int flag)
+void beiscsi_ep_disconnect(struct iscsi_endpoint *ep)
{
- struct iscsi_conn *conn = cls_conn->dd_data;
- struct beiscsi_conn *beiscsi_conn = conn->dd_data;
+ struct beiscsi_conn *beiscsi_conn;
struct beiscsi_endpoint *beiscsi_ep;
- struct iscsi_session *session = conn->session;
- struct Scsi_Host *shost = iscsi_session_to_shost(session->cls_session);
- struct beiscsi_hba *phba = iscsi_host_priv(shost);
+ struct beiscsi_hba *phba;
unsigned int tag;
unsigned short savecfg_flag = CMD_ISCSI_SESSION_SAVE_CFG_ON_FLASH;
- beiscsi_ep = beiscsi_conn->ep;
- if (!beiscsi_ep) {
- SE_DEBUG(DBG_LVL_8, "In beiscsi_conn_stop , no beiscsi_ep\n");
+ beiscsi_ep = ep->dd_data;
+ phba = beiscsi_ep->phba;
+ SE_DEBUG(DBG_LVL_8, "In beiscsi_ep_disconnect for ep_cid = %d\n",
+ beiscsi_ep->ep_cid);
+
+ if (!beiscsi_ep->conn) {
+ SE_DEBUG(DBG_LVL_8, "In beiscsi_ep_disconnect, no "
+ "beiscsi_ep\n");
return;
}
- SE_DEBUG(DBG_LVL_8, "In beiscsi_conn_stop ep_cid = %d\n",
- beiscsi_ep->ep_cid);
+ beiscsi_conn = beiscsi_ep->conn;
+ iscsi_suspend_queue(beiscsi_conn->conn);
+
+ SE_DEBUG(DBG_LVL_8, "In beiscsi_ep_disconnect ep_cid = %d\n",
+ beiscsi_ep->ep_cid);
+
tag = mgmt_invalidate_connection(phba, beiscsi_ep,
beiscsi_ep->ep_cid, 1,
savecfg_flag);
if (!tag) {
SE_DEBUG(DBG_LVL_1,
- "mgmt_invalidate_connection Failed for cid=%d \n",
+ "mgmt_invalidate_connection Failed for cid=%d\n",
beiscsi_ep->ep_cid);
} else {
wait_event_interruptible(phba->ctrl.mcc_wait[tag],
phba->ctrl.mcc_numtag[tag]);
free_mcc_tag(&phba->ctrl, tag);
}
+
beiscsi_close_conn(beiscsi_ep, CONNECTION_UPLOAD_GRACEFUL);
beiscsi_free_ep(beiscsi_ep);
- iscsi_destroy_endpoint(beiscsi_ep->openiscsi_ep);
beiscsi_unbind_conn_to_cid(phba, beiscsi_ep->ep_cid);
- iscsi_conn_stop(cls_conn, flag);
+ iscsi_destroy_endpoint(beiscsi_ep->openiscsi_ep);
}
diff --git a/drivers/scsi/be2iscsi/be_iscsi.h b/drivers/scsi/be2iscsi/be_iscsi.h
index 1f512c28cbf..870cdb2a73e 100644
--- a/drivers/scsi/be2iscsi/be_iscsi.h
+++ b/drivers/scsi/be2iscsi/be_iscsi.h
@@ -59,8 +59,6 @@ int beiscsi_set_param(struct iscsi_cls_conn *cls_conn,
int beiscsi_conn_start(struct iscsi_cls_conn *cls_conn);
-void beiscsi_conn_stop(struct iscsi_cls_conn *cls_conn, int flag);
-
struct iscsi_endpoint *beiscsi_ep_connect(struct Scsi_Host *shost,
struct sockaddr *dst_addr,
int non_blocking);
diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
index dd5b105f8f4..7436c5ad569 100644
--- a/drivers/scsi/be2iscsi/be_main.c
+++ b/drivers/scsi/be2iscsi/be_main.c
@@ -41,6 +41,8 @@
static unsigned int be_iopoll_budget = 10;
static unsigned int be_max_phys_size = 64;
static unsigned int enable_msix = 1;
+static unsigned int gcrashmode = 0;
+static unsigned int num_hba = 0;
MODULE_DEVICE_TABLE(pci, beiscsi_pci_id_table);
MODULE_DESCRIPTION(DRV_DESC " " BUILD_STR);
@@ -69,6 +71,7 @@ static int beiscsi_eh_abort(struct scsi_cmnd *sc)
struct beiscsi_hba *phba;
struct iscsi_session *session;
struct invalidate_command_table *inv_tbl;
+ struct be_dma_mem nonemb_cmd;
unsigned int cid, tag, num_invalidate;
cls_session = starget_to_session(scsi_target(sc->device));
@@ -99,18 +102,34 @@ static int beiscsi_eh_abort(struct scsi_cmnd *sc)
inv_tbl->cid = cid;
inv_tbl->icd = aborted_io_task->psgl_handle->sgl_index;
num_invalidate = 1;
- tag = mgmt_invalidate_icds(phba, inv_tbl, num_invalidate, cid);
+ nonemb_cmd.va = pci_alloc_consistent(phba->ctrl.pdev,
+ sizeof(struct invalidate_commands_params_in),
+ &nonemb_cmd.dma);
+ if (nonemb_cmd.va == NULL) {
+ SE_DEBUG(DBG_LVL_1,
+ "Failed to allocate memory for"
+ "mgmt_invalidate_icds\n");
+ return FAILED;
+ }
+ nonemb_cmd.size = sizeof(struct invalidate_commands_params_in);
+
+ tag = mgmt_invalidate_icds(phba, inv_tbl, num_invalidate,
+ cid, &nonemb_cmd);
if (!tag) {
shost_printk(KERN_WARNING, phba->shost,
"mgmt_invalidate_icds could not be"
" submitted\n");
+ pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
+ nonemb_cmd.va, nonemb_cmd.dma);
+
return FAILED;
} else {
wait_event_interruptible(phba->ctrl.mcc_wait[tag],
phba->ctrl.mcc_numtag[tag]);
free_mcc_tag(&phba->ctrl, tag);
}
-
+ pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
+ nonemb_cmd.va, nonemb_cmd.dma);
return iscsi_eh_abort(sc);
}
@@ -124,6 +143,7 @@ static int beiscsi_eh_device_reset(struct scsi_cmnd *sc)
struct iscsi_session *session;
struct iscsi_cls_session *cls_session;
struct invalidate_command_table *inv_tbl;
+ struct be_dma_mem nonemb_cmd;
unsigned int cid, tag, i, num_invalidate;
int rc = FAILED;
@@ -158,18 +178,33 @@ static int beiscsi_eh_device_reset(struct scsi_cmnd *sc)
spin_unlock_bh(&session->lock);
inv_tbl = phba->inv_tbl;
- tag = mgmt_invalidate_icds(phba, inv_tbl, num_invalidate, cid);
+ nonemb_cmd.va = pci_alloc_consistent(phba->ctrl.pdev,
+ sizeof(struct invalidate_commands_params_in),
+ &nonemb_cmd.dma);
+ if (nonemb_cmd.va == NULL) {
+ SE_DEBUG(DBG_LVL_1,
+ "Failed to allocate memory for"
+ "mgmt_invalidate_icds\n");
+ return FAILED;
+ }
+ nonemb_cmd.size = sizeof(struct invalidate_commands_params_in);
+ memset(nonemb_cmd.va, 0, nonemb_cmd.size);
+ tag = mgmt_invalidate_icds(phba, inv_tbl, num_invalidate,
+ cid, &nonemb_cmd);
if (!tag) {
shost_printk(KERN_WARNING, phba->shost,
"mgmt_invalidate_icds could not be"
" submitted\n");
+ pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
+ nonemb_cmd.va, nonemb_cmd.dma);
return FAILED;
} else {
wait_event_interruptible(phba->ctrl.mcc_wait[tag],
phba->ctrl.mcc_numtag[tag]);
free_mcc_tag(&phba->ctrl, tag);
}
-
+ pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
+ nonemb_cmd.va, nonemb_cmd.dma);
return iscsi_eh_device_reset(sc);
unlock:
spin_unlock_bh(&session->lock);
@@ -216,7 +251,7 @@ static struct beiscsi_hba *beiscsi_hba_alloc(struct pci_dev *pcidev)
shost = iscsi_host_alloc(&beiscsi_sht, sizeof(*phba), 0);
if (!shost) {
dev_err(&pcidev->dev, "beiscsi_hba_alloc -"
- "iscsi_host_alloc failed \n");
+ "iscsi_host_alloc failed\n");
return NULL;
}
shost->dma_boundary = pcidev->dma_mask;
@@ -371,7 +406,7 @@ static void beiscsi_get_params(struct beiscsi_hba *phba)
+ BE2_TMFS) / 512) + 1) * 512;
phba->params.num_eq_entries = (phba->params.num_eq_entries < 1024)
? 1024 : phba->params.num_eq_entries;
- SE_DEBUG(DBG_LVL_8, "phba->params.num_eq_entries=%d \n",
+ SE_DEBUG(DBG_LVL_8, "phba->params.num_eq_entries=%d\n",
phba->params.num_eq_entries);
phba->params.num_cq_entries =
(((BE2_CMDS_PER_CXN * 2 + phba->fw_config.iscsi_cid_count * 2
@@ -616,7 +651,7 @@ static int beiscsi_init_irqs(struct beiscsi_hba *phba)
struct pci_dev *pcidev = phba->pcidev;
struct hwi_controller *phwi_ctrlr;
struct hwi_context_memory *phwi_context;
- int ret, msix_vec, i = 0;
+ int ret, msix_vec, i, j;
char desc[32];
phwi_ctrlr = phba->phwi_ctrlr;
@@ -628,10 +663,25 @@ static int beiscsi_init_irqs(struct beiscsi_hba *phba)
msix_vec = phba->msix_entries[i].vector;
ret = request_irq(msix_vec, be_isr_msix, 0, desc,
&phwi_context->be_eq[i]);
+ if (ret) {
+ shost_printk(KERN_ERR, phba->shost,
+ "beiscsi_init_irqs-Failed to"
+ "register msix for i = %d\n", i);
+ if (!i)
+ return ret;
+ goto free_msix_irqs;
+ }
}
msix_vec = phba->msix_entries[i].vector;
ret = request_irq(msix_vec, be_isr_mcc, 0, "beiscsi_msix_mcc",
&phwi_context->be_eq[i]);
+ if (ret) {
+ shost_printk(KERN_ERR, phba->shost, "beiscsi_init_irqs-"
+ "Failed to register beiscsi_msix_mcc\n");
+ i++;
+ goto free_msix_irqs;
+ }
+
} else {
ret = request_irq(pcidev->irq, be_isr, IRQF_SHARED,
"beiscsi", phba);
@@ -642,6 +692,10 @@ static int beiscsi_init_irqs(struct beiscsi_hba *phba)
}
}
return 0;
+free_msix_irqs:
+ for (j = i - 1; j == 0; j++)
+ free_irq(msix_vec, &phwi_context->be_eq[j]);
+ return ret;
}
static void hwi_ring_cq_db(struct beiscsi_hba *phba,
@@ -692,7 +746,7 @@ beiscsi_process_async_pdu(struct beiscsi_conn *beiscsi_conn,
break;
default:
shost_printk(KERN_WARNING, phba->shost,
- "Unrecognized opcode 0x%x in async msg \n",
+ "Unrecognized opcode 0x%x in async msg\n",
(ppdu->
dw[offsetof(struct amap_pdu_base, opcode) / 32]
& PDUBASE_OPCODE_MASK));
@@ -711,7 +765,7 @@ static struct sgl_handle *alloc_io_sgl_handle(struct beiscsi_hba *phba)
if (phba->io_sgl_hndl_avbl) {
SE_DEBUG(DBG_LVL_8,
- "In alloc_io_sgl_handle,io_sgl_alloc_index=%d \n",
+ "In alloc_io_sgl_handle,io_sgl_alloc_index=%d\n",
phba->io_sgl_alloc_index);
psgl_handle = phba->io_sgl_hndl_base[phba->
io_sgl_alloc_index];
@@ -730,7 +784,7 @@ static struct sgl_handle *alloc_io_sgl_handle(struct beiscsi_hba *phba)
static void
free_io_sgl_handle(struct beiscsi_hba *phba, struct sgl_handle *psgl_handle)
{
- SE_DEBUG(DBG_LVL_8, "In free_,io_sgl_free_index=%d \n",
+ SE_DEBUG(DBG_LVL_8, "In free_,io_sgl_free_index=%d\n",
phba->io_sgl_free_index);
if (phba->io_sgl_hndl_base[phba->io_sgl_free_index]) {
/*
@@ -739,7 +793,7 @@ free_io_sgl_handle(struct beiscsi_hba *phba, struct sgl_handle *psgl_handle)
*/
SE_DEBUG(DBG_LVL_8,
"Double Free in IO SGL io_sgl_free_index=%d,"
- "value there=%p \n", phba->io_sgl_free_index,
+ "value there=%p\n", phba->io_sgl_free_index,
phba->io_sgl_hndl_base[phba->io_sgl_free_index]);
return;
}
@@ -804,7 +858,7 @@ free_wrb_handle(struct beiscsi_hba *phba, struct hwi_wrb_context *pwrb_context,
SE_DEBUG(DBG_LVL_8,
"FREE WRB: pwrb_handle=%p free_index=0x%x"
- "wrb_handles_available=%d \n",
+ "wrb_handles_available=%d\n",
pwrb_handle, pwrb_context->free_index,
pwrb_context->wrb_handles_available);
}
@@ -816,7 +870,7 @@ static struct sgl_handle *alloc_mgmt_sgl_handle(struct beiscsi_hba *phba)
if (phba->eh_sgl_hndl_avbl) {
psgl_handle = phba->eh_sgl_hndl_base[phba->eh_sgl_alloc_index];
phba->eh_sgl_hndl_base[phba->eh_sgl_alloc_index] = NULL;
- SE_DEBUG(DBG_LVL_8, "mgmt_sgl_alloc_index=%d=0x%x \n",
+ SE_DEBUG(DBG_LVL_8, "mgmt_sgl_alloc_index=%d=0x%x\n",
phba->eh_sgl_alloc_index, phba->eh_sgl_alloc_index);
phba->eh_sgl_hndl_avbl--;
if (phba->eh_sgl_alloc_index ==
@@ -834,7 +888,7 @@ void
free_mgmt_sgl_handle(struct beiscsi_hba *phba, struct sgl_handle *psgl_handle)
{
- SE_DEBUG(DBG_LVL_8, "In free_mgmt_sgl_handle,eh_sgl_free_index=%d \n",
+ SE_DEBUG(DBG_LVL_8, "In free_mgmt_sgl_handle,eh_sgl_free_index=%d\n",
phba->eh_sgl_free_index);
if (phba->eh_sgl_hndl_base[phba->eh_sgl_free_index]) {
/*
@@ -842,7 +896,7 @@ free_mgmt_sgl_handle(struct beiscsi_hba *phba, struct sgl_handle *psgl_handle)
* failed in xmit_task or alloc_pdu.
*/
SE_DEBUG(DBG_LVL_8,
- "Double Free in eh SGL ,eh_sgl_free_index=%d \n",
+ "Double Free in eh SGL ,eh_sgl_free_index=%d\n",
phba->eh_sgl_free_index);
return;
}
@@ -1081,7 +1135,7 @@ static void hwi_complete_cmd(struct beiscsi_conn *beiscsi_conn,
case HWH_TYPE_LOGIN:
SE_DEBUG(DBG_LVL_1,
"\t\t No HWH_TYPE_LOGIN Expected in hwi_complete_cmd"
- "- Solicited path \n");
+ "- Solicited path\n");
break;
case HWH_TYPE_NOP:
@@ -1164,7 +1218,7 @@ hwi_get_async_handle(struct beiscsi_hba *phba,
default:
pbusy_list = NULL;
shost_printk(KERN_WARNING, phba->shost,
- "Unexpected code=%d \n",
+ "Unexpected code=%d\n",
pdpdu_cqe->dw[offsetof(struct amap_i_t_dpdu_cqe,
code) / 32] & PDUCQE_CODE_MASK);
return NULL;
@@ -1552,7 +1606,7 @@ static void beiscsi_process_mcc_isr(struct beiscsi_hba *phba)
else
SE_DEBUG(DBG_LVL_1,
" Unsupported Async Event, flags"
- " = 0x%08x \n", mcc_compl->flags);
+ " = 0x%08x\n", mcc_compl->flags);
} else if (mcc_compl->flags & CQE_FLAGS_COMPLETED_MASK) {
be_mcc_compl_process_isr(&phba->ctrl, mcc_compl);
atomic_dec(&phba->ctrl.mcc_obj.q.used);
@@ -1611,7 +1665,7 @@ static unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq)
hwi_complete_cmd(beiscsi_conn, phba, sol);
break;
case DRIVERMSG_NOTIFY:
- SE_DEBUG(DBG_LVL_8, "Received DRIVERMSG_NOTIFY \n");
+ SE_DEBUG(DBG_LVL_8, "Received DRIVERMSG_NOTIFY\n");
dmsg = (struct dmsg_cqe *)sol;
hwi_complete_drvr_msgs(beiscsi_conn, phba, sol);
break;
@@ -1782,9 +1836,9 @@ hwi_write_sgl(struct iscsi_wrb *pwrb, struct scatterlist *sg,
sg_len = sg_dma_len(sg);
addr = (u64) sg_dma_address(sg);
AMAP_SET_BITS(struct amap_iscsi_wrb, sge0_addr_lo, pwrb,
- (addr & 0xFFFFFFFF));
+ ((u32)(addr & 0xFFFFFFFF)));
AMAP_SET_BITS(struct amap_iscsi_wrb, sge0_addr_hi, pwrb,
- (addr >> 32));
+ ((u32)(addr >> 32)));
AMAP_SET_BITS(struct amap_iscsi_wrb, sge0_len, pwrb,
sg_len);
sge_len = sg_len;
@@ -1794,9 +1848,9 @@ hwi_write_sgl(struct iscsi_wrb *pwrb, struct scatterlist *sg,
sg_len = sg_dma_len(sg);
addr = (u64) sg_dma_address(sg);
AMAP_SET_BITS(struct amap_iscsi_wrb, sge1_addr_lo, pwrb,
- (addr & 0xFFFFFFFF));
+ ((u32)(addr & 0xFFFFFFFF)));
AMAP_SET_BITS(struct amap_iscsi_wrb, sge1_addr_hi, pwrb,
- (addr >> 32));
+ ((u32)(addr >> 32)));
AMAP_SET_BITS(struct amap_iscsi_wrb, sge1_len, pwrb,
sg_len);
}
@@ -1872,9 +1926,9 @@ static void hwi_write_buffer(struct iscsi_wrb *pwrb, struct iscsi_task *task)
addr = 0;
}
AMAP_SET_BITS(struct amap_iscsi_wrb, sge0_addr_lo, pwrb,
- (addr & 0xFFFFFFFF));
+ ((u32)(addr & 0xFFFFFFFF)));
AMAP_SET_BITS(struct amap_iscsi_wrb, sge0_addr_hi, pwrb,
- (addr >> 32));
+ ((u32)(addr >> 32)));
AMAP_SET_BITS(struct amap_iscsi_wrb, sge0_len, pwrb,
task->data_count);
@@ -1904,9 +1958,9 @@ static void hwi_write_buffer(struct iscsi_wrb *pwrb, struct iscsi_task *task)
psgl++;
if (task->data) {
AMAP_SET_BITS(struct amap_iscsi_sge, addr_lo, psgl,
- (addr & 0xFFFFFFFF));
+ ((u32)(addr & 0xFFFFFFFF)));
AMAP_SET_BITS(struct amap_iscsi_sge, addr_hi, psgl,
- (addr >> 32));
+ ((u32)(addr >> 32)));
}
AMAP_SET_BITS(struct amap_iscsi_sge, len, psgl, 0x106);
}
@@ -2054,7 +2108,8 @@ free_mem:
mem_descr->mem_array[j - 1].size,
mem_descr->mem_array[j - 1].
virtual_address,
- mem_descr->mem_array[j - 1].
+ (unsigned long)mem_descr->
+ mem_array[j - 1].
bus_address.u.a64.address);
}
if (i) {
@@ -2223,10 +2278,10 @@ static void hwi_init_async_pdu_ctx(struct beiscsi_hba *phba)
if (mem_descr->mem_array[0].virtual_address) {
SE_DEBUG(DBG_LVL_8,
"hwi_init_async_pdu_ctx HWI_MEM_ASYNC_HEADER_BUF"
- "va=%p \n", mem_descr->mem_array[0].virtual_address);
+ "va=%p\n", mem_descr->mem_array[0].virtual_address);
} else
shost_printk(KERN_WARNING, phba->shost,
- "No Virtual address \n");
+ "No Virtual address\n");
pasync_ctx->async_header.va_base =
mem_descr->mem_array[0].virtual_address;
@@ -2239,10 +2294,10 @@ static void hwi_init_async_pdu_ctx(struct beiscsi_hba *phba)
if (mem_descr->mem_array[0].virtual_address) {
SE_DEBUG(DBG_LVL_8,
"hwi_init_async_pdu_ctx HWI_MEM_ASYNC_HEADER_RING"
- "va=%p \n", mem_descr->mem_array[0].virtual_address);
+ "va=%p\n", mem_descr->mem_array[0].virtual_address);
} else
shost_printk(KERN_WARNING, phba->shost,
- "No Virtual address \n");
+ "No Virtual address\n");
pasync_ctx->async_header.ring_base =
mem_descr->mem_array[0].virtual_address;
@@ -2251,10 +2306,10 @@ static void hwi_init_async_pdu_ctx(struct beiscsi_hba *phba)
if (mem_descr->mem_array[0].virtual_address) {
SE_DEBUG(DBG_LVL_8,
"hwi_init_async_pdu_ctx HWI_MEM_ASYNC_HEADER_HANDLE"
- "va=%p \n", mem_descr->mem_array[0].virtual_address);
+ "va=%p\n", mem_descr->mem_array[0].virtual_address);
} else
shost_printk(KERN_WARNING, phba->shost,
- "No Virtual address \n");
+ "No Virtual address\n");
pasync_ctx->async_header.handle_base =
mem_descr->mem_array[0].virtual_address;
@@ -2266,10 +2321,10 @@ static void hwi_init_async_pdu_ctx(struct beiscsi_hba *phba)
if (mem_descr->mem_array[0].virtual_address) {
SE_DEBUG(DBG_LVL_8,
"hwi_init_async_pdu_ctx HWI_MEM_ASYNC_DATA_BUF"
- "va=%p \n", mem_descr->mem_array[0].virtual_address);
+ "va=%p\n", mem_descr->mem_array[0].virtual_address);
} else
shost_printk(KERN_WARNING, phba->shost,
- "No Virtual address \n");
+ "No Virtual address\n");
pasync_ctx->async_data.va_base =
mem_descr->mem_array[0].virtual_address;
pasync_ctx->async_data.pa_base.u.a64.address =
@@ -2280,10 +2335,10 @@ static void hwi_init_async_pdu_ctx(struct beiscsi_hba *phba)
if (mem_descr->mem_array[0].virtual_address) {
SE_DEBUG(DBG_LVL_8,
"hwi_init_async_pdu_ctx HWI_MEM_ASYNC_DATA_RING"
- "va=%p \n", mem_descr->mem_array[0].virtual_address);
+ "va=%p\n", mem_descr->mem_array[0].virtual_address);
} else
shost_printk(KERN_WARNING, phba->shost,
- "No Virtual address \n");
+ "No Virtual address\n");
pasync_ctx->async_data.ring_base =
mem_descr->mem_array[0].virtual_address;
@@ -2292,7 +2347,7 @@ static void hwi_init_async_pdu_ctx(struct beiscsi_hba *phba)
mem_descr += HWI_MEM_ASYNC_DATA_HANDLE;
if (!mem_descr->mem_array[0].virtual_address)
shost_printk(KERN_WARNING, phba->shost,
- "No Virtual address \n");
+ "No Virtual address\n");
pasync_ctx->async_data.handle_base =
mem_descr->mem_array[0].virtual_address;
@@ -2364,7 +2419,7 @@ be_sgl_create_contiguous(void *virtual_address,
WARN_ON(!sgl);
sgl->va = virtual_address;
- sgl->dma = physical_address;
+ sgl->dma = (unsigned long)physical_address;
sgl->size = length;
return 0;
@@ -2447,7 +2502,7 @@ static int beiscsi_create_eqs(struct beiscsi_hba *phba,
sizeof(struct be_eq_entry), eq_vaddress);
if (ret) {
shost_printk(KERN_ERR, phba->shost,
- "be_fill_queue Failed for EQ \n");
+ "be_fill_queue Failed for EQ\n");
goto create_eq_error;
}
@@ -2457,7 +2512,7 @@ static int beiscsi_create_eqs(struct beiscsi_hba *phba,
if (ret) {
shost_printk(KERN_ERR, phba->shost,
"beiscsi_cmd_eq_create"
- "Failedfor EQ \n");
+ "Failedfor EQ\n");
goto create_eq_error;
}
SE_DEBUG(DBG_LVL_8, "eqid = %d\n", phwi_context->be_eq[i].q.id);
@@ -2505,7 +2560,7 @@ static int beiscsi_create_cqs(struct beiscsi_hba *phba,
sizeof(struct sol_cqe), cq_vaddress);
if (ret) {
shost_printk(KERN_ERR, phba->shost,
- "be_fill_queue Failed for ISCSI CQ \n");
+ "be_fill_queue Failed for ISCSI CQ\n");
goto create_cq_error;
}
@@ -2515,7 +2570,7 @@ static int beiscsi_create_cqs(struct beiscsi_hba *phba,
if (ret) {
shost_printk(KERN_ERR, phba->shost,
"beiscsi_cmd_eq_create"
- "Failed for ISCSI CQ \n");
+ "Failed for ISCSI CQ\n");
goto create_cq_error;
}
SE_DEBUG(DBG_LVL_8, "iscsi cq_id is %d for eq_id %d\n",
@@ -2565,7 +2620,8 @@ beiscsi_create_def_hdr(struct beiscsi_hba *phba,
"be_fill_queue Failed for DEF PDU HDR\n");
return ret;
}
- mem->dma = mem_descr->mem_array[idx].bus_address.u.a64.address;
+ mem->dma = (unsigned long)mem_descr->mem_array[idx].
+ bus_address.u.a64.address;
ret = be_cmd_create_default_pdu_queue(&phba->ctrl, cq, dq,
def_pdu_ring_sz,
phba->params.defpdu_hdr_sz);
@@ -2609,7 +2665,8 @@ beiscsi_create_def_data(struct beiscsi_hba *phba,
"be_fill_queue Failed for DEF PDU DATA\n");
return ret;
}
- mem->dma = mem_descr->mem_array[idx].bus_address.u.a64.address;
+ mem->dma = (unsigned long)mem_descr->mem_array[idx].
+ bus_address.u.a64.address;
ret = be_cmd_create_default_pdu_queue(&phba->ctrl, cq, dataq,
def_pdu_ring_sz,
phba->params.defpdu_data_sz);
@@ -2623,7 +2680,7 @@ beiscsi_create_def_data(struct beiscsi_hba *phba,
SE_DEBUG(DBG_LVL_8, "iscsi def data id is %d\n",
phwi_context->be_def_dataq.id);
hwi_post_async_buffers(phba, 0);
- SE_DEBUG(DBG_LVL_8, "DEFAULT PDU DATA RING CREATED \n");
+ SE_DEBUG(DBG_LVL_8, "DEFAULT PDU DATA RING CREATED\n");
return 0;
}
@@ -2655,7 +2712,7 @@ beiscsi_post_pages(struct beiscsi_hba *phba)
}
pm_arr++;
}
- SE_DEBUG(DBG_LVL_8, "POSTED PAGES \n");
+ SE_DEBUG(DBG_LVL_8, "POSTED PAGES\n");
return 0;
}
@@ -2678,7 +2735,7 @@ static int be_queue_alloc(struct beiscsi_hba *phba, struct be_queue_info *q,
mem->size = len * entry_size;
mem->va = pci_alloc_consistent(phba->pcidev, mem->size, &mem->dma);
if (!mem->va)
- return -1;
+ return -ENOMEM;
memset(mem->va, 0, mem->size);
return 0;
}
@@ -2750,6 +2807,7 @@ beiscsi_create_wrb_rings(struct beiscsi_hba *phba,
if (status != 0) {
shost_printk(KERN_ERR, phba->shost,
"wrbq create failed.");
+ kfree(pwrb_arr);
return status;
}
phwi_ctrlr->wrb_context[i * 2].cid = phwi_context->be_wrbq[i].
@@ -2873,7 +2931,7 @@ mcc_cq_destroy:
mcc_cq_free:
be_queue_free(phba, cq);
err:
- return -1;
+ return -ENOMEM;
}
static int find_num_cpus(void)
@@ -2884,7 +2942,7 @@ static int find_num_cpus(void)
if (num_cpus >= MAX_CPUS)
num_cpus = MAX_CPUS - 1;
- SE_DEBUG(DBG_LVL_8, "num_cpus = %d \n", num_cpus);
+ SE_DEBUG(DBG_LVL_8, "num_cpus = %d\n", num_cpus);
return num_cpus;
}
@@ -2907,7 +2965,7 @@ static int hwi_init_port(struct beiscsi_hba *phba)
status = beiscsi_create_eqs(phba, phwi_context);
if (status != 0) {
- shost_printk(KERN_ERR, phba->shost, "EQ not created \n");
+ shost_printk(KERN_ERR, phba->shost, "EQ not created\n");
goto error;
}
@@ -2918,7 +2976,7 @@ static int hwi_init_port(struct beiscsi_hba *phba)
status = mgmt_check_supported_fw(ctrl, phba);
if (status != 0) {
shost_printk(KERN_ERR, phba->shost,
- "Unsupported fw version \n");
+ "Unsupported fw version\n");
goto error;
}
@@ -2974,7 +3032,7 @@ static int hwi_init_controller(struct beiscsi_hba *phba)
if (1 == phba->init_mem[HWI_MEM_ADDN_CONTEXT].num_elements) {
phwi_ctrlr->phwi_ctxt = (struct hwi_context_memory *)phba->
init_mem[HWI_MEM_ADDN_CONTEXT].mem_array[0].virtual_address;
- SE_DEBUG(DBG_LVL_8, " phwi_ctrlr->phwi_ctxt=%p \n",
+ SE_DEBUG(DBG_LVL_8, " phwi_ctrlr->phwi_ctxt=%p\n",
phwi_ctrlr->phwi_ctxt);
} else {
shost_printk(KERN_ERR, phba->shost,
@@ -3007,8 +3065,8 @@ static void beiscsi_free_mem(struct beiscsi_hba *phba)
pci_free_consistent(phba->pcidev,
mem_descr->mem_array[j - 1].size,
mem_descr->mem_array[j - 1].virtual_address,
- mem_descr->mem_array[j - 1].bus_address.
- u.a64.address);
+ (unsigned long)mem_descr->mem_array[j - 1].
+ bus_address.u.a64.address);
}
kfree(mem_descr->mem_array);
mem_descr++;
@@ -3024,7 +3082,7 @@ static int beiscsi_init_controller(struct beiscsi_hba *phba)
ret = beiscsi_get_memory(phba);
if (ret < 0) {
shost_printk(KERN_ERR, phba->shost, "beiscsi_dev_probe -"
- "Failed in beiscsi_alloc_memory \n");
+ "Failed in beiscsi_alloc_memory\n");
return ret;
}
@@ -3101,12 +3159,12 @@ static int beiscsi_init_sgl_handle(struct beiscsi_hba *phba)
}
SE_DEBUG(DBG_LVL_8,
"phba->io_sgl_hndl_avbl=%d"
- "phba->eh_sgl_hndl_avbl=%d \n",
+ "phba->eh_sgl_hndl_avbl=%d\n",
phba->io_sgl_hndl_avbl,
phba->eh_sgl_hndl_avbl);
mem_descr_sg = phba->init_mem;
mem_descr_sg += HWI_MEM_SGE;
- SE_DEBUG(DBG_LVL_8, "\n mem_descr_sg->num_elements=%d \n",
+ SE_DEBUG(DBG_LVL_8, "\n mem_descr_sg->num_elements=%d\n",
mem_descr_sg->num_elements);
arr_index = 0;
idx = 0;
@@ -3155,7 +3213,7 @@ static int hba_setup_cid_tbls(struct beiscsi_hba *phba)
if (!phba->ep_array) {
shost_printk(KERN_ERR, phba->shost,
"Failed to allocate memory in "
- "hba_setup_cid_tbls \n");
+ "hba_setup_cid_tbls\n");
kfree(phba->cid_array);
return -ENOMEM;
}
@@ -3168,7 +3226,7 @@ static int hba_setup_cid_tbls(struct beiscsi_hba *phba)
return 0;
}
-static unsigned char hwi_enable_intr(struct beiscsi_hba *phba)
+static void hwi_enable_intr(struct beiscsi_hba *phba)
{
struct be_ctrl_info *ctrl = &phba->ctrl;
struct hwi_controller *phwi_ctrlr;
@@ -3184,26 +3242,25 @@ static unsigned char hwi_enable_intr(struct beiscsi_hba *phba)
addr = (u8 __iomem *) ((u8 __iomem *) ctrl->pcicfg +
PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET);
reg = ioread32(addr);
- SE_DEBUG(DBG_LVL_8, "reg =x%08x \n", reg);
+ SE_DEBUG(DBG_LVL_8, "reg =x%08x\n", reg);
enabled = reg & MEMBAR_CTRL_INT_CTRL_HOSTINTR_MASK;
if (!enabled) {
reg |= MEMBAR_CTRL_INT_CTRL_HOSTINTR_MASK;
- SE_DEBUG(DBG_LVL_8, "reg =x%08x addr=%p \n", reg, addr);
+ SE_DEBUG(DBG_LVL_8, "reg =x%08x addr=%p\n", reg, addr);
iowrite32(reg, addr);
if (!phba->msix_enabled) {
eq = &phwi_context->be_eq[0].q;
- SE_DEBUG(DBG_LVL_8, "eq->id=%d \n", eq->id);
+ SE_DEBUG(DBG_LVL_8, "eq->id=%d\n", eq->id);
hwi_ring_eq_db(phba, eq->id, 0, 0, 1, 1);
} else {
for (i = 0; i <= phba->num_cpus; i++) {
eq = &phwi_context->be_eq[i].q;
- SE_DEBUG(DBG_LVL_8, "eq->id=%d \n", eq->id);
+ SE_DEBUG(DBG_LVL_8, "eq->id=%d\n", eq->id);
hwi_ring_eq_db(phba, eq->id, 0, 0, 1, 1);
}
}
}
- return true;
}
static void hwi_disable_intr(struct beiscsi_hba *phba)
@@ -3219,7 +3276,7 @@ static void hwi_disable_intr(struct beiscsi_hba *phba)
iowrite32(reg, addr);
} else
shost_printk(KERN_WARNING, phba->shost,
- "In hwi_disable_intr, Already Disabled \n");
+ "In hwi_disable_intr, Already Disabled\n");
}
static int beiscsi_init_port(struct beiscsi_hba *phba)
@@ -3230,14 +3287,14 @@ static int beiscsi_init_port(struct beiscsi_hba *phba)
if (ret < 0) {
shost_printk(KERN_ERR, phba->shost,
"beiscsi_dev_probe - Failed in"
- "beiscsi_init_controller \n");
+ "beiscsi_init_controller\n");
return ret;
}
ret = beiscsi_init_sgl_handle(phba);
if (ret < 0) {
shost_printk(KERN_ERR, phba->shost,
"beiscsi_dev_probe - Failed in"
- "beiscsi_init_sgl_handle \n");
+ "beiscsi_init_sgl_handle\n");
goto do_cleanup_ctrlr;
}
@@ -3291,12 +3348,12 @@ static void hwi_purge_eq(struct beiscsi_hba *phba)
static void beiscsi_clean_port(struct beiscsi_hba *phba)
{
- unsigned char mgmt_status;
+ int mgmt_status;
mgmt_status = mgmt_epfw_cleanup(phba, CMD_CONNECTION_CHUTE_0);
if (mgmt_status)
shost_printk(KERN_WARNING, phba->shost,
- "mgmt_epfw_cleanup FAILED \n");
+ "mgmt_epfw_cleanup FAILED\n");
hwi_purge_eq(phba);
hwi_cleanup(phba);
@@ -3428,14 +3485,12 @@ static int beiscsi_alloc_pdu(struct iscsi_task *task, uint8_t opcode)
return -ENOMEM;
io_task->bhs_pa.u.a64.address = paddr;
io_task->libiscsi_itt = (itt_t)task->itt;
- io_task->pwrb_handle = alloc_wrb_handle(phba,
- beiscsi_conn->beiscsi_conn_cid -
- phba->fw_config.iscsi_cid_start
- );
io_task->conn = beiscsi_conn;
task->hdr = (struct iscsi_hdr *)&io_task->cmd_bhs->iscsi_hdr;
task->hdr_max = sizeof(struct be_cmd_bhs);
+ io_task->psgl_handle = NULL;
+ io_task->psgl_handle = NULL;
if (task->sc) {
spin_lock(&phba->io_sgl_lock);
@@ -3443,6 +3498,11 @@ static int beiscsi_alloc_pdu(struct iscsi_task *task, uint8_t opcode)
spin_unlock(&phba->io_sgl_lock);
if (!io_task->psgl_handle)
goto free_hndls;
+ io_task->pwrb_handle = alloc_wrb_handle(phba,
+ beiscsi_conn->beiscsi_conn_cid -
+ phba->fw_config.iscsi_cid_start);
+ if (!io_task->pwrb_handle)
+ goto free_io_hndls;
} else {
io_task->scsi_cmnd = NULL;
if ((opcode & ISCSI_OPCODE_MASK) == ISCSI_OP_LOGIN) {
@@ -3457,9 +3517,20 @@ static int beiscsi_alloc_pdu(struct iscsi_task *task, uint8_t opcode)
beiscsi_conn->login_in_progress = 1;
beiscsi_conn->plogin_sgl_handle =
io_task->psgl_handle;
+ io_task->pwrb_handle =
+ alloc_wrb_handle(phba,
+ beiscsi_conn->beiscsi_conn_cid -
+ phba->fw_config.iscsi_cid_start);
+ if (!io_task->pwrb_handle)
+ goto free_io_hndls;
+ beiscsi_conn->plogin_wrb_handle =
+ io_task->pwrb_handle;
+
} else {
io_task->psgl_handle =
beiscsi_conn->plogin_sgl_handle;
+ io_task->pwrb_handle =
+ beiscsi_conn->plogin_wrb_handle;
}
} else {
spin_lock(&phba->mgmt_sgl_lock);
@@ -3467,6 +3538,13 @@ static int beiscsi_alloc_pdu(struct iscsi_task *task, uint8_t opcode)
spin_unlock(&phba->mgmt_sgl_lock);
if (!io_task->psgl_handle)
goto free_hndls;
+ io_task->pwrb_handle =
+ alloc_wrb_handle(phba,
+ beiscsi_conn->beiscsi_conn_cid -
+ phba->fw_config.iscsi_cid_start);
+ if (!io_task->pwrb_handle)
+ goto free_mgmt_hndls;
+
}
}
itt = (itt_t) cpu_to_be32(((unsigned int)io_task->pwrb_handle->
@@ -3477,16 +3555,26 @@ static int beiscsi_alloc_pdu(struct iscsi_task *task, uint8_t opcode)
io_task->cmd_bhs->iscsi_hdr.itt = itt;
return 0;
+free_io_hndls:
+ spin_lock(&phba->io_sgl_lock);
+ free_io_sgl_handle(phba, io_task->psgl_handle);
+ spin_unlock(&phba->io_sgl_lock);
+ goto free_hndls;
+free_mgmt_hndls:
+ spin_lock(&phba->mgmt_sgl_lock);
+ free_mgmt_sgl_handle(phba, io_task->psgl_handle);
+ spin_unlock(&phba->mgmt_sgl_lock);
free_hndls:
phwi_ctrlr = phba->phwi_ctrlr;
pwrb_context = &phwi_ctrlr->wrb_context[
beiscsi_conn->beiscsi_conn_cid -
phba->fw_config.iscsi_cid_start];
- free_wrb_handle(phba, pwrb_context, io_task->pwrb_handle);
+ if (io_task->pwrb_handle)
+ free_wrb_handle(phba, pwrb_context, io_task->pwrb_handle);
io_task->pwrb_handle = NULL;
pci_pool_free(beiscsi_sess->bhs_pool, io_task->cmd_bhs,
io_task->bhs_pa.u.a64.address);
- SE_DEBUG(DBG_LVL_1, "Alloc of SGL_ICD Failed \n");
+ SE_DEBUG(DBG_LVL_1, "Alloc of SGL_ICD Failed\n");
return -ENOMEM;
}
@@ -3653,7 +3741,7 @@ static int beiscsi_mtask(struct iscsi_task *task)
break;
default:
- SE_DEBUG(DBG_LVL_1, "opcode =%d Not supported \n",
+ SE_DEBUG(DBG_LVL_1, "opcode =%d Not supported\n",
task->hdr->opcode & ISCSI_OPCODE_MASK);
return -EINVAL;
}
@@ -3689,13 +3777,11 @@ static int beiscsi_task_xmit(struct iscsi_task *task)
SE_DEBUG(DBG_LVL_1, " scsi_dma_map Failed\n")
return num_sg;
}
- SE_DEBUG(DBG_LVL_4, "xferlen=0x%08x scmd=%p num_sg=%d sernum=%lu\n",
- (scsi_bufflen(sc)), sc, num_sg, sc->serial_number);
xferlen = scsi_bufflen(sc);
sg = scsi_sglist(sc);
if (sc->sc_data_direction == DMA_TO_DEVICE) {
writedir = 1;
- SE_DEBUG(DBG_LVL_4, "task->imm_count=0x%08x \n",
+ SE_DEBUG(DBG_LVL_4, "task->imm_count=0x%08x\n",
task->imm_count);
} else
writedir = 0;
@@ -3709,10 +3795,12 @@ static void beiscsi_remove(struct pci_dev *pcidev)
struct hwi_context_memory *phwi_context;
struct be_eq_obj *pbe_eq;
unsigned int i, msix_vec;
+ u8 *real_offset = 0;
+ u32 value = 0;
phba = (struct beiscsi_hba *)pci_get_drvdata(pcidev);
if (!phba) {
- dev_err(&pcidev->dev, "beiscsi_remove called with no phba \n");
+ dev_err(&pcidev->dev, "beiscsi_remove called with no phba\n");
return;
}
@@ -3737,6 +3825,14 @@ static void beiscsi_remove(struct pci_dev *pcidev)
beiscsi_clean_port(phba);
beiscsi_free_mem(phba);
+ real_offset = (u8 *)phba->csr_va + MPU_EP_SEMAPHORE;
+
+ value = readl((void *)real_offset);
+
+ if (value & 0x00010000) {
+ value &= 0xfffeffff;
+ writel(value, (void *)real_offset);
+ }
beiscsi_unmap_pci_function(phba);
pci_free_consistent(phba->pcidev,
phba->ctrl.mbox_mem_alloced.size,
@@ -3769,19 +3865,21 @@ static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev,
struct hwi_controller *phwi_ctrlr;
struct hwi_context_memory *phwi_context;
struct be_eq_obj *pbe_eq;
- int ret, msix_vec, num_cpus, i;
+ int ret, num_cpus, i;
+ u8 *real_offset = 0;
+ u32 value = 0;
ret = beiscsi_enable_pci(pcidev);
if (ret < 0) {
- shost_printk(KERN_ERR, phba->shost, "beiscsi_dev_probe-"
- "Failed to enable pci device \n");
+ dev_err(&pcidev->dev, "beiscsi_dev_probe-"
+ " Failed to enable pci device\n");
return ret;
}
phba = beiscsi_hba_alloc(pcidev);
if (!phba) {
dev_err(&pcidev->dev, "beiscsi_dev_probe-"
- " Failed in beiscsi_hba_alloc \n");
+ " Failed in beiscsi_hba_alloc\n");
goto disable_pci;
}
@@ -3804,7 +3902,7 @@ static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev,
else
num_cpus = 1;
phba->num_cpus = num_cpus;
- SE_DEBUG(DBG_LVL_8, "num_cpus = %d \n", phba->num_cpus);
+ SE_DEBUG(DBG_LVL_8, "num_cpus = %d\n", phba->num_cpus);
if (enable_msix)
beiscsi_msix_enable(phba);
@@ -3815,6 +3913,33 @@ static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev,
goto hba_free;
}
+ if (!num_hba) {
+ real_offset = (u8 *)phba->csr_va + MPU_EP_SEMAPHORE;
+ value = readl((void *)real_offset);
+ if (value & 0x00010000) {
+ gcrashmode++;
+ shost_printk(KERN_ERR, phba->shost,
+ "Loading Driver in crashdump mode\n");
+ ret = beiscsi_pci_soft_reset(phba);
+ if (ret) {
+ shost_printk(KERN_ERR, phba->shost,
+ "Reset Failed. Aborting Crashdump\n");
+ goto hba_free;
+ }
+ ret = be_chk_reset_complete(phba);
+ if (ret) {
+ shost_printk(KERN_ERR, phba->shost,
+ "Failed to get out of reset."
+ "Aborting Crashdump\n");
+ goto hba_free;
+ }
+ } else {
+ value |= 0x00010000;
+ writel(value, (void *)real_offset);
+ num_hba++;
+ }
+ }
+
spin_lock_init(&phba->io_sgl_lock);
spin_lock_init(&phba->mgmt_sgl_lock);
spin_lock_init(&phba->isr_lock);
@@ -3870,25 +3995,10 @@ static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev,
"Failed to beiscsi_init_irqs\n");
goto free_blkenbld;
}
- ret = hwi_enable_intr(phba);
- if (ret < 0) {
- shost_printk(KERN_ERR, phba->shost, "beiscsi_dev_probe-"
- "Failed to hwi_enable_intr\n");
- goto free_ctrlr;
- }
- SE_DEBUG(DBG_LVL_8, "\n\n\n SUCCESS - DRIVER LOADED \n\n\n");
+ hwi_enable_intr(phba);
+ SE_DEBUG(DBG_LVL_8, "\n\n\n SUCCESS - DRIVER LOADED\n\n\n");
return 0;
-free_ctrlr:
- if (phba->msix_enabled) {
- for (i = 0; i <= phba->num_cpus; i++) {
- msix_vec = phba->msix_entries[i].vector;
- free_irq(msix_vec, &phwi_context->be_eq[i]);
- }
- } else
- if (phba->pcidev->irq)
- free_irq(phba->pcidev->irq, phba);
- pci_disable_msix(phba->pcidev);
free_blkenbld:
destroy_workqueue(phba->wq);
if (blk_iopoll_enabled)
@@ -3900,12 +4010,23 @@ free_twq:
beiscsi_clean_port(phba);
beiscsi_free_mem(phba);
free_port:
+ real_offset = (u8 *)phba->csr_va + MPU_EP_SEMAPHORE;
+
+ value = readl((void *)real_offset);
+
+ if (value & 0x00010000) {
+ value &= 0xfffeffff;
+ writel(value, (void *)real_offset);
+ }
+
pci_free_consistent(phba->pcidev,
phba->ctrl.mbox_mem_alloced.size,
phba->ctrl.mbox_mem_alloced.va,
phba->ctrl.mbox_mem_alloced.dma);
beiscsi_unmap_pci_function(phba);
hba_free:
+ if (phba->msix_enabled)
+ pci_disable_msix(phba->pcidev);
iscsi_host_remove(phba->shost);
pci_dev_put(phba->pcidev);
iscsi_host_free(phba->shost);
@@ -3955,7 +4076,7 @@ struct iscsi_transport beiscsi_iscsi_transport = {
.get_session_param = iscsi_session_get_param,
.get_host_param = beiscsi_get_host_param,
.start_conn = beiscsi_conn_start,
- .stop_conn = beiscsi_conn_stop,
+ .stop_conn = iscsi_conn_stop,
.send_pdu = iscsi_conn_send_pdu,
.xmit_task = beiscsi_task_xmit,
.cleanup_task = beiscsi_cleanup_task,
@@ -3988,7 +4109,7 @@ static int __init beiscsi_module_init(void)
"transport.\n");
return -ENOMEM;
}
- SE_DEBUG(DBG_LVL_8, "In beiscsi_module_init, tt=%p \n",
+ SE_DEBUG(DBG_LVL_8, "In beiscsi_module_init, tt=%p\n",
&beiscsi_iscsi_transport);
ret = pci_register_driver(&beiscsi_pci_driver);
diff --git a/drivers/scsi/be2iscsi/be_main.h b/drivers/scsi/be2iscsi/be_main.h
index 87ec21280a3..c643bb3736f 100644
--- a/drivers/scsi/be2iscsi/be_main.h
+++ b/drivers/scsi/be2iscsi/be_main.h
@@ -23,6 +23,7 @@
#include <linux/kernel.h>
#include <linux/pci.h>
+#include <linux/if_ether.h>
#include <linux/in.h>
#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
@@ -39,7 +40,7 @@
"Linux iSCSI Driver version" BUILD_STR
#define DRV_DESC BE_NAME " " "Driver"
-#define BE_VENDOR_ID 0x19A2
+#define BE_VENDOR_ID 0x19A2
/* DEVICE ID's for BE2 */
#define BE_DEVICE_ID1 0x212
#define OC_DEVICE_ID1 0x702
@@ -68,8 +69,15 @@
#define BEISCSI_NUM_MAX_LUN 256 /* scsi_host->max_lun */
#define BEISCSI_NUM_DEVICES_SUPPORTED 0x01
#define BEISCSI_MAX_FRAGS_INIT 192
-#define BE_NUM_MSIX_ENTRIES 1
-#define MPU_EP_SEMAPHORE 0xac
+#define BE_NUM_MSIX_ENTRIES 1
+
+#define MPU_EP_CONTROL 0
+#define MPU_EP_SEMAPHORE 0xac
+#define BE2_SOFT_RESET 0x5c
+#define BE2_PCI_ONLINE0 0xb0
+#define BE2_PCI_ONLINE1 0xb4
+#define BE2_SET_RESET 0x80
+#define BE2_MPU_IRAM_ONLINE 0x00000080
#define BE_SENSE_INFO_SIZE 258
#define BE_ISCSI_PDU_HEADER_SIZE 64
@@ -105,7 +113,7 @@ do { \
#define HWI_GET_ASYNC_PDU_CTX(phwi) (phwi->phwi_ctxt->pasync_ctx)
/********* Memory BAR register ************/
-#define PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET 0xfc
+#define PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET 0xfc
/**
* Host Interrupt Enable, if set interrupts are enabled although "PCI Interrupt
* Disable" may still globally block interrupts in addition to individual
@@ -116,7 +124,7 @@ do { \
#define MEMBAR_CTRL_INT_CTRL_HOSTINTR_MASK (1 << 29) /* bit 29 */
/********* ISR0 Register offset **********/
-#define CEV_ISR0_OFFSET 0xC18
+#define CEV_ISR0_OFFSET 0xC18
#define CEV_ISR_SIZE 4
/**
@@ -139,12 +147,12 @@ do { \
#define DB_EQ_REARM_SHIFT (29) /* bit 29 */
/********* Compl Q door bell *************/
-#define DB_CQ_OFFSET 0x120
+#define DB_CQ_OFFSET 0x120
#define DB_CQ_RING_ID_MASK 0x3FF /* bits 0 - 9 */
/* Number of event entries processed */
-#define DB_CQ_NUM_POPPED_SHIFT (16) /* bits 16 - 28 */
+#define DB_CQ_NUM_POPPED_SHIFT (16) /* bits 16 - 28 */
/* Rearm bit */
-#define DB_CQ_REARM_SHIFT (29) /* bit 29 */
+#define DB_CQ_REARM_SHIFT (29) /* bit 29 */
#define GET_HWI_CONTROLLER_WS(pc) (pc->phwi_ctrlr)
#define HWI_GET_DEF_BUFQ_ID(pc) (((struct hwi_controller *)\
@@ -161,12 +169,12 @@ enum be_mem_enum {
HWI_MEM_WRBH,
HWI_MEM_SGLH,
HWI_MEM_SGE,
- HWI_MEM_ASYNC_HEADER_BUF, /* 5 */
+ HWI_MEM_ASYNC_HEADER_BUF, /* 5 */
HWI_MEM_ASYNC_DATA_BUF,
HWI_MEM_ASYNC_HEADER_RING,
HWI_MEM_ASYNC_DATA_RING,
HWI_MEM_ASYNC_HEADER_HANDLE,
- HWI_MEM_ASYNC_DATA_HANDLE, /* 10 */
+ HWI_MEM_ASYNC_DATA_HANDLE, /* 10 */
HWI_MEM_ASYNC_PDU_CONTEXT,
ISCSI_MEM_GLOBAL_HEADER,
SE_MEM_MAX
@@ -352,6 +360,7 @@ struct beiscsi_conn {
u32 beiscsi_conn_cid;
struct beiscsi_endpoint *ep;
unsigned short login_in_progress;
+ struct wrb_handle *plogin_wrb_handle;
struct sgl_handle *plogin_sgl_handle;
struct beiscsi_session *beiscsi_sess;
struct iscsi_task *task;
diff --git a/drivers/scsi/be2iscsi/be_mgmt.c b/drivers/scsi/be2iscsi/be_mgmt.c
index 350cbeaae16..3f3fab91a7d 100644
--- a/drivers/scsi/be2iscsi/be_mgmt.c
+++ b/drivers/scsi/be2iscsi/be_mgmt.c
@@ -21,7 +21,7 @@
#include "be_mgmt.h"
#include "be_iscsi.h"
-unsigned char mgmt_get_fw_config(struct be_ctrl_info *ctrl,
+int mgmt_get_fw_config(struct be_ctrl_info *ctrl,
struct beiscsi_hba *phba)
{
struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
@@ -50,7 +50,7 @@ unsigned char mgmt_get_fw_config(struct be_ctrl_info *ctrl,
pfw_cfg->ulp[0].sq_count;
if (phba->fw_config.iscsi_cid_count > (BE2_MAX_SESSIONS / 2)) {
SE_DEBUG(DBG_LVL_8,
- "FW reported MAX CXNS as %d \t"
+ "FW reported MAX CXNS as %d\t"
"Max Supported = %d.\n",
phba->fw_config.iscsi_cid_count,
BE2_MAX_SESSIONS);
@@ -58,14 +58,14 @@ unsigned char mgmt_get_fw_config(struct be_ctrl_info *ctrl,
}
} else {
shost_printk(KERN_WARNING, phba->shost,
- "Failed in mgmt_get_fw_config \n");
+ "Failed in mgmt_get_fw_config\n");
}
spin_unlock(&ctrl->mbox_lock);
return status;
}
-unsigned char mgmt_check_supported_fw(struct be_ctrl_info *ctrl,
+int mgmt_check_supported_fw(struct be_ctrl_info *ctrl,
struct beiscsi_hba *phba)
{
struct be_dma_mem nonemb_cmd;
@@ -81,7 +81,7 @@ unsigned char mgmt_check_supported_fw(struct be_ctrl_info *ctrl,
SE_DEBUG(DBG_LVL_1,
"Failed to allocate memory for mgmt_check_supported_fw"
"\n");
- return -1;
+ return -ENOMEM;
}
nonemb_cmd.size = sizeof(struct be_mgmt_controller_attributes);
req = nonemb_cmd.va;
@@ -117,8 +117,7 @@ unsigned char mgmt_check_supported_fw(struct be_ctrl_info *ctrl,
return status;
}
-
-unsigned char mgmt_epfw_cleanup(struct beiscsi_hba *phba, unsigned short chute)
+int mgmt_epfw_cleanup(struct beiscsi_hba *phba, unsigned short chute)
{
struct be_ctrl_info *ctrl = &phba->ctrl;
struct be_mcc_wrb *wrb = wrb_from_mccq(phba);
@@ -144,11 +143,12 @@ unsigned char mgmt_epfw_cleanup(struct beiscsi_hba *phba, unsigned short chute)
return status;
}
-unsigned char mgmt_invalidate_icds(struct beiscsi_hba *phba,
+unsigned int mgmt_invalidate_icds(struct beiscsi_hba *phba,
struct invalidate_command_table *inv_tbl,
- unsigned int num_invalidate, unsigned int cid)
+ unsigned int num_invalidate, unsigned int cid,
+ struct be_dma_mem *nonemb_cmd)
+
{
- struct be_dma_mem nonemb_cmd;
struct be_ctrl_info *ctrl = &phba->ctrl;
struct be_mcc_wrb *wrb;
struct be_sge *sge;
@@ -162,17 +162,7 @@ unsigned char mgmt_invalidate_icds(struct beiscsi_hba *phba,
return tag;
}
- nonemb_cmd.va = pci_alloc_consistent(ctrl->pdev,
- sizeof(struct invalidate_commands_params_in),
- &nonemb_cmd.dma);
- if (nonemb_cmd.va == NULL) {
- SE_DEBUG(DBG_LVL_1,
- "Failed to allocate memory for mgmt_invalidate_icds\n");
- spin_unlock(&ctrl->mbox_lock);
- return 0;
- }
- nonemb_cmd.size = sizeof(struct invalidate_commands_params_in);
- req = nonemb_cmd.va;
+ req = nonemb_cmd->va;
memset(req, 0, sizeof(*req));
wrb = wrb_from_mccq(phba);
sge = nonembedded_sgl(wrb);
@@ -190,19 +180,16 @@ unsigned char mgmt_invalidate_icds(struct beiscsi_hba *phba,
req->icd_count++;
inv_tbl++;
}
- sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd.dma));
- sge->pa_lo = cpu_to_le32(nonemb_cmd.dma & 0xFFFFFFFF);
- sge->len = cpu_to_le32(nonemb_cmd.size);
+ sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
+ sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
+ sge->len = cpu_to_le32(nonemb_cmd->size);
be_mcc_notify(phba);
spin_unlock(&ctrl->mbox_lock);
- if (nonemb_cmd.va)
- pci_free_consistent(ctrl->pdev, nonemb_cmd.size,
- nonemb_cmd.va, nonemb_cmd.dma);
return tag;
}
-unsigned char mgmt_invalidate_connection(struct beiscsi_hba *phba,
+unsigned int mgmt_invalidate_connection(struct beiscsi_hba *phba,
struct beiscsi_endpoint *beiscsi_ep,
unsigned short cid,
unsigned short issue_reset,
@@ -239,7 +226,7 @@ unsigned char mgmt_invalidate_connection(struct beiscsi_hba *phba,
return tag;
}
-unsigned char mgmt_upload_connection(struct beiscsi_hba *phba,
+unsigned int mgmt_upload_connection(struct beiscsi_hba *phba,
unsigned short cid, unsigned int upload_flag)
{
struct be_ctrl_info *ctrl = &phba->ctrl;
@@ -269,7 +256,9 @@ unsigned char mgmt_upload_connection(struct beiscsi_hba *phba,
int mgmt_open_connection(struct beiscsi_hba *phba,
struct sockaddr *dst_addr,
- struct beiscsi_endpoint *beiscsi_ep)
+ struct beiscsi_endpoint *beiscsi_ep,
+ struct be_dma_mem *nonemb_cmd)
+
{
struct hwi_controller *phwi_ctrlr;
struct hwi_context_memory *phwi_context;
@@ -285,6 +274,7 @@ int mgmt_open_connection(struct beiscsi_hba *phba,
unsigned int tag = 0;
unsigned int i;
unsigned short cid = beiscsi_ep->ep_cid;
+ struct be_sge *sge;
phwi_ctrlr = phba->phwi_ctrlr;
phwi_context = phwi_ctrlr->phwi_ctxt;
@@ -300,10 +290,14 @@ int mgmt_open_connection(struct beiscsi_hba *phba,
return tag;
}
wrb = wrb_from_mccq(phba);
- req = embedded_payload(wrb);
+ memset(wrb, 0, sizeof(*wrb));
+ sge = nonembedded_sgl(wrb);
+
+ req = nonemb_cmd->va;
+ memset(req, 0, sizeof(*req));
wrb->tag0 |= tag;
- be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
+ be_wrb_hdr_prepare(wrb, sizeof(*req), true, 1);
be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
OPCODE_COMMON_ISCSI_TCP_CONNECT_AND_OFFLOAD,
sizeof(*req));
@@ -331,6 +325,7 @@ int mgmt_open_connection(struct beiscsi_hba *phba,
shost_printk(KERN_ERR, phba->shost, "unknown addr family %d\n",
dst_addr->sa_family);
spin_unlock(&ctrl->mbox_lock);
+ free_mcc_tag(&phba->ctrl, tag);
return -EINVAL;
}
@@ -339,13 +334,16 @@ int mgmt_open_connection(struct beiscsi_hba *phba,
if (phba->nxt_cqid == phba->num_cpus)
phba->nxt_cqid = 0;
req->cq_id = phwi_context->be_cq[i].id;
- SE_DEBUG(DBG_LVL_8, "i=%d cq_id=%d \n", i, req->cq_id);
+ SE_DEBUG(DBG_LVL_8, "i=%d cq_id=%d\n", i, req->cq_id);
req->defq_id = def_hdr_id;
req->hdr_ring_id = def_hdr_id;
req->data_ring_id = def_data_id;
req->do_offload = 1;
req->dataout_template_pa.lo = ptemplate_address->lo;
req->dataout_template_pa.hi = ptemplate_address->hi;
+ sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
+ sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
+ sge->len = cpu_to_le32(nonemb_cmd->size);
be_mcc_notify(phba);
spin_unlock(&ctrl->mbox_lock);
return tag;
diff --git a/drivers/scsi/be2iscsi/be_mgmt.h b/drivers/scsi/be2iscsi/be_mgmt.h
index 3d316b82feb..b9acedf7865 100644
--- a/drivers/scsi/be2iscsi/be_mgmt.h
+++ b/drivers/scsi/be2iscsi/be_mgmt.h
@@ -86,16 +86,19 @@ struct mcc_wrb {
struct mcc_wrb_payload payload;
};
-unsigned char mgmt_epfw_cleanup(struct beiscsi_hba *phba, unsigned short chute);
-int mgmt_open_connection(struct beiscsi_hba *phba, struct sockaddr *dst_addr,
- struct beiscsi_endpoint *beiscsi_ep);
+int mgmt_epfw_cleanup(struct beiscsi_hba *phba, unsigned short chute);
+int mgmt_open_connection(struct beiscsi_hba *phba,
+ struct sockaddr *dst_addr,
+ struct beiscsi_endpoint *beiscsi_ep,
+ struct be_dma_mem *nonemb_cmd);
-unsigned char mgmt_upload_connection(struct beiscsi_hba *phba,
+unsigned int mgmt_upload_connection(struct beiscsi_hba *phba,
unsigned short cid,
unsigned int upload_flag);
-unsigned char mgmt_invalidate_icds(struct beiscsi_hba *phba,
+unsigned int mgmt_invalidate_icds(struct beiscsi_hba *phba,
struct invalidate_command_table *inv_tbl,
- unsigned int num_invalidate, unsigned int cid);
+ unsigned int num_invalidate, unsigned int cid,
+ struct be_dma_mem *nonemb_cmd);
struct iscsi_invalidate_connection_params_in {
struct be_cmd_req_hdr hdr;
@@ -237,10 +240,10 @@ struct beiscsi_endpoint {
u16 cid_vld;
};
-unsigned char mgmt_get_fw_config(struct be_ctrl_info *ctrl,
+int mgmt_get_fw_config(struct be_ctrl_info *ctrl,
struct beiscsi_hba *phba);
-unsigned char mgmt_invalidate_connection(struct beiscsi_hba *phba,
+unsigned int mgmt_invalidate_connection(struct beiscsi_hba *phba,
struct beiscsi_endpoint *beiscsi_ep,
unsigned short cid,
unsigned short issue_reset,
diff --git a/drivers/scsi/bfa/Makefile b/drivers/scsi/bfa/Makefile
index 17e06cae71b..ac3fdf02d5f 100644
--- a/drivers/scsi/bfa/Makefile
+++ b/drivers/scsi/bfa/Makefile
@@ -1,7 +1,7 @@
obj-$(CONFIG_SCSI_BFA_FC) := bfa.o
bfa-y := bfad.o bfad_intr.o bfad_os.o bfad_im.o bfad_attr.o bfad_fwimg.o
-
+bfa-y += bfad_debugfs.o
bfa-y += bfa_core.o bfa_ioc.o bfa_ioc_ct.o bfa_ioc_cb.o bfa_iocfc.o bfa_fcxp.o
bfa-y += bfa_lps.o bfa_hw_cb.o bfa_hw_ct.o bfa_intr.o bfa_timer.o bfa_rport.o
bfa-y += bfa_fcport.o bfa_port.o bfa_uf.o bfa_sgpg.o bfa_module.o bfa_ioim.o
diff --git a/drivers/scsi/bfa/bfa_cb_ioim_macros.h b/drivers/scsi/bfa/bfa_cb_ioim_macros.h
index 53a616f5f50..3906ed92696 100644
--- a/drivers/scsi/bfa/bfa_cb_ioim_macros.h
+++ b/drivers/scsi/bfa/bfa_cb_ioim_macros.h
@@ -171,6 +171,11 @@ bfa_cb_ioim_get_cdblen(struct bfad_ioim_s *dio)
return cmnd->cmd_len;
}
-
+/**
+ * Assign queue to be used for the I/O request. This value depends on whether
+ * the driver wants to use the queues via any specific algorithm. Currently,
+ * this is not supported.
+ */
+#define bfa_cb_ioim_get_reqq(__dio) BFA_FALSE
#endif /* __BFA_HCB_IOIM_MACROS_H__ */
diff --git a/drivers/scsi/bfa/bfa_core.c b/drivers/scsi/bfa/bfa_core.c
index 3a7b3f88932..bef70924d5c 100644
--- a/drivers/scsi/bfa/bfa_core.c
+++ b/drivers/scsi/bfa/bfa_core.c
@@ -333,6 +333,7 @@ bfa_get_pciids(struct bfa_pciid_s **pciids, int *npciids)
{BFA_PCI_VENDOR_ID_BROCADE, BFA_PCI_DEVICE_ID_FC_8G2P},
{BFA_PCI_VENDOR_ID_BROCADE, BFA_PCI_DEVICE_ID_FC_8G1P},
{BFA_PCI_VENDOR_ID_BROCADE, BFA_PCI_DEVICE_ID_CT},
+ {BFA_PCI_VENDOR_ID_BROCADE, BFA_PCI_DEVICE_ID_CT_FC},
};
*npciids = sizeof(__pciids) / sizeof(__pciids[0]);
diff --git a/drivers/scsi/bfa/bfa_fcpim.c b/drivers/scsi/bfa/bfa_fcpim.c
index 790c945aeae..8c703d8dc94 100644
--- a/drivers/scsi/bfa/bfa_fcpim.c
+++ b/drivers/scsi/bfa/bfa_fcpim.c
@@ -80,11 +80,6 @@ bfa_fcpim_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
}
static void
-bfa_fcpim_initdone(struct bfa_s *bfa)
-{
-}
-
-static void
bfa_fcpim_detach(struct bfa_s *bfa)
{
struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
@@ -172,4 +167,28 @@ bfa_fcpim_qdepth_get(struct bfa_s *bfa)
return fcpim->q_depth;
}
+void
+bfa_fcpim_update_ioredirect(struct bfa_s *bfa)
+{
+ bfa_boolean_t ioredirect;
+
+ /*
+ * IO redirection is turned off when QoS is enabled and vice versa
+ */
+ ioredirect = bfa_fcport_is_qos_enabled(bfa) ? BFA_FALSE : BFA_TRUE;
+ /*
+ * Notify the bfad module of a possible state change in
+ * IO redirection capability, due to a QoS state change. bfad will
+ * check on the support for io redirection and update the
+ * fcpim's ioredirect state accordingly.
+ */
+ bfa_cb_ioredirect_state_change((void *)(bfa->bfad), ioredirect);
+}
+
+void
+bfa_fcpim_set_ioredirect(struct bfa_s *bfa, bfa_boolean_t state)
+{
+ struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
+ fcpim->ioredirect = state;
+}
diff --git a/drivers/scsi/bfa/bfa_fcpim_priv.h b/drivers/scsi/bfa/bfa_fcpim_priv.h
index 5cf418460f7..762516cb5cb 100644
--- a/drivers/scsi/bfa/bfa_fcpim_priv.h
+++ b/drivers/scsi/bfa/bfa_fcpim_priv.h
@@ -49,7 +49,8 @@ struct bfa_fcpim_mod_s {
int num_tskim_reqs;
u32 path_tov;
u16 q_depth;
- u16 rsvd;
+ u8 reqq; /* Request queue to be used */
+ u8 rsvd;
struct list_head itnim_q; /* queue of active itnim */
struct list_head ioim_free_q; /* free IO resources */
struct list_head ioim_resfree_q; /* IOs waiting for f/w */
@@ -58,6 +59,7 @@ struct bfa_fcpim_mod_s {
u32 ios_active; /* current active IOs */
u32 delay_comp;
struct bfa_fcpim_stats_s stats;
+ bfa_boolean_t ioredirect;
};
struct bfa_ioim_s;
@@ -82,6 +84,7 @@ struct bfa_ioim_s {
struct bfa_cb_qe_s hcb_qe; /* bfa callback qelem */
bfa_cb_cbfn_t io_cbfn; /* IO completion handler */
struct bfa_ioim_sp_s *iosp; /* slow-path IO handling */
+ u8 reqq; /* Request queue for I/O */
};
struct bfa_ioim_sp_s {
@@ -141,6 +144,7 @@ struct bfa_itnim_s {
struct bfa_reqq_wait_s reqq_wait; /* to wait for room in reqq */
struct bfa_fcpim_mod_s *fcpim; /* fcpim module */
struct bfa_itnim_hal_stats_s stats;
+ struct bfa_itnim_latency_s io_latency;
};
#define bfa_itnim_is_online(_itnim) ((_itnim)->is_online)
diff --git a/drivers/scsi/bfa/bfa_fcport.c b/drivers/scsi/bfa/bfa_fcport.c
index c589488db0c..f0933d8d1ed 100644
--- a/drivers/scsi/bfa/bfa_fcport.c
+++ b/drivers/scsi/bfa/bfa_fcport.c
@@ -18,6 +18,7 @@
#include <bfa.h>
#include <bfa_svc.h>
#include <bfi/bfi_pport.h>
+#include <bfi/bfi_pbc.h>
#include <cs/bfa_debug.h>
#include <aen/bfa_aen.h>
#include <cs/bfa_plog.h>
@@ -310,10 +311,12 @@ bfa_fcport_sm_linkdown(struct bfa_fcport_s *fcport,
if (!bfa_ioc_get_fcmode(&fcport->bfa->ioc)) {
- bfa_trc(fcport->bfa, pevent->link_state.fcf.fipenabled);
- bfa_trc(fcport->bfa, pevent->link_state.fcf.fipfailed);
+ bfa_trc(fcport->bfa,
+ pevent->link_state.vc_fcf.fcf.fipenabled);
+ bfa_trc(fcport->bfa,
+ pevent->link_state.vc_fcf.fcf.fipfailed);
- if (pevent->link_state.fcf.fipfailed)
+ if (pevent->link_state.vc_fcf.fcf.fipfailed)
bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
BFA_PL_EID_FIP_FCF_DISC, 0,
"FIP FCF Discovery Failed");
@@ -888,6 +891,7 @@ bfa_fcport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
struct bfa_pport_cfg_s *port_cfg = &fcport->cfg;
struct bfa_fcport_ln_s *ln = &fcport->ln;
+ struct bfa_timeval_s tv;
bfa_os_memset(fcport, 0, sizeof(struct bfa_fcport_s));
fcport->bfa = bfa;
@@ -899,6 +903,12 @@ bfa_fcport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn);
/**
+ * initialize time stamp for stats reset
+ */
+ bfa_os_gettimeofday(&tv);
+ fcport->stats_reset_time = tv.tv_sec;
+
+ /**
* initialize and set default configuration
*/
port_cfg->topology = BFA_PPORT_TOPOLOGY_P2P;
@@ -912,25 +922,6 @@ bfa_fcport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
}
static void
-bfa_fcport_initdone(struct bfa_s *bfa)
-{
- struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
-
- /**
- * Initialize port attributes from IOC hardware data.
- */
- bfa_fcport_set_wwns(fcport);
- if (fcport->cfg.maxfrsize == 0)
- fcport->cfg.maxfrsize = bfa_ioc_maxfrsize(&bfa->ioc);
- fcport->cfg.rx_bbcredit = bfa_ioc_rx_bbcredit(&bfa->ioc);
- fcport->speed_sup = bfa_ioc_speed_sup(&bfa->ioc);
-
- bfa_assert(fcport->cfg.maxfrsize);
- bfa_assert(fcport->cfg.rx_bbcredit);
- bfa_assert(fcport->speed_sup);
-}
-
-static void
bfa_fcport_detach(struct bfa_s *bfa)
{
}
@@ -971,14 +962,15 @@ bfa_fcport_update_linkinfo(struct bfa_fcport_s *fcport)
fcport->topology = pevent->link_state.topology;
if (fcport->topology == BFA_PPORT_TOPOLOGY_LOOP)
- fcport->myalpa =
- pevent->link_state.tl.loop_info.myalpa;
+ fcport->myalpa = 0;
/*
* QoS Details
*/
bfa_os_assign(fcport->qos_attr, pevent->link_state.qos_attr);
- bfa_os_assign(fcport->qos_vc_attr, pevent->link_state.qos_vc_attr);
+ bfa_os_assign(fcport->qos_vc_attr,
+ pevent->link_state.vc_fcf.qos_vc_attr);
+
bfa_trc(fcport->bfa, fcport->speed);
bfa_trc(fcport->bfa, fcport->topology);
@@ -1145,16 +1137,22 @@ __bfa_cb_fcport_stats_get(void *cbarg, bfa_boolean_t complete)
if (complete) {
if (fcport->stats_status == BFA_STATUS_OK) {
+ struct bfa_timeval_s tv;
/* Swap FC QoS or FCoE stats */
- if (bfa_ioc_get_fcmode(&fcport->bfa->ioc))
+ if (bfa_ioc_get_fcmode(&fcport->bfa->ioc)) {
bfa_fcport_qos_stats_swap(
&fcport->stats_ret->fcqos,
&fcport->stats->fcqos);
- else
+ } else {
bfa_fcport_fcoe_stats_swap(
&fcport->stats_ret->fcoe,
&fcport->stats->fcoe);
+
+ bfa_os_gettimeofday(&tv);
+ fcport->stats_ret->fcoe.secs_reset =
+ tv.tv_sec - fcport->stats_reset_time;
+ }
}
fcport->stats_cbfn(fcport->stats_cbarg, fcport->stats_status);
} else {
@@ -1210,6 +1208,14 @@ __bfa_cb_fcport_stats_clr(void *cbarg, bfa_boolean_t complete)
struct bfa_fcport_s *fcport = cbarg;
if (complete) {
+ struct bfa_timeval_s tv;
+
+ /**
+ * re-initialize time stamp for stats reset
+ */
+ bfa_os_gettimeofday(&tv);
+ fcport->stats_reset_time = tv.tv_sec;
+
fcport->stats_cbfn(fcport->stats_cbarg, fcport->stats_status);
} else {
fcport->stats_busy = BFA_FALSE;
@@ -1263,6 +1269,29 @@ bfa_fcport_send_stats_clear(void *cbarg)
*/
/**
+ * Called to initialize port attributes
+ */
+void
+bfa_fcport_init(struct bfa_s *bfa)
+{
+ struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
+
+ /**
+ * Initialize port attributes from IOC hardware data.
+ */
+ bfa_fcport_set_wwns(fcport);
+ if (fcport->cfg.maxfrsize == 0)
+ fcport->cfg.maxfrsize = bfa_ioc_maxfrsize(&bfa->ioc);
+ fcport->cfg.rx_bbcredit = bfa_ioc_rx_bbcredit(&bfa->ioc);
+ fcport->speed_sup = bfa_ioc_speed_sup(&bfa->ioc);
+
+ bfa_assert(fcport->cfg.maxfrsize);
+ bfa_assert(fcport->cfg.rx_bbcredit);
+ bfa_assert(fcport->speed_sup);
+}
+
+
+/**
* Firmware message handler.
*/
void
@@ -1355,6 +1384,17 @@ bfa_status_t
bfa_fcport_enable(struct bfa_s *bfa)
{
struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
+ struct bfa_iocfc_s *iocfc = &bfa->iocfc;
+ struct bfi_iocfc_cfgrsp_s *cfgrsp = iocfc->cfgrsp;
+
+ /* if port is PBC disabled, return error */
+ if (cfgrsp->pbc_cfg.port_enabled == BFI_PBC_PORT_DISABLED) {
+ bfa_trc(bfa, fcport->pwwn);
+ return BFA_STATUS_PBC;
+ }
+
+ if (bfa_ioc_is_disabled(&bfa->ioc))
+ return BFA_STATUS_IOC_DISABLED;
if (fcport->diag_busy)
return BFA_STATUS_DIAG_BUSY;
@@ -1369,6 +1409,16 @@ bfa_fcport_enable(struct bfa_s *bfa)
bfa_status_t
bfa_fcport_disable(struct bfa_s *bfa)
{
+ struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
+ struct bfa_iocfc_s *iocfc = &bfa->iocfc;
+ struct bfi_iocfc_cfgrsp_s *cfgrsp = iocfc->cfgrsp;
+
+ /* if port is PBC disabled, return error */
+ if (cfgrsp->pbc_cfg.port_enabled == BFI_PBC_PORT_DISABLED) {
+ bfa_trc(bfa, fcport->pwwn);
+ return BFA_STATUS_PBC;
+ }
+
bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_DISABLE);
return BFA_STATUS_OK;
}
@@ -1559,12 +1609,17 @@ void
bfa_fcport_get_attr(struct bfa_s *bfa, struct bfa_pport_attr_s *attr)
{
struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
+ struct bfa_iocfc_s *iocfc = &bfa->iocfc;
+ struct bfi_iocfc_cfgrsp_s *cfgrsp = iocfc->cfgrsp;
bfa_os_memset(attr, 0, sizeof(struct bfa_pport_attr_s));
attr->nwwn = fcport->nwwn;
attr->pwwn = fcport->pwwn;
+ attr->factorypwwn = bfa_ioc_get_mfg_pwwn(&bfa->ioc);
+ attr->factorynwwn = bfa_ioc_get_mfg_nwwn(&bfa->ioc);
+
bfa_os_memcpy(&attr->pport_cfg, &fcport->cfg,
sizeof(struct bfa_pport_cfg_s));
/*
@@ -1590,11 +1645,18 @@ bfa_fcport_get_attr(struct bfa_s *bfa, struct bfa_pport_attr_s *attr)
attr->pport_cfg.path_tov = bfa_fcpim_path_tov_get(bfa);
attr->pport_cfg.q_depth = bfa_fcpim_qdepth_get(bfa);
- attr->port_state = bfa_sm_to_state(hal_pport_sm_table, fcport->sm);
- if (bfa_ioc_is_disabled(&fcport->bfa->ioc))
- attr->port_state = BFA_PPORT_ST_IOCDIS;
- else if (bfa_ioc_fw_mismatch(&fcport->bfa->ioc))
- attr->port_state = BFA_PPORT_ST_FWMISMATCH;
+
+ /* PBC Disabled State */
+ if (cfgrsp->pbc_cfg.port_enabled == BFI_PBC_PORT_DISABLED)
+ attr->port_state = BFA_PPORT_ST_PREBOOT_DISABLED;
+ else {
+ attr->port_state = bfa_sm_to_state(
+ hal_pport_sm_table, fcport->sm);
+ if (bfa_ioc_is_disabled(&fcport->bfa->ioc))
+ attr->port_state = BFA_PPORT_ST_IOCDIS;
+ else if (bfa_ioc_fw_mismatch(&fcport->bfa->ioc))
+ attr->port_state = BFA_PPORT_ST_FWMISMATCH;
+ }
}
#define BFA_FCPORT_STATS_TOV 1000
@@ -1801,8 +1863,13 @@ bfa_fcport_cfg_qos(struct bfa_s *bfa, bfa_boolean_t on_off)
bfa_trc(bfa, ioc_type);
- if (ioc_type == BFA_IOC_TYPE_FC)
+ if (ioc_type == BFA_IOC_TYPE_FC) {
fcport->cfg.qos_enabled = on_off;
+ /**
+ * Notify fcpim of the change in QoS state
+ */
+ bfa_fcpim_update_ioredirect(bfa);
+ }
}
void
@@ -1886,4 +1953,10 @@ bfa_fcport_is_linkup(struct bfa_s *bfa)
return bfa_sm_cmp_state(BFA_FCPORT_MOD(bfa), bfa_fcport_sm_linkup);
}
+bfa_boolean_t
+bfa_fcport_is_qos_enabled(struct bfa_s *bfa)
+{
+ struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
+ return fcport->cfg.qos_enabled;
+}
diff --git a/drivers/scsi/bfa/bfa_fcs.c b/drivers/scsi/bfa/bfa_fcs.c
index 3516172c597..3ec2f49de61 100644
--- a/drivers/scsi/bfa/bfa_fcs.c
+++ b/drivers/scsi/bfa/bfa_fcs.c
@@ -99,14 +99,22 @@ bfa_fcs_attach(struct bfa_fcs_s *fcs, struct bfa_s *bfa, struct bfad_s *bfad,
void
bfa_fcs_init(struct bfa_fcs_s *fcs)
{
- int i;
+ int i, npbc_vports;
struct bfa_fcs_mod_s *mod;
+ struct bfi_pbc_vport_s pbc_vports[BFI_PBC_MAX_VPORTS];
for (i = 0; i < sizeof(fcs_modules) / sizeof(fcs_modules[0]); i++) {
mod = &fcs_modules[i];
if (mod->modinit)
mod->modinit(fcs);
}
+ /* Initialize pbc vports */
+ if (!fcs->min_cfg) {
+ npbc_vports =
+ bfa_iocfc_get_pbc_vports(fcs->bfa, pbc_vports);
+ for (i = 0; i < npbc_vports; i++)
+ bfa_fcb_pbc_vport_create(fcs->bfa->bfad, pbc_vports[i]);
+ }
}
/**
diff --git a/drivers/scsi/bfa/bfa_fcs_lport.c b/drivers/scsi/bfa/bfa_fcs_lport.c
index 7c1251c682d..35df20e68a5 100644
--- a/drivers/scsi/bfa/bfa_fcs_lport.c
+++ b/drivers/scsi/bfa/bfa_fcs_lport.c
@@ -135,6 +135,9 @@ bfa_fcs_port_sm_init(struct bfa_fcs_port_s *port, enum bfa_fcs_port_event event)
bfa_fcs_port_deleted(port);
break;
+ case BFA_FCS_PORT_SM_OFFLINE:
+ break;
+
default:
bfa_sm_fault(port->fcs, event);
}
diff --git a/drivers/scsi/bfa/bfa_fcxp.c b/drivers/scsi/bfa/bfa_fcxp.c
index cf0ad678268..8258f88bfee 100644
--- a/drivers/scsi/bfa/bfa_fcxp.c
+++ b/drivers/scsi/bfa/bfa_fcxp.c
@@ -149,11 +149,6 @@ bfa_fcxp_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
}
static void
-bfa_fcxp_initdone(struct bfa_s *bfa)
-{
-}
-
-static void
bfa_fcxp_detach(struct bfa_s *bfa)
{
}
@@ -225,7 +220,7 @@ bfa_fcxp_null_comp(void *bfad_fcxp, struct bfa_fcxp_s *fcxp, void *cbarg,
bfa_status_t req_status, u32 rsp_len,
u32 resid_len, struct fchs_s *rsp_fchs)
{
- /**discarded fcxp completion */
+ /* discarded fcxp completion */
}
static void
@@ -527,11 +522,8 @@ bfa_fcxp_alloc(void *caller, struct bfa_s *bfa, int nreq_sgles,
if (nreq_sgles > BFI_SGE_INLINE) {
nreq_sgpg = BFA_SGPG_NPAGE(nreq_sgles);
- if (bfa_sgpg_malloc
- (bfa, &fcxp->req_sgpg_q, nreq_sgpg)
+ if (bfa_sgpg_malloc(bfa, &fcxp->req_sgpg_q, nreq_sgpg)
!= BFA_STATUS_OK) {
- /* bfa_sgpg_wait(bfa, &fcxp->req_sgpg_wqe,
- nreq_sgpg); */
/*
* TODO
*/
@@ -685,7 +677,7 @@ bfa_fcxp_send(struct bfa_fcxp_s *fcxp, struct bfa_rport_s *rport,
fcxp->send_cbarg = cbarg;
/**
- * If no room in CPE queue, wait for
+ * If no room in CPE queue, wait for space in request queue
*/
send_req = bfa_reqq_next(bfa, BFA_REQQ_FCXP);
if (!send_req) {
diff --git a/drivers/scsi/bfa/bfa_fwimg_priv.h b/drivers/scsi/bfa/bfa_fwimg_priv.h
index 1ec1355924d..d33e19e5439 100644
--- a/drivers/scsi/bfa/bfa_fwimg_priv.h
+++ b/drivers/scsi/bfa/bfa_fwimg_priv.h
@@ -21,11 +21,24 @@
#define BFI_FLASH_CHUNK_SZ 256 /* Flash chunk size */
#define BFI_FLASH_CHUNK_SZ_WORDS (BFI_FLASH_CHUNK_SZ/sizeof(u32))
-extern u32 *bfi_image_ct_get_chunk(u32 off);
-extern u32 bfi_image_ct_size;
-extern u32 *bfi_image_cb_get_chunk(u32 off);
-extern u32 bfi_image_cb_size;
-extern u32 *bfi_image_cb;
-extern u32 *bfi_image_ct;
+/**
+ * BFI FW image type
+ */
+enum {
+ BFI_IMAGE_CB_FC,
+ BFI_IMAGE_CT_FC,
+ BFI_IMAGE_CT_CNA,
+ BFI_IMAGE_MAX,
+};
+
+extern u32 *bfi_image_get_chunk(int type, uint32_t off);
+extern u32 bfi_image_get_size(int type);
+extern u32 bfi_image_ct_fc_size;
+extern u32 bfi_image_ct_cna_size;
+extern u32 bfi_image_cb_fc_size;
+extern u32 *bfi_image_ct_fc;
+extern u32 *bfi_image_ct_cna;
+extern u32 *bfi_image_cb_fc;
+
#endif /* __BFA_FWIMG_PRIV_H__ */
diff --git a/drivers/scsi/bfa/bfa_hw_cb.c b/drivers/scsi/bfa/bfa_hw_cb.c
index 871a4e28575..edfd729445c 100644
--- a/drivers/scsi/bfa/bfa_hw_cb.c
+++ b/drivers/scsi/bfa/bfa_hw_cb.c
@@ -152,4 +152,9 @@ bfa_hwcb_isr_mode_set(struct bfa_s *bfa, bfa_boolean_t msix)
bfa->iocfc.hwif.hw_rspq_ack = bfa_hwcb_rspq_ack_msix;
}
-
+void
+bfa_hwcb_msix_get_rme_range(struct bfa_s *bfa, u32 *start, u32 *end)
+{
+ *start = BFA_MSIX_RME_Q0;
+ *end = BFA_MSIX_RME_Q7;
+}
diff --git a/drivers/scsi/bfa/bfa_hw_ct.c b/drivers/scsi/bfa/bfa_hw_ct.c
index 76ceb9a4bf2..a357fb3066f 100644
--- a/drivers/scsi/bfa/bfa_hw_ct.c
+++ b/drivers/scsi/bfa/bfa_hw_ct.c
@@ -168,4 +168,9 @@ bfa_hwct_isr_mode_set(struct bfa_s *bfa, bfa_boolean_t msix)
bfa_ioc_isr_mode_set(&bfa->ioc, msix);
}
-
+void
+bfa_hwct_msix_get_rme_range(struct bfa_s *bfa, u32 *start, u32 *end)
+{
+ *start = BFA_MSIX_RME_Q0;
+ *end = BFA_MSIX_RME_Q3;
+}
diff --git a/drivers/scsi/bfa/bfa_intr.c b/drivers/scsi/bfa/bfa_intr.c
index 0eba3f930d5..493678889b2 100644
--- a/drivers/scsi/bfa/bfa_intr.c
+++ b/drivers/scsi/bfa/bfa_intr.c
@@ -134,6 +134,7 @@ bfa_isr_enable(struct bfa_s *bfa)
bfa_reg_write(bfa->iocfc.bfa_regs.intr_status, intr_unmask);
bfa_reg_write(bfa->iocfc.bfa_regs.intr_mask, ~intr_unmask);
+ bfa->iocfc.intr_mask = ~intr_unmask;
bfa_isr_mode_set(bfa, bfa->msix.nvecs != 0);
}
diff --git a/drivers/scsi/bfa/bfa_ioc.c b/drivers/scsi/bfa/bfa_ioc.c
index e038bc9769f..8e78f20110a 100644
--- a/drivers/scsi/bfa/bfa_ioc.c
+++ b/drivers/scsi/bfa/bfa_ioc.c
@@ -59,22 +59,18 @@ BFA_TRC_FILE(CNA, IOC);
((__ioc)->ioc_hwif->ioc_firmware_lock(__ioc))
#define bfa_ioc_firmware_unlock(__ioc) \
((__ioc)->ioc_hwif->ioc_firmware_unlock(__ioc))
-#define bfa_ioc_fwimg_get_chunk(__ioc, __off) \
- ((__ioc)->ioc_hwif->ioc_fwimg_get_chunk(__ioc, __off))
-#define bfa_ioc_fwimg_get_size(__ioc) \
- ((__ioc)->ioc_hwif->ioc_fwimg_get_size(__ioc))
#define bfa_ioc_reg_init(__ioc) ((__ioc)->ioc_hwif->ioc_reg_init(__ioc))
#define bfa_ioc_map_port(__ioc) ((__ioc)->ioc_hwif->ioc_map_port(__ioc))
#define bfa_ioc_notify_hbfail(__ioc) \
((__ioc)->ioc_hwif->ioc_notify_hbfail(__ioc))
+#define bfa_ioc_is_optrom(__ioc) \
+ (bfi_image_get_size(BFA_IOC_FWIMG_TYPE(__ioc)) < BFA_IOC_FWIMG_MINSZ)
bfa_boolean_t bfa_auto_recover = BFA_TRUE;
/*
* forward declarations
*/
-static void bfa_ioc_aen_post(struct bfa_ioc_s *bfa,
- enum bfa_ioc_aen_event event);
static void bfa_ioc_hw_sem_get(struct bfa_ioc_s *ioc);
static void bfa_ioc_hw_sem_get_cancel(struct bfa_ioc_s *ioc);
static void bfa_ioc_hwinit(struct bfa_ioc_s *ioc, bfa_boolean_t force);
@@ -88,6 +84,7 @@ static void bfa_ioc_reset(struct bfa_ioc_s *ioc, bfa_boolean_t force);
static void bfa_ioc_mbox_poll(struct bfa_ioc_s *ioc);
static void bfa_ioc_mbox_hbfail(struct bfa_ioc_s *ioc);
static void bfa_ioc_recover(struct bfa_ioc_s *ioc);
+static void bfa_ioc_check_attr_wwns(struct bfa_ioc_s *ioc);
static void bfa_ioc_disable_comp(struct bfa_ioc_s *ioc);
static void bfa_ioc_lpu_stop(struct bfa_ioc_s *ioc);
@@ -433,6 +430,7 @@ bfa_ioc_sm_getattr(struct bfa_ioc_s *ioc, enum ioc_event event)
switch (event) {
case IOC_E_FWRSP_GETATTR:
bfa_ioc_timer_stop(ioc);
+ bfa_ioc_check_attr_wwns(ioc);
bfa_fsm_set_state(ioc, bfa_ioc_sm_op);
break;
@@ -879,8 +877,8 @@ bfa_ioc_fwver_cmp(struct bfa_ioc_s *ioc, struct bfi_ioc_image_hdr_s *fwhdr)
struct bfi_ioc_image_hdr_s *drv_fwhdr;
int i;
- drv_fwhdr =
- (struct bfi_ioc_image_hdr_s *)bfa_ioc_fwimg_get_chunk(ioc, 0);
+ drv_fwhdr = (struct bfi_ioc_image_hdr_s *)
+ bfi_image_get_chunk(BFA_IOC_FWIMG_TYPE(ioc), 0);
for (i = 0; i < BFI_IOC_MD5SUM_SZ; i++) {
if (fwhdr->md5sum[i] != drv_fwhdr->md5sum[i]) {
@@ -907,12 +905,13 @@ bfa_ioc_fwver_valid(struct bfa_ioc_s *ioc)
/**
* If bios/efi boot (flash based) -- return true
*/
- if (bfa_ioc_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ)
+ if (bfa_ioc_is_optrom(ioc))
return BFA_TRUE;
bfa_ioc_fwver_get(ioc, &fwhdr);
- drv_fwhdr =
- (struct bfi_ioc_image_hdr_s *)bfa_ioc_fwimg_get_chunk(ioc, 0);
+ drv_fwhdr = (struct bfi_ioc_image_hdr_s *)
+ bfi_image_get_chunk(BFA_IOC_FWIMG_TYPE(ioc), 0);
+
if (fwhdr.signature != drv_fwhdr->signature) {
bfa_trc(ioc, fwhdr.signature);
@@ -980,8 +979,13 @@ bfa_ioc_hwinit(struct bfa_ioc_s *ioc, bfa_boolean_t force)
/**
* If IOC function is disabled and firmware version is same,
* just re-enable IOC.
+ *
+ * If option rom, IOC must not be in operational state. With
+ * convergence, IOC will be in operational state when 2nd driver
+ * is loaded.
*/
- if (ioc_fwstate == BFI_IOC_DISABLED || ioc_fwstate == BFI_IOC_OP) {
+ if (ioc_fwstate == BFI_IOC_DISABLED ||
+ (!bfa_ioc_is_optrom(ioc) && ioc_fwstate == BFI_IOC_OP)) {
bfa_trc(ioc, ioc_fwstate);
/**
@@ -1125,21 +1129,22 @@ bfa_ioc_download_fw(struct bfa_ioc_s *ioc, u32 boot_type,
/**
* Flash based firmware boot
*/
- bfa_trc(ioc, bfa_ioc_fwimg_get_size(ioc));
- if (bfa_ioc_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ)
+ bfa_trc(ioc, bfi_image_get_size(BFA_IOC_FWIMG_TYPE(ioc)));
+ if (bfa_ioc_is_optrom(ioc))
boot_type = BFI_BOOT_TYPE_FLASH;
- fwimg = bfa_ioc_fwimg_get_chunk(ioc, chunkno);
+ fwimg = bfi_image_get_chunk(BFA_IOC_FWIMG_TYPE(ioc), chunkno);
+
pgnum = bfa_ioc_smem_pgnum(ioc, loff);
pgoff = bfa_ioc_smem_pgoff(ioc, loff);
bfa_reg_write(ioc->ioc_regs.host_page_num_fn, pgnum);
- for (i = 0; i < bfa_ioc_fwimg_get_size(ioc); i++) {
+ for (i = 0; i < bfi_image_get_size(BFA_IOC_FWIMG_TYPE(ioc)); i++) {
if (BFA_IOC_FLASH_CHUNK_NO(i) != chunkno) {
chunkno = BFA_IOC_FLASH_CHUNK_NO(i);
- fwimg = bfa_ioc_fwimg_get_chunk(ioc,
+ fwimg = bfi_image_get_chunk(BFA_IOC_FWIMG_TYPE(ioc),
BFA_IOC_FLASH_CHUNK_ADDR(chunkno));
}
@@ -1188,6 +1193,7 @@ bfa_ioc_getattr_reply(struct bfa_ioc_s *ioc)
struct bfi_ioc_attr_s *attr = ioc->attr;
attr->adapter_prop = bfa_os_ntohl(attr->adapter_prop);
+ attr->card_type = bfa_os_ntohl(attr->card_type);
attr->maxfrsize = bfa_os_ntohs(attr->maxfrsize);
bfa_fsm_send_event(ioc, IOC_E_FWRSP_GETATTR);
@@ -1282,6 +1288,7 @@ bfa_ioc_boot(struct bfa_ioc_s *ioc, u32 boot_type, u32 boot_param)
bfa_reg_write((rb + BFA_IOC1_STATE_REG), BFI_IOC_INITING);
}
+ bfa_ioc_msgflush(ioc);
bfa_ioc_download_fw(ioc, boot_type, boot_param);
/**
@@ -1416,7 +1423,7 @@ bfa_ioc_pci_init(struct bfa_ioc_s *ioc, struct bfa_pcidev_s *pcidev,
{
ioc->ioc_mc = mc;
ioc->pcidev = *pcidev;
- ioc->ctdev = (ioc->pcidev.device_id == BFA_PCI_DEVICE_ID_CT);
+ ioc->ctdev = bfa_asic_id_ct(ioc->pcidev.device_id);
ioc->cna = ioc->ctdev && !ioc->fcmode;
/**
@@ -1607,6 +1614,13 @@ bfa_ioc_error_isr(struct bfa_ioc_s *ioc)
bfa_fsm_send_event(ioc, IOC_E_HWERROR);
}
+void
+bfa_ioc_set_fcmode(struct bfa_ioc_s *ioc)
+{
+ ioc->fcmode = BFA_TRUE;
+ ioc->port_id = bfa_ioc_pcifn(ioc);
+}
+
#ifndef BFA_BIOS_BUILD
/**
@@ -1696,6 +1710,9 @@ bfa_ioc_get_adapter_attr(struct bfa_ioc_s *ioc,
/* For now, model descr uses same model string */
bfa_ioc_get_adapter_model(ioc, ad_attr->model_descr);
+ ad_attr->card_type = ioc_attr->card_type;
+ ad_attr->is_mezz = bfa_mfg_is_mezz(ioc_attr->card_type);
+
if (BFI_ADAPTER_IS_SPECIAL(ioc_attr->adapter_prop))
ad_attr->prototype = 1;
else
@@ -1779,28 +1796,17 @@ void
bfa_ioc_get_adapter_model(struct bfa_ioc_s *ioc, char *model)
{
struct bfi_ioc_attr_s *ioc_attr;
- u8 nports;
- u8 max_speed;
bfa_assert(model);
bfa_os_memset((void *)model, 0, BFA_ADAPTER_MODEL_NAME_LEN);
ioc_attr = ioc->attr;
- nports = bfa_ioc_get_nports(ioc);
- max_speed = bfa_ioc_speed_sup(ioc);
-
/**
* model name
*/
- if (max_speed == 10) {
- strcpy(model, "BR-10?0");
- model[5] = '0' + nports;
- } else {
- strcpy(model, "Brocade-??5");
- model[8] = '0' + max_speed;
- model[9] = '0' + nports;
- }
+ snprintf(model, BFA_ADAPTER_MODEL_NAME_LEN, "%s-%u",
+ BFA_MFG_NAME, ioc_attr->card_type);
}
enum bfa_ioc_state
@@ -1827,78 +1833,54 @@ bfa_ioc_get_attr(struct bfa_ioc_s *ioc, struct bfa_ioc_attr_s *ioc_attr)
}
/**
- * hal_wwn_public
+ * bfa_wwn_public
*/
wwn_t
bfa_ioc_get_pwwn(struct bfa_ioc_s *ioc)
{
- union {
- wwn_t wwn;
- u8 byte[sizeof(wwn_t)];
- }
- w;
-
- w.wwn = ioc->attr->mfg_wwn;
-
- if (bfa_ioc_portid(ioc) == 1)
- w.byte[7]++;
-
- return w.wwn;
+ return ioc->attr->pwwn;
}
wwn_t
bfa_ioc_get_nwwn(struct bfa_ioc_s *ioc)
{
- union {
- wwn_t wwn;
- u8 byte[sizeof(wwn_t)];
- }
- w;
-
- w.wwn = ioc->attr->mfg_wwn;
-
- if (bfa_ioc_portid(ioc) == 1)
- w.byte[7]++;
+ return ioc->attr->nwwn;
+}
- w.byte[0] = 0x20;
+u64
+bfa_ioc_get_adid(struct bfa_ioc_s *ioc)
+{
+ return ioc->attr->mfg_pwwn;
+}
- return w.wwn;
+mac_t
+bfa_ioc_get_mac(struct bfa_ioc_s *ioc)
+{
+ /*
+ * Currently mfg mac is used as FCoE enode mac (not configured by PBC)
+ */
+ if (bfa_ioc_get_type(ioc) == BFA_IOC_TYPE_FCoE)
+ return bfa_ioc_get_mfg_mac(ioc);
+ else
+ return ioc->attr->mac;
}
wwn_t
-bfa_ioc_get_wwn_naa5(struct bfa_ioc_s *ioc, u16 inst)
+bfa_ioc_get_mfg_pwwn(struct bfa_ioc_s *ioc)
{
- union {
- wwn_t wwn;
- u8 byte[sizeof(wwn_t)];
- }
- w , w5;
-
- bfa_trc(ioc, inst);
-
- w.wwn = ioc->attr->mfg_wwn;
- w5.byte[0] = 0x50 | w.byte[2] >> 4;
- w5.byte[1] = w.byte[2] << 4 | w.byte[3] >> 4;
- w5.byte[2] = w.byte[3] << 4 | w.byte[4] >> 4;
- w5.byte[3] = w.byte[4] << 4 | w.byte[5] >> 4;
- w5.byte[4] = w.byte[5] << 4 | w.byte[6] >> 4;
- w5.byte[5] = w.byte[6] << 4 | w.byte[7] >> 4;
- w5.byte[6] = w.byte[7] << 4 | (inst & 0x0f00) >> 8;
- w5.byte[7] = (inst & 0xff);
-
- return w5.wwn;
+ return ioc->attr->mfg_pwwn;
}
-u64
-bfa_ioc_get_adid(struct bfa_ioc_s *ioc)
+wwn_t
+bfa_ioc_get_mfg_nwwn(struct bfa_ioc_s *ioc)
{
- return ioc->attr->mfg_wwn;
+ return ioc->attr->mfg_nwwn;
}
mac_t
-bfa_ioc_get_mac(struct bfa_ioc_s *ioc)
+bfa_ioc_get_mfg_mac(struct bfa_ioc_s *ioc)
{
- mac_t mac;
+ mac_t mac;
mac = ioc->attr->mfg_mac;
mac.mac[MAC_ADDRLEN - 1] += bfa_ioc_pcifn(ioc);
@@ -1906,23 +1888,16 @@ bfa_ioc_get_mac(struct bfa_ioc_s *ioc)
return mac;
}
-void
-bfa_ioc_set_fcmode(struct bfa_ioc_s *ioc)
-{
- ioc->fcmode = BFA_TRUE;
- ioc->port_id = bfa_ioc_pcifn(ioc);
-}
-
bfa_boolean_t
bfa_ioc_get_fcmode(struct bfa_ioc_s *ioc)
{
- return ioc->fcmode || (ioc->pcidev.device_id != BFA_PCI_DEVICE_ID_CT);
+ return ioc->fcmode || !bfa_asic_id_ct(ioc->pcidev.device_id);
}
/**
* Send AEN notification
*/
-static void
+void
bfa_ioc_aen_post(struct bfa_ioc_s *ioc, enum bfa_ioc_aen_event event)
{
union bfa_aen_data_u aen_data;
@@ -2070,19 +2045,16 @@ bfa_ioc_recover(struct bfa_ioc_s *ioc)
bfa_fsm_send_event(ioc, IOC_E_HBFAIL);
}
-#else
-
static void
-bfa_ioc_aen_post(struct bfa_ioc_s *ioc, enum bfa_ioc_aen_event event)
+bfa_ioc_check_attr_wwns(struct bfa_ioc_s *ioc)
{
-}
+ if (bfa_ioc_get_type(ioc) == BFA_IOC_TYPE_LL)
+ return;
-static void
-bfa_ioc_recover(struct bfa_ioc_s *ioc)
-{
- bfa_assert(0);
+ if (ioc->attr->nwwn == 0)
+ bfa_ioc_aen_post(ioc, BFA_IOC_AEN_INVALID_NWWN);
+ if (ioc->attr->pwwn == 0)
+ bfa_ioc_aen_post(ioc, BFA_IOC_AEN_INVALID_PWWN);
}
#endif
-
-
diff --git a/drivers/scsi/bfa/bfa_ioc.h b/drivers/scsi/bfa/bfa_ioc.h
index d0804406ea1..cae05b251c9 100644
--- a/drivers/scsi/bfa/bfa_ioc.h
+++ b/drivers/scsi/bfa/bfa_ioc.h
@@ -186,9 +186,6 @@ struct bfa_ioc_hwif_s {
bfa_status_t (*ioc_pll_init) (struct bfa_ioc_s *ioc);
bfa_boolean_t (*ioc_firmware_lock) (struct bfa_ioc_s *ioc);
void (*ioc_firmware_unlock) (struct bfa_ioc_s *ioc);
- u32 * (*ioc_fwimg_get_chunk) (struct bfa_ioc_s *ioc,
- u32 off);
- u32 (*ioc_fwimg_get_size) (struct bfa_ioc_s *ioc);
void (*ioc_reg_init) (struct bfa_ioc_s *ioc);
void (*ioc_map_port) (struct bfa_ioc_s *ioc);
void (*ioc_isr_mode_set) (struct bfa_ioc_s *ioc,
@@ -214,6 +211,10 @@ struct bfa_ioc_hwif_s {
#define bfa_ioc_stats(_ioc, _stats) ((_ioc)->stats._stats++)
#define BFA_IOC_FWIMG_MINSZ (16 * 1024)
+#define BFA_IOC_FWIMG_TYPE(__ioc) \
+ (((__ioc)->ctdev) ? \
+ (((__ioc)->fcmode) ? BFI_IMAGE_CT_FC : BFI_IMAGE_CT_CNA) : \
+ BFI_IMAGE_CB_FC)
#define BFA_IOC_FLASH_CHUNK_NO(off) (off / BFI_FLASH_CHUNK_SZ_WORDS)
#define BFA_IOC_FLASH_OFFSET_IN_CHUNK(off) (off % BFI_FLASH_CHUNK_SZ_WORDS)
@@ -296,14 +297,17 @@ void bfa_ioc_fwver_get(struct bfa_ioc_s *ioc,
struct bfi_ioc_image_hdr_s *fwhdr);
bfa_boolean_t bfa_ioc_fwver_cmp(struct bfa_ioc_s *ioc,
struct bfi_ioc_image_hdr_s *fwhdr);
+void bfa_ioc_aen_post(struct bfa_ioc_s *ioc, enum bfa_ioc_aen_event event);
/*
* bfa mfg wwn API functions
*/
wwn_t bfa_ioc_get_pwwn(struct bfa_ioc_s *ioc);
wwn_t bfa_ioc_get_nwwn(struct bfa_ioc_s *ioc);
-wwn_t bfa_ioc_get_wwn_naa5(struct bfa_ioc_s *ioc, u16 inst);
mac_t bfa_ioc_get_mac(struct bfa_ioc_s *ioc);
+wwn_t bfa_ioc_get_mfg_pwwn(struct bfa_ioc_s *ioc);
+wwn_t bfa_ioc_get_mfg_nwwn(struct bfa_ioc_s *ioc);
+mac_t bfa_ioc_get_mfg_mac(struct bfa_ioc_s *ioc);
u64 bfa_ioc_get_adid(struct bfa_ioc_s *ioc);
#endif /* __BFA_IOC_H__ */
diff --git a/drivers/scsi/bfa/bfa_ioc_cb.c b/drivers/scsi/bfa/bfa_ioc_cb.c
index 3ce85319f73..324bdde7ea2 100644
--- a/drivers/scsi/bfa/bfa_ioc_cb.c
+++ b/drivers/scsi/bfa/bfa_ioc_cb.c
@@ -33,26 +33,13 @@ BFA_TRC_FILE(CNA, IOC_CB);
static bfa_status_t bfa_ioc_cb_pll_init(struct bfa_ioc_s *ioc);
static bfa_boolean_t bfa_ioc_cb_firmware_lock(struct bfa_ioc_s *ioc);
static void bfa_ioc_cb_firmware_unlock(struct bfa_ioc_s *ioc);
-static u32 *bfa_ioc_cb_fwimg_get_chunk(struct bfa_ioc_s *ioc, u32 off);
-static u32 bfa_ioc_cb_fwimg_get_size(struct bfa_ioc_s *ioc);
static void bfa_ioc_cb_reg_init(struct bfa_ioc_s *ioc);
static void bfa_ioc_cb_map_port(struct bfa_ioc_s *ioc);
static void bfa_ioc_cb_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix);
static void bfa_ioc_cb_notify_hbfail(struct bfa_ioc_s *ioc);
static void bfa_ioc_cb_ownership_reset(struct bfa_ioc_s *ioc);
-struct bfa_ioc_hwif_s hwif_cb = {
- bfa_ioc_cb_pll_init,
- bfa_ioc_cb_firmware_lock,
- bfa_ioc_cb_firmware_unlock,
- bfa_ioc_cb_fwimg_get_chunk,
- bfa_ioc_cb_fwimg_get_size,
- bfa_ioc_cb_reg_init,
- bfa_ioc_cb_map_port,
- bfa_ioc_cb_isr_mode_set,
- bfa_ioc_cb_notify_hbfail,
- bfa_ioc_cb_ownership_reset,
-};
+struct bfa_ioc_hwif_s hwif_cb;
/**
* Called from bfa_ioc_attach() to map asic specific calls.
@@ -60,19 +47,16 @@ struct bfa_ioc_hwif_s hwif_cb = {
void
bfa_ioc_set_cb_hwif(struct bfa_ioc_s *ioc)
{
- ioc->ioc_hwif = &hwif_cb;
-}
-
-static u32 *
-bfa_ioc_cb_fwimg_get_chunk(struct bfa_ioc_s *ioc, u32 off)
-{
- return bfi_image_cb_get_chunk(off);
-}
+ hwif_cb.ioc_pll_init = bfa_ioc_cb_pll_init;
+ hwif_cb.ioc_firmware_lock = bfa_ioc_cb_firmware_lock;
+ hwif_cb.ioc_firmware_unlock = bfa_ioc_cb_firmware_unlock;
+ hwif_cb.ioc_reg_init = bfa_ioc_cb_reg_init;
+ hwif_cb.ioc_map_port = bfa_ioc_cb_map_port;
+ hwif_cb.ioc_isr_mode_set = bfa_ioc_cb_isr_mode_set;
+ hwif_cb.ioc_notify_hbfail = bfa_ioc_cb_notify_hbfail;
+ hwif_cb.ioc_ownership_reset = bfa_ioc_cb_ownership_reset;
-static u32
-bfa_ioc_cb_fwimg_get_size(struct bfa_ioc_s *ioc)
-{
- return bfi_image_cb_size;
+ ioc->ioc_hwif = &hwif_cb;
}
/**
diff --git a/drivers/scsi/bfa/bfa_ioc_ct.c b/drivers/scsi/bfa/bfa_ioc_ct.c
index 20b58ad5f95..68f027da001 100644
--- a/drivers/scsi/bfa/bfa_ioc_ct.c
+++ b/drivers/scsi/bfa/bfa_ioc_ct.c
@@ -33,27 +33,13 @@ BFA_TRC_FILE(CNA, IOC_CT);
static bfa_status_t bfa_ioc_ct_pll_init(struct bfa_ioc_s *ioc);
static bfa_boolean_t bfa_ioc_ct_firmware_lock(struct bfa_ioc_s *ioc);
static void bfa_ioc_ct_firmware_unlock(struct bfa_ioc_s *ioc);
-static u32* bfa_ioc_ct_fwimg_get_chunk(struct bfa_ioc_s *ioc,
- u32 off);
-static u32 bfa_ioc_ct_fwimg_get_size(struct bfa_ioc_s *ioc);
static void bfa_ioc_ct_reg_init(struct bfa_ioc_s *ioc);
static void bfa_ioc_ct_map_port(struct bfa_ioc_s *ioc);
static void bfa_ioc_ct_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix);
static void bfa_ioc_ct_notify_hbfail(struct bfa_ioc_s *ioc);
static void bfa_ioc_ct_ownership_reset(struct bfa_ioc_s *ioc);
-struct bfa_ioc_hwif_s hwif_ct = {
- bfa_ioc_ct_pll_init,
- bfa_ioc_ct_firmware_lock,
- bfa_ioc_ct_firmware_unlock,
- bfa_ioc_ct_fwimg_get_chunk,
- bfa_ioc_ct_fwimg_get_size,
- bfa_ioc_ct_reg_init,
- bfa_ioc_ct_map_port,
- bfa_ioc_ct_isr_mode_set,
- bfa_ioc_ct_notify_hbfail,
- bfa_ioc_ct_ownership_reset,
-};
+struct bfa_ioc_hwif_s hwif_ct;
/**
* Called from bfa_ioc_attach() to map asic specific calls.
@@ -61,19 +47,16 @@ struct bfa_ioc_hwif_s hwif_ct = {
void
bfa_ioc_set_ct_hwif(struct bfa_ioc_s *ioc)
{
- ioc->ioc_hwif = &hwif_ct;
-}
+ hwif_ct.ioc_pll_init = bfa_ioc_ct_pll_init;
+ hwif_ct.ioc_firmware_lock = bfa_ioc_ct_firmware_lock;
+ hwif_ct.ioc_firmware_unlock = bfa_ioc_ct_firmware_unlock;
+ hwif_ct.ioc_reg_init = bfa_ioc_ct_reg_init;
+ hwif_ct.ioc_map_port = bfa_ioc_ct_map_port;
+ hwif_ct.ioc_isr_mode_set = bfa_ioc_ct_isr_mode_set;
+ hwif_ct.ioc_notify_hbfail = bfa_ioc_ct_notify_hbfail;
+ hwif_ct.ioc_ownership_reset = bfa_ioc_ct_ownership_reset;
-static u32*
-bfa_ioc_ct_fwimg_get_chunk(struct bfa_ioc_s *ioc, u32 off)
-{
- return bfi_image_ct_get_chunk(off);
-}
-
-static u32
-bfa_ioc_ct_fwimg_get_size(struct bfa_ioc_s *ioc)
-{
- return bfi_image_ct_size;
+ ioc->ioc_hwif = &hwif_ct;
}
/**
@@ -95,7 +78,7 @@ bfa_ioc_ct_firmware_lock(struct bfa_ioc_s *ioc)
/**
* If bios boot (flash based) -- do not increment usage count
*/
- if (bfa_ioc_ct_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ)
+ if (bfi_image_get_size(BFA_IOC_FWIMG_TYPE(ioc)) < BFA_IOC_FWIMG_MINSZ)
return BFA_TRUE;
bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg);
@@ -146,9 +129,14 @@ bfa_ioc_ct_firmware_unlock(struct bfa_ioc_s *ioc)
/**
* Firmware lock is relevant only for CNA.
+ */
+ if (!ioc->cna)
+ return;
+
+ /**
* If bios boot (flash based) -- do not decrement usage count
*/
- if (!ioc->cna || bfa_ioc_ct_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ)
+ if (bfi_image_get_size(BFA_IOC_FWIMG_TYPE(ioc)) < BFA_IOC_FWIMG_MINSZ)
return;
/**
@@ -388,10 +376,35 @@ bfa_ioc_ct_pll_init(struct bfa_ioc_s *ioc)
bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, pll_fclk |
__APP_PLL_425_ENABLE);
+ /**
+ * PSS memory reset is asserted at power-on-reset. Need to clear
+ * this before running EDRAM BISTR
+ */
+ if (ioc->cna) {
+ bfa_reg_write((rb + PMM_1T_RESET_REG_P0), __PMM_1T_RESET_P);
+ bfa_reg_write((rb + PMM_1T_RESET_REG_P1), __PMM_1T_RESET_P);
+ }
+
+ r32 = bfa_reg_read((rb + PSS_CTL_REG));
+ r32 &= ~__PSS_LMEM_RESET;
+ bfa_reg_write((rb + PSS_CTL_REG), r32);
+ bfa_os_udelay(1000);
+
+ if (ioc->cna) {
+ bfa_reg_write((rb + PMM_1T_RESET_REG_P0), 0);
+ bfa_reg_write((rb + PMM_1T_RESET_REG_P1), 0);
+ }
+
bfa_reg_write((rb + MBIST_CTL_REG), __EDRAM_BISTR_START);
bfa_os_udelay(1000);
r32 = bfa_reg_read((rb + MBIST_STAT_REG));
bfa_trc(ioc, r32);
+
+ /**
+ * Clear BISTR
+ */
+ bfa_reg_write((rb + MBIST_CTL_REG), 0);
+
/*
* release semaphore.
*/
diff --git a/drivers/scsi/bfa/bfa_iocfc.c b/drivers/scsi/bfa/bfa_iocfc.c
index a76de2669bf..90820be9986 100644
--- a/drivers/scsi/bfa/bfa_iocfc.c
+++ b/drivers/scsi/bfa/bfa_iocfc.c
@@ -113,7 +113,6 @@ bfa_iocfc_send_cfg(void *bfa_arg)
bfa_assert(cfg->fwcfg.num_cqs <= BFI_IOC_MAX_CQS);
bfa_trc(bfa, cfg->fwcfg.num_cqs);
- iocfc->cfgdone = BFA_FALSE;
bfa_iocfc_reset_queues(bfa);
/**
@@ -145,6 +144,15 @@ bfa_iocfc_send_cfg(void *bfa_arg)
}
/**
+ * Enable interrupt coalescing if it is driver init path
+ * and not ioc disable/enable path.
+ */
+ if (!iocfc->cfgdone)
+ cfg_info->intr_attr.coalesce = BFA_TRUE;
+
+ iocfc->cfgdone = BFA_FALSE;
+
+ /**
* dma map IOC configuration itself
*/
bfi_h2i_set(cfg_req.mh, BFI_MC_IOCFC, BFI_IOCFC_H2I_CFG_REQ,
@@ -170,7 +178,7 @@ bfa_iocfc_init_mem(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
/**
* Initialize chip specific handlers.
*/
- if (bfa_ioc_devid(&bfa->ioc) == BFA_PCI_DEVICE_ID_CT) {
+ if (bfa_asic_id_ct(bfa_ioc_devid(&bfa->ioc))) {
iocfc->hwif.hw_reginit = bfa_hwct_reginit;
iocfc->hwif.hw_reqq_ack = bfa_hwct_reqq_ack;
iocfc->hwif.hw_rspq_ack = bfa_hwct_rspq_ack;
@@ -179,6 +187,7 @@ bfa_iocfc_init_mem(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
iocfc->hwif.hw_msix_uninstall = bfa_hwct_msix_uninstall;
iocfc->hwif.hw_isr_mode_set = bfa_hwct_isr_mode_set;
iocfc->hwif.hw_msix_getvecs = bfa_hwct_msix_getvecs;
+ iocfc->hwif.hw_msix_get_rme_range = bfa_hwct_msix_get_rme_range;
} else {
iocfc->hwif.hw_reginit = bfa_hwcb_reginit;
iocfc->hwif.hw_reqq_ack = bfa_hwcb_reqq_ack;
@@ -188,6 +197,7 @@ bfa_iocfc_init_mem(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
iocfc->hwif.hw_msix_uninstall = bfa_hwcb_msix_uninstall;
iocfc->hwif.hw_isr_mode_set = bfa_hwcb_isr_mode_set;
iocfc->hwif.hw_msix_getvecs = bfa_hwcb_msix_getvecs;
+ iocfc->hwif.hw_msix_get_rme_range = bfa_hwcb_msix_get_rme_range;
}
iocfc->hwif.hw_reginit(bfa);
@@ -291,18 +301,6 @@ bfa_iocfc_mem_claim(struct bfa_s *bfa, struct bfa_iocfc_cfg_s *cfg,
}
/**
- * BFA submodules initialization completion notification.
- */
-static void
-bfa_iocfc_initdone_submod(struct bfa_s *bfa)
-{
- int i;
-
- for (i = 0; hal_mods[i]; i++)
- hal_mods[i]->initdone(bfa);
-}
-
-/**
* Start BFA submodules.
*/
static void
@@ -376,7 +374,6 @@ bfa_iocfc_cfgrsp(struct bfa_s *bfa)
struct bfa_iocfc_s *iocfc = &bfa->iocfc;
struct bfi_iocfc_cfgrsp_s *cfgrsp = iocfc->cfgrsp;
struct bfa_iocfc_fwcfg_s *fwcfg = &cfgrsp->fwcfg;
- struct bfi_iocfc_cfg_s *cfginfo = iocfc->cfginfo;
fwcfg->num_cqs = fwcfg->num_cqs;
fwcfg->num_ioim_reqs = bfa_os_ntohs(fwcfg->num_ioim_reqs);
@@ -385,15 +382,13 @@ bfa_iocfc_cfgrsp(struct bfa_s *bfa)
fwcfg->num_uf_bufs = bfa_os_ntohs(fwcfg->num_uf_bufs);
fwcfg->num_rports = bfa_os_ntohs(fwcfg->num_rports);
- cfginfo->intr_attr.coalesce = cfgrsp->intr_attr.coalesce;
- cfginfo->intr_attr.delay = bfa_os_ntohs(cfgrsp->intr_attr.delay);
- cfginfo->intr_attr.latency = bfa_os_ntohs(cfgrsp->intr_attr.latency);
-
iocfc->cfgdone = BFA_TRUE;
/**
* Configuration is complete - initialize/start submodules
*/
+ bfa_fcport_init(bfa);
+
if (iocfc->action == BFA_IOCFC_ACT_INIT)
bfa_cb_queue(bfa, &iocfc->init_hcb_qe, bfa_iocfc_init_cb, bfa);
else
@@ -531,7 +526,6 @@ bfa_iocfc_enable_cbfn(void *bfa_arg, enum bfa_status status)
return;
}
- bfa_iocfc_initdone_submod(bfa);
bfa_iocfc_send_cfg(bfa);
}
@@ -625,9 +619,9 @@ bfa_iocfc_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
bfa->trcmod, bfa->aen, bfa->logm);
/**
- * Choose FC (ssid: 0x1C) v/s FCoE (ssid: 0x14) mode.
+ * Set FC mode for BFA_PCI_DEVICE_ID_CT_FC.
*/
- if (0)
+ if (pcidev->device_id == BFA_PCI_DEVICE_ID_CT_FC)
bfa_ioc_set_fcmode(&bfa->ioc);
bfa_ioc_pci_init(&bfa->ioc, pcidev, BFI_MC_IOCFC);
@@ -748,10 +742,20 @@ bfa_adapter_get_id(struct bfa_s *bfa)
void
bfa_iocfc_get_attr(struct bfa_s *bfa, struct bfa_iocfc_attr_s *attr)
{
- struct bfa_iocfc_s *iocfc = &bfa->iocfc;
+ struct bfa_iocfc_s *iocfc = &bfa->iocfc;
+
+ attr->intr_attr.coalesce = iocfc->cfginfo->intr_attr.coalesce;
+
+ attr->intr_attr.delay = iocfc->cfginfo->intr_attr.delay ?
+ bfa_os_ntohs(iocfc->cfginfo->intr_attr.delay) :
+ bfa_os_ntohs(iocfc->cfgrsp->intr_attr.delay);
+
+ attr->intr_attr.latency = iocfc->cfginfo->intr_attr.latency ?
+ bfa_os_ntohs(iocfc->cfginfo->intr_attr.latency) :
+ bfa_os_ntohs(iocfc->cfgrsp->intr_attr.latency);
+
+ attr->config = iocfc->cfg;
- attr->intr_attr = iocfc->cfginfo->intr_attr;
- attr->config = iocfc->cfg;
}
bfa_status_t
@@ -760,7 +764,10 @@ bfa_iocfc_israttr_set(struct bfa_s *bfa, struct bfa_iocfc_intr_attr_s *attr)
struct bfa_iocfc_s *iocfc = &bfa->iocfc;
struct bfi_iocfc_set_intr_req_s *m;
- iocfc->cfginfo->intr_attr = *attr;
+ iocfc->cfginfo->intr_attr.coalesce = attr->coalesce;
+ iocfc->cfginfo->intr_attr.delay = bfa_os_htons(attr->delay);
+ iocfc->cfginfo->intr_attr.latency = bfa_os_htons(attr->latency);
+
if (!bfa_iocfc_is_operational(bfa))
return BFA_STATUS_OK;
@@ -770,9 +777,10 @@ bfa_iocfc_israttr_set(struct bfa_s *bfa, struct bfa_iocfc_intr_attr_s *attr)
bfi_h2i_set(m->mh, BFI_MC_IOCFC, BFI_IOCFC_H2I_SET_INTR_REQ,
bfa_lpuid(bfa));
- m->coalesce = attr->coalesce;
- m->delay = bfa_os_htons(attr->delay);
- m->latency = bfa_os_htons(attr->latency);
+ m->coalesce = iocfc->cfginfo->intr_attr.coalesce;
+ m->delay = iocfc->cfginfo->intr_attr.delay;
+ m->latency = iocfc->cfginfo->intr_attr.latency;
+
bfa_trc(bfa, attr->delay);
bfa_trc(bfa, attr->latency);
@@ -872,15 +880,48 @@ bfa_iocfc_is_operational(struct bfa_s *bfa)
* Return boot target port wwns -- read from boot information in flash.
*/
void
-bfa_iocfc_get_bootwwns(struct bfa_s *bfa, u8 *nwwns, wwn_t **wwns)
+bfa_iocfc_get_bootwwns(struct bfa_s *bfa, u8 *nwwns, wwn_t *wwns)
{
- struct bfa_iocfc_s *iocfc = &bfa->iocfc;
- struct bfi_iocfc_cfgrsp_s *cfgrsp = iocfc->cfgrsp;
+ struct bfa_iocfc_s *iocfc = &bfa->iocfc;
+ struct bfi_iocfc_cfgrsp_s *cfgrsp = iocfc->cfgrsp;
+ int i;
+
+ if (cfgrsp->pbc_cfg.boot_enabled && cfgrsp->pbc_cfg.nbluns) {
+ bfa_trc(bfa, cfgrsp->pbc_cfg.nbluns);
+ *nwwns = cfgrsp->pbc_cfg.nbluns;
+ for (i = 0; i < cfgrsp->pbc_cfg.nbluns; i++)
+ wwns[i] = cfgrsp->pbc_cfg.blun[i].tgt_pwwn;
+
+ return;
+ }
*nwwns = cfgrsp->bootwwns.nwwns;
- *wwns = cfgrsp->bootwwns.wwn;
+ memcpy(wwns, cfgrsp->bootwwns.wwn, sizeof(cfgrsp->bootwwns.wwn));
+}
+
+void
+bfa_iocfc_get_pbc_boot_cfg(struct bfa_s *bfa, struct bfa_boot_pbc_s *pbcfg)
+{
+ struct bfa_iocfc_s *iocfc = &bfa->iocfc;
+ struct bfi_iocfc_cfgrsp_s *cfgrsp = iocfc->cfgrsp;
+
+ pbcfg->enable = cfgrsp->pbc_cfg.boot_enabled;
+ pbcfg->nbluns = cfgrsp->pbc_cfg.nbluns;
+ pbcfg->speed = cfgrsp->pbc_cfg.port_speed;
+ memcpy(pbcfg->pblun, cfgrsp->pbc_cfg.blun, sizeof(pbcfg->pblun));
}
+int
+bfa_iocfc_get_pbc_vports(struct bfa_s *bfa, struct bfi_pbc_vport_s *pbc_vport)
+{
+ struct bfa_iocfc_s *iocfc = &bfa->iocfc;
+ struct bfi_iocfc_cfgrsp_s *cfgrsp = iocfc->cfgrsp;
+
+ memcpy(pbc_vport, cfgrsp->pbc_cfg.vport, sizeof(cfgrsp->pbc_cfg.vport));
+ return cfgrsp->pbc_cfg.nvports;
+}
+
+
#endif
diff --git a/drivers/scsi/bfa/bfa_iocfc.h b/drivers/scsi/bfa/bfa_iocfc.h
index fbb4bdc9d60..74a6a048d1f 100644
--- a/drivers/scsi/bfa/bfa_iocfc.h
+++ b/drivers/scsi/bfa/bfa_iocfc.h
@@ -21,6 +21,7 @@
#include <bfa_ioc.h>
#include <bfa.h>
#include <bfi/bfi_iocfc.h>
+#include <bfi/bfi_pbc.h>
#include <bfa_callback_priv.h>
#define BFA_REQQ_NELEMS_MIN (4)
@@ -62,6 +63,8 @@ struct bfa_hwif_s {
void (*hw_isr_mode_set)(struct bfa_s *bfa, bfa_boolean_t msix);
void (*hw_msix_getvecs)(struct bfa_s *bfa, u32 *vecmap,
u32 *nvecs, u32 *maxvec);
+ void (*hw_msix_get_rme_range) (struct bfa_s *bfa, u32 *start,
+ u32 *end);
};
typedef void (*bfa_cb_iocfc_t) (void *cbarg, enum bfa_status status);
@@ -103,7 +106,8 @@ struct bfa_iocfc_s {
struct bfa_hwif_s hwif;
bfa_cb_iocfc_t updateq_cbfn; /* bios callback function */
- void *updateq_cbarg; /* bios callback arg */
+ void *updateq_cbarg; /* bios callback arg */
+ u32 intr_mask;
};
#define bfa_lpuid(__bfa) bfa_ioc_portid(&(__bfa)->ioc)