···66 Copyright (c) 2000-2005 LSI Logic Corporation.7788 ---------------------------------------99- Header Set Release Version: 01.05.101010- Header Set Release Date: 03-11-0599+ Header Set Release Version: 01.05.121010+ Header Set Release Date: 08-30-051111 ---------------------------------------12121313 Filename Current version Prior version1414 ---------- --------------- -------------1515- mpi.h 01.05.08 01.05.071616- mpi_ioc.h 01.05.09 01.05.081717- mpi_cnfg.h 01.05.09 01.05.081818- mpi_init.h 01.05.05 01.05.041919- mpi_targ.h 01.05.05 01.05.041515+ mpi.h 01.05.10 01.05.091616+ mpi_ioc.h 01.05.10 01.05.091717+ mpi_cnfg.h 01.05.11 01.05.101818+ mpi_init.h 01.05.06 01.05.061919+ mpi_targ.h 01.05.05 01.05.052020 mpi_fc.h 01.05.01 01.05.012121 mpi_lan.h 01.05.01 01.05.012222 mpi_raid.h 01.05.02 01.05.022323 mpi_tool.h 01.05.03 01.05.032424 mpi_inb.h 01.05.01 01.05.012525- mpi_sas.h 01.05.01 01.05.012626- mpi_type.h 01.05.01 01.05.012727- mpi_history.txt 01.05.09 01.05.092525+ mpi_sas.h 01.05.02 01.05.012626+ mpi_type.h 01.05.02 01.05.012727+ mpi_history.txt 01.05.12 01.05.11282829293030 * Date Version Description···9191 * 06-24-05 01.05.08 Added function codes for SCSI IO 32 and9292 * TargetAssistExtended requests.9393 * Added EEDP IOCStatus codes.9494+ * 08-03-05 01.05.09 Bumped MPI_HEADER_VERSION_UNIT.9595+ * 08-30-05 01.05.10 Added 2 new IOCStatus codes for Target.9496 * --------------------------------------------------------------------------95979698mpi_ioc.h···166164 * Removed IOCFacts Reply EEDP Capability bit.167165 * 06-24-05 01.05.09 Added 5 new IOCFacts Reply IOCCapabilities bits.168166 * Added Max SATA Targets to SAS Discovery Error event.167167+ * 08-30-05 01.05.10 Added 4 new events and their event data structures.168168+ * Added new ReasonCode value for SAS Device Status Change169169+ * event.170170+ * Added new family code for FC949E.169171 * --------------------------------------------------------------------------170172171173mpi_cnfg.h···408402 * Added OwnerDevHandle and Flags field to SAS PHY Page 0.409403 * Added IOC GPIO Flags define to SAS Enclosure Page 0.410404 * Fixed the value for MPI_SAS_IOUNIT1_CONTROL_DEV_SATA_SUPPORT.405405+ * 08-03-05 01.05.10 Removed ISDataScrubRate and ISResyncRate from406406+ * Manufacturing Page 4.407407+ * Added MPI_IOUNITPAGE1_SATA_WRITE_CACHE_DISABLE bit.408408+ * Added NumDevsPerEnclosure field to SAS IO Unit page 2.409409+ * Added MPI_SAS_IOUNIT2_FLAGS_HOST_ASSIGNED_PHYS_MAP410410+ * define.411411+ * Added EnclosureHandle field to SAS Expander page 0.412412+ * Removed redundant NumTableEntriesProg field from SAS413413+ * Expander Page 1.414414+ * 08-30-05 01.05.11 Added DeviceID for FC949E and changed the DeviceID for415415+ * SAS1078.416416+ * Added more defines for Manufacturing Page 4 Flags field.417417+ * Added more defines for IOCSettings and added418418+ * ExpanderSpinup field to Bios Page 1.419419+ * Added postpone SATA Init bit to SAS IO Unit Page 1420420+ * ControlFlags.421421+ * Changed LogEntry format for Log Page 0.411422 * --------------------------------------------------------------------------412423413424mpi_init.h···465442 * addressing.466443 * 06-24-05 01.05.05 Added SCSI IO 32 structures and defines.467444 * Added four new defines for SEP SlotStatus.445445+ * 08-03-05 01.05.06 Fixed some MPI_SCSIIO32_MSGFLGS_ defines to make them446446+ * unique in the first 32 characters.468447 * --------------------------------------------------------------------------469448470449mpi_targ.h···607582608583mpi_sas.h609584 * 08-19-04 01.05.01 Original release.585585+ * 08-30-05 01.05.02 Added DeviceInfo bit for SEP.586586+ * Added PrimFlags and Primitive field to SAS IO Unit587587+ * Control request, and added a new operation code.610588 * --------------------------------------------------------------------------611589612590mpi_type.h···620592 * 08-08-01 01.02.01 Original release for v1.2 work.621593 * 05-11-04 01.03.01 Original release for MPI v1.3.622594 * 08-19-04 01.05.01 Original release for MPI v1.5.595595+ * 08-30-05 01.05.02 Added PowerPC option to #ifdef's.623596 * --------------------------------------------------------------------------624597625598mpi_history.txt Parts list history626599627627-Filename 01.05.10 01.05.09628628----------- -------- --------629629-mpi.h 01.05.08 01.05.07630630-mpi_ioc.h 01.05.09 01.05.08631631-mpi_cnfg.h 01.05.09 01.05.08632632-mpi_init.h 01.05.05 01.05.04633633-mpi_targ.h 01.05.05 01.05.04634634-mpi_fc.h 01.05.01 01.05.01635635-mpi_lan.h 01.05.01 01.05.01636636-mpi_raid.h 01.05.02 01.05.02637637-mpi_tool.h 01.05.03 01.05.03638638-mpi_inb.h 01.05.01 01.05.01639639-mpi_sas.h 01.05.01 01.05.01640640-mpi_type.h 01.05.01 01.05.01600600+Filename 01.05.12 01.05.11 01.05.10 01.05.09601601+---------- -------- -------- -------- --------602602+mpi.h 01.05.10 01.05.09 01.05.08 01.05.07603603+mpi_ioc.h 01.05.10 01.05.09 01.05.09 01.05.08604604+mpi_cnfg.h 01.05.11 01.05.10 01.05.09 01.05.08605605+mpi_init.h 01.05.06 01.05.06 01.05.05 01.05.04606606+mpi_targ.h 01.05.05 01.05.05 01.05.05 01.05.04607607+mpi_fc.h 01.05.01 01.05.01 01.05.01 01.05.01608608+mpi_lan.h 01.05.01 01.05.01 01.05.01 01.05.01609609+mpi_raid.h 01.05.02 01.05.02 01.05.02 01.05.02610610+mpi_tool.h 01.05.03 01.05.03 01.05.03 01.05.03611611+mpi_inb.h 01.05.01 01.05.01 01.05.01 01.05.01612612+mpi_sas.h 01.05.02 01.05.01 01.05.01 01.05.01613613+mpi_type.h 01.05.02 01.05.01 01.05.01 01.05.01641614642615Filename 01.05.08 01.05.07 01.05.06 01.05.05 01.05.04 01.05.03643616---------- -------- -------- -------- -------- -------- --------
+5-3
drivers/message/fusion/lsi/mpi_init.h
···66 * Title: MPI initiator mode messages and structures77 * Creation Date: June 8, 200088 *99- * mpi_init.h Version: 01.05.0599+ * mpi_init.h Version: 01.05.061010 *1111 * Version History1212 * ---------------···5050 * addressing.5151 * 06-24-05 01.05.05 Added SCSI IO 32 structures and defines.5252 * Added four new defines for SEP SlotStatus.5353+ * 08-03-05 01.05.06 Fixed some MPI_SCSIIO32_MSGFLGS_ defines to make them5454+ * unique in the first 32 characters.5355 * --------------------------------------------------------------------------5456 */5557···292290293291/* SCSI IO 32 MsgFlags bits */294292#define MPI_SCSIIO32_MSGFLGS_SENSE_WIDTH (0x01)295295-#define MPI_SCSIIO32_MSGFLGS_SENSE_WIDTH_32 (0x00)296296-#define MPI_SCSIIO32_MSGFLGS_SENSE_WIDTH_64 (0x01)293293+#define MPI_SCSIIO32_MSGFLGS_32_SENSE_WIDTH (0x00)294294+#define MPI_SCSIIO32_MSGFLGS_64_SENSE_WIDTH (0x01)297295298296#define MPI_SCSIIO32_MSGFLGS_SENSE_LOCATION (0x02)299297#define MPI_SCSIIO32_MSGFLGS_SENSE_LOC_HOST (0x00)
+121-1
drivers/message/fusion/lsi/mpi_ioc.h
···66 * Title: MPI IOC, Port, Event, FW Download, and FW Upload messages77 * Creation Date: August 11, 200088 *99- * mpi_ioc.h Version: 01.05.0999+ * mpi_ioc.h Version: 01.05.101010 *1111 * Version History1212 * ---------------···8383 * Removed IOCFacts Reply EEDP Capability bit.8484 * 06-24-05 01.05.09 Added 5 new IOCFacts Reply IOCCapabilities bits.8585 * Added Max SATA Targets to SAS Discovery Error event.8686+ * 08-30-05 01.05.10 Added 4 new events and their event data structures.8787+ * Added new ReasonCode value for SAS Device Status Change8888+ * event.8989+ * Added new family code for FC949E.8690 * --------------------------------------------------------------------------8791 */8892···468464#define MPI_EVENT_PERSISTENT_TABLE_FULL (0x00000011)469465#define MPI_EVENT_SAS_PHY_LINK_STATUS (0x00000012)470466#define MPI_EVENT_SAS_DISCOVERY_ERROR (0x00000013)467467+#define MPI_EVENT_IR_RESYNC_UPDATE (0x00000014)468468+#define MPI_EVENT_IR2 (0x00000015)469469+#define MPI_EVENT_SAS_DISCOVERY (0x00000016)470470+#define MPI_EVENT_LOG_ENTRY_ADDED (0x00000021)471471472472/* AckRequired field values */473473···487479 U16 Reserved1; /* 02h */488480} EVENT_DATA_EVENT_CHANGE, MPI_POINTER PTR_EVENT_DATA_EVENT_CHANGE,489481 EventDataEventChange_t, MPI_POINTER pEventDataEventChange_t;482482+483483+/* LogEntryAdded Event data */484484+485485+/* this structure matches MPI_LOG_0_ENTRY in mpi_cnfg.h */486486+#define MPI_EVENT_DATA_LOG_ENTRY_DATA_LENGTH (0x1C)487487+typedef struct _EVENT_DATA_LOG_ENTRY488488+{489489+ U32 TimeStamp; /* 00h */490490+ U32 Reserved1; /* 04h */491491+ U16 LogSequence; /* 08h */492492+ U16 LogEntryQualifier; /* 0Ah */493493+ U8 LogData[MPI_EVENT_DATA_LOG_ENTRY_DATA_LENGTH]; /* 0Ch */494494+} EVENT_DATA_LOG_ENTRY, MPI_POINTER PTR_EVENT_DATA_LOG_ENTRY,495495+ MpiEventDataLogEntry_t, MPI_POINTER pMpiEventDataLogEntry_t;496496+497497+typedef struct _EVENT_DATA_LOG_ENTRY_ADDED498498+{499499+ U16 LogSequence; /* 00h */500500+ U16 Reserved1; /* 02h */501501+ U32 Reserved2; /* 04h */502502+ EVENT_DATA_LOG_ENTRY LogEntry; /* 08h */503503+} EVENT_DATA_LOG_ENTRY_ADDED, MPI_POINTER PTR_EVENT_DATA_LOG_ENTRY_ADDED,504504+ MpiEventDataLogEntryAdded_t, MPI_POINTER pMpiEventDataLogEntryAdded_t;490505491506/* SCSI Event data for Port, Bus and Device forms */492507···569538#define MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA (0x05)570539#define MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED (0x06)571540#define MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED (0x07)541541+#define MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET (0x08)572542573543574544/* SCSI Event data for Queue Full event */···610578#define MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED (0x09)611579#define MPI_EVENT_RAID_RC_SMART_DATA (0x0A)612580#define MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED (0x0B)581581+582582+583583+/* MPI Integrated RAID Resync Update Event data */584584+585585+typedef struct _MPI_EVENT_DATA_IR_RESYNC_UPDATE586586+{587587+ U8 VolumeID; /* 00h */588588+ U8 VolumeBus; /* 01h */589589+ U8 ResyncComplete; /* 02h */590590+ U8 Reserved1; /* 03h */591591+ U32 Reserved2; /* 04h */592592+} MPI_EVENT_DATA_IR_RESYNC_UPDATE,593593+ MPI_POINTER PTR_MPI_EVENT_DATA_IR_RESYNC_UPDATE,594594+ MpiEventDataIrResyncUpdate_t, MPI_POINTER pMpiEventDataIrResyncUpdate_t;595595+596596+/* MPI IR2 Event data */597597+598598+/* MPI_LD_STATE or MPI_PD_STATE */599599+typedef struct _IR2_STATE_CHANGED600600+{601601+ U16 PreviousState; /* 00h */602602+ U16 NewState; /* 02h */603603+} IR2_STATE_CHANGED, MPI_POINTER PTR_IR2_STATE_CHANGED;604604+605605+typedef struct _IR2_PD_INFO606606+{607607+ U16 DeviceHandle; /* 00h */608608+ U8 TruncEnclosureHandle; /* 02h */609609+ U8 TruncatedSlot; /* 03h */610610+} IR2_PD_INFO, MPI_POINTER PTR_IR2_PD_INFO;611611+612612+typedef union _MPI_IR2_RC_EVENT_DATA613613+{614614+ IR2_STATE_CHANGED StateChanged;615615+ U32 Lba;616616+ IR2_PD_INFO PdInfo;617617+} MPI_IR2_RC_EVENT_DATA, MPI_POINTER PTR_MPI_IR2_RC_EVENT_DATA;618618+619619+typedef struct _MPI_EVENT_DATA_IR2620620+{621621+ U8 TargetID; /* 00h */622622+ U8 Bus; /* 01h */623623+ U8 ReasonCode; /* 02h */624624+ U8 PhysDiskNum; /* 03h */625625+ MPI_IR2_RC_EVENT_DATA IR2EventData; /* 04h */626626+} MPI_EVENT_DATA_IR2, MPI_POINTER PTR_MPI_EVENT_DATA_IR2,627627+ MpiEventDataIR2_t, MPI_POINTER pMpiEventDataIR2_t;628628+629629+/* MPI IR2 Event data ReasonCode values */630630+#define MPI_EVENT_IR2_RC_LD_STATE_CHANGED (0x01)631631+#define MPI_EVENT_IR2_RC_PD_STATE_CHANGED (0x02)632632+#define MPI_EVENT_IR2_RC_BAD_BLOCK_TABLE_FULL (0x03)633633+#define MPI_EVENT_IR2_RC_PD_INSERTED (0x04)634634+#define MPI_EVENT_IR2_RC_PD_REMOVED (0x05)635635+#define MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED (0x06)636636+#define MPI_EVENT_IR2_RC_REBUILD_MEDIUM_ERROR (0x07)637637+638638+/* defines for logical disk states */639639+#define MPI_LD_STATE_OPTIMAL (0x00)640640+#define MPI_LD_STATE_DEGRADED (0x01)641641+#define MPI_LD_STATE_FAILED (0x02)642642+#define MPI_LD_STATE_MISSING (0x03)643643+#define MPI_LD_STATE_OFFLINE (0x04)644644+645645+/* defines for physical disk states */646646+#define MPI_PD_STATE_ONLINE (0x00)647647+#define MPI_PD_STATE_MISSING (0x01)648648+#define MPI_PD_STATE_NOT_COMPATIBLE (0x02)649649+#define MPI_PD_STATE_FAILED (0x03)650650+#define MPI_PD_STATE_INITIALIZING (0x04)651651+#define MPI_PD_STATE_OFFLINE_AT_HOST_REQUEST (0x05)652652+#define MPI_PD_STATE_FAILED_AT_HOST_REQUEST (0x06)653653+#define MPI_PD_STATE_OFFLINE_FOR_ANOTHER_REASON (0xFF)613654614655/* MPI Link Status Change Event data */615656···764659#define MPI_EVENT_SAS_PLS_LR_RATE_SATA_OOB_COMPLETE (0x03)765660#define MPI_EVENT_SAS_PLS_LR_RATE_1_5 (0x08)766661#define MPI_EVENT_SAS_PLS_LR_RATE_3_0 (0x09)662662+663663+/* SAS Discovery Event data */664664+665665+typedef struct _EVENT_DATA_SAS_DISCOVERY666666+{667667+ U32 DiscoveryStatus; /* 00h */668668+ U32 Reserved1; /* 04h */669669+} EVENT_DATA_SAS_DISCOVERY, MPI_POINTER PTR_EVENT_DATA_SAS_DISCOVERY,670670+ EventDataSasDiscovery_t, MPI_POINTER pEventDataSasDiscovery_t;671671+672672+#define MPI_EVENT_SAS_DSCVRY_COMPLETE (0x00000000)673673+#define MPI_EVENT_SAS_DSCVRY_IN_PROGRESS (0x00000001)674674+#define MPI_EVENT_SAS_DSCVRY_PHY_BITS_MASK (0xFFFF0000)675675+#define MPI_EVENT_SAS_DSCVRY_PHY_BITS_SHIFT (16)767676768677/* SAS Discovery Errror Event data */769678···988869#define MPI_FW_HEADER_PID_FAMILY_919XL_FC (0x0003) /* 919XL and 929XL */989870#define MPI_FW_HEADER_PID_FAMILY_939X_FC (0x0004) /* 939X and 949X */990871#define MPI_FW_HEADER_PID_FAMILY_959_FC (0x0005)872872+#define MPI_FW_HEADER_PID_FAMILY_949E_FC (0x0006)991873/* SAS */992874#define MPI_FW_HEADER_PID_FAMILY_1064_SAS (0x0001)993875#define MPI_FW_HEADER_PID_FAMILY_1068_SAS (0x0002)
+89
drivers/message/fusion/lsi/mpi_log_fc.h
···11+/*22+ * Copyright (c) 2000-2001 LSI Logic Corporation. All rights reserved.33+ *44+ * NAME: fc_log.h55+ * SUMMARY: MPI IocLogInfo definitions for the SYMFC9xx chips66+ * DESCRIPTION: Contains the enumerated list of values that may be returned77+ * in the IOCLogInfo field of a MPI Default Reply Message.88+ *99+ * CREATION DATE: 6/02/20001010+ * ID: $Id: fc_log.h,v 4.6 2001/07/26 14:41:33 sschremm Exp $1111+ */1212+1313+1414+/*1515+ * MpiIocLogInfo_t enum1616+ *1717+ * These 32 bit values are used in the IOCLogInfo field of the MPI reply1818+ * messages.1919+ * The value is 0xabcccccc where2020+ * a = The type of log info as per the MPI spec. Since these codes are2121+ * all for Fibre Channel this value will always be 2.2222+ * b = Specifies a subclass of the firmware where2323+ * 0 = FCP Initiator2424+ * 1 = FCP Target2525+ * 2 = LAN2626+ * 3 = MPI Message Layer2727+ * 4 = FC Link2828+ * 5 = Context Manager2929+ * 6 = Invalid Field Offset3030+ * 7 = State Change Info3131+ * all others are reserved for future use3232+ * c = A specific value within the subclass.3333+ *3434+ * NOTE: Any new values should be added to the end of each subclass so that the3535+ * codes remain consistent across firmware releases.3636+ */3737+typedef enum _MpiIocLogInfoFc3838+{3939+ MPI_IOCLOGINFO_FC_INIT_BASE = 0x20000000,4040+ MPI_IOCLOGINFO_FC_INIT_ERROR_OUT_OF_ORDER_FRAME = 0x20000001, /* received an out of order frame - unsupported */4141+ MPI_IOCLOGINFO_FC_INIT_ERROR_BAD_START_OF_FRAME = 0x20000002, /* Bad Rx Frame, bad start of frame primative */4242+ MPI_IOCLOGINFO_FC_INIT_ERROR_BAD_END_OF_FRAME = 0x20000003, /* Bad Rx Frame, bad end of frame primative */4343+ MPI_IOCLOGINFO_FC_INIT_ERROR_OVER_RUN = 0x20000004, /* Bad Rx Frame, overrun */4444+ MPI_IOCLOGINFO_FC_INIT_ERROR_RX_OTHER = 0x20000005, /* Other errors caught by IOC which require retries */4545+ MPI_IOCLOGINFO_FC_INIT_ERROR_SUBPROC_DEAD = 0x20000006, /* Main processor could not initialize sub-processor */4646+ MPI_IOCLOGINFO_FC_INIT_ERROR_RX_OVERRUN = 0x20000007, /* Scatter Gather overrun */4747+ MPI_IOCLOGINFO_FC_INIT_ERROR_RX_BAD_STATUS = 0x20000008, /* Receiver detected context mismatch via invalid header */4848+ MPI_IOCLOGINFO_FC_INIT_ERROR_RX_UNEXPECTED_FRAME= 0x20000009, /* CtxMgr detected unsupported frame type */4949+ MPI_IOCLOGINFO_FC_INIT_ERROR_LINK_FAILURE = 0x2000000A, /* Link failure occurred */5050+ MPI_IOCLOGINFO_FC_INIT_ERROR_TX_TIMEOUT = 0x2000000B, /* Transmitter timeout error */5151+5252+ MPI_IOCLOGINFO_FC_TARGET_BASE = 0x21000000,5353+ MPI_IOCLOGINFO_FC_TARGET_NO_PDISC = 0x21000001, /* not sent because we are waiting for a PDISC from the initiator */5454+ MPI_IOCLOGINFO_FC_TARGET_NO_LOGIN = 0x21000002, /* not sent because we are not logged in to the remote node */5555+ MPI_IOCLOGINFO_FC_TARGET_DOAR_KILLED_BY_LIP = 0x21000003, /* Data Out, Auto Response, not sent due to a LIP */5656+ MPI_IOCLOGINFO_FC_TARGET_DIAR_KILLED_BY_LIP = 0x21000004, /* Data In, Auto Response, not sent due to a LIP */5757+ MPI_IOCLOGINFO_FC_TARGET_DIAR_MISSING_DATA = 0x21000005, /* Data In, Auto Response, missing data frames */5858+ MPI_IOCLOGINFO_FC_TARGET_DONR_KILLED_BY_LIP = 0x21000006, /* Data Out, No Response, not sent due to a LIP */5959+ MPI_IOCLOGINFO_FC_TARGET_WRSP_KILLED_BY_LIP = 0x21000007, /* Auto-response after a write not sent due to a LIP */6060+ MPI_IOCLOGINFO_FC_TARGET_DINR_KILLED_BY_LIP = 0x21000008, /* Data In, No Response, not completed due to a LIP */6161+ MPI_IOCLOGINFO_FC_TARGET_DINR_MISSING_DATA = 0x21000009, /* Data In, No Response, missing data frames */6262+ MPI_IOCLOGINFO_FC_TARGET_MRSP_KILLED_BY_LIP = 0x2100000a, /* Manual Response not sent due to a LIP */6363+ MPI_IOCLOGINFO_FC_TARGET_NO_CLASS_3 = 0x2100000b, /* not sent because remote node does not support Class 3 */6464+ MPI_IOCLOGINFO_FC_TARGET_LOGIN_NOT_VALID = 0x2100000c, /* not sent because login to remote node not validated */6565+ MPI_IOCLOGINFO_FC_TARGET_FROM_OUTBOUND = 0x2100000e, /* cleared from the outbound queue after a logout */6666+ MPI_IOCLOGINFO_FC_TARGET_WAITING_FOR_DATA_IN = 0x2100000f, /* cleared waiting for data after a logout */6767+6868+ MPI_IOCLOGINFO_FC_LAN_BASE = 0x22000000,6969+ MPI_IOCLOGINFO_FC_LAN_TRANS_SGL_MISSING = 0x22000001, /* Transaction Context Sgl Missing */7070+ MPI_IOCLOGINFO_FC_LAN_TRANS_WRONG_PLACE = 0x22000002, /* Transaction Context found before an EOB */7171+ MPI_IOCLOGINFO_FC_LAN_TRANS_RES_BITS_SET = 0x22000003, /* Transaction Context value has reserved bits set */7272+ MPI_IOCLOGINFO_FC_LAN_WRONG_SGL_FLAG = 0x22000004, /* Invalid SGL Flags */7373+7474+ MPI_IOCLOGINFO_FC_MSG_BASE = 0x23000000,7575+7676+ MPI_IOCLOGINFO_FC_LINK_BASE = 0x24000000,7777+ MPI_IOCLOGINFO_FC_LINK_LOOP_INIT_TIMEOUT = 0x24000001, /* Loop initialization timed out */7878+ MPI_IOCLOGINFO_FC_LINK_ALREADY_INITIALIZED = 0x24000002, /* Another system controller already initialized the loop */7979+ MPI_IOCLOGINFO_FC_LINK_LINK_NOT_ESTABLISHED = 0x24000003, /* Not synchronized to signal or still negotiating (possible cable problem) */8080+ MPI_IOCLOGINFO_FC_LINK_CRC_ERROR = 0x24000004, /* CRC check detected error on received frame */8181+8282+ MPI_IOCLOGINFO_FC_CTX_BASE = 0x25000000,8383+8484+ MPI_IOCLOGINFO_FC_INVALID_FIELD_BYTE_OFFSET = 0x26000000, /* The lower 24 bits give the byte offset of the field in the request message that is invalid */8585+ MPI_IOCLOGINFO_FC_INVALID_FIELD_MAX_OFFSET = 0x26ffffff,8686+8787+ MPI_IOCLOGINFO_FC_STATE_CHANGE = 0x27000000 /* The lower 24 bits give additional information concerning state change */8888+8989+} MpiIocLogInfoFc_t;
+162
drivers/message/fusion/lsi/mpi_log_sas.h
···11+22+/***************************************************************************33+ * *44+ * Copyright 2003 LSI Logic Corporation. All rights reserved. *55+ * *66+ * This file is confidential and a trade secret of LSI Logic. The *77+ * receipt of or possession of this file does not convey any rights to *88+ * reproduce or disclose its contents or to manufacture, use, or sell *99+ * anything it may describe, in whole, or in part, without the specific *1010+ * written consent of LSI Logic Corporation. *1111+ * *1212+ ***************************************************************************1313+ *1414+ * Name: iopiIocLogInfo.h1515+ * Title: SAS Firmware IOP Interface IOC Log Info Definitions1616+ * Programmer: Guy Kendall1717+ * Creation Date: September 24, 20031818+ *1919+ * Version History2020+ * ---------------2121+ *2222+ * Last Updated2323+ * -------------2424+ * Version %version: 22 %2525+ * Date Updated %date_modified: %2626+ * Programmer %created_by: nperucca %2727+ *2828+ * Date Who Description2929+ * -------- --- -------------------------------------------------------3030+ * 09/24/03 GWK Initial version3131+ *3232+ *3333+ * Description3434+ * ------------3535+ * This include file contains SAS firmware interface IOC Log Info codes3636+ *3737+ *-------------------------------------------------------------------------3838+ */3939+4040+#ifndef IOPI_IOCLOGINFO_H_INCLUDED4141+#define IOPI_IOCLOGINFO_H_INCLUDED4242+4343+4444+/****************************************************************************/4545+/* IOC LOGINFO defines, 0x00000000 - 0x0FFFFFFF */4646+/* Format: */4747+/* Bits 31-28: MPI_IOCLOGINFO_TYPE_SAS (3) */4848+/* Bits 27-24: IOC_LOGINFO_ORIGINATOR: 0=IOP, 1=PL, 2=IR */4949+/* Bits 23-16: LOGINFO_CODE */5050+/* Bits 15-0: LOGINFO_CODE Specific */5151+/****************************************************************************/5252+5353+/****************************************************************************/5454+/* IOC_LOGINFO_ORIGINATOR defines */5555+/****************************************************************************/5656+#define IOC_LOGINFO_ORIGINATOR_IOP (0x00000000)5757+#define IOC_LOGINFO_ORIGINATOR_PL (0x01000000)5858+#define IOC_LOGINFO_ORIGINATOR_IR (0x02000000)5959+6060+/****************************************************************************/6161+/* LOGINFO_CODE defines */6262+/****************************************************************************/6363+#define IOC_LOGINFO_CODE_MASK (0x00FF0000)6464+#define IOC_LOGINFO_CODE_SHIFT (16)6565+6666+/****************************************************************************/6767+/* IOP LOGINFO_CODE defines, valid if IOC_LOGINFO_ORIGINATOR = IOP */6868+/****************************************************************************/6969+#define IOP_LOGINFO_CODE_INVALID_SAS_ADDRESS (0x00010000)7070+#define IOP_LOGINFO_CODE_UNUSED2 (0x00020000)7171+#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE (0x00030000)7272+#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_RT (0x00030100) /* Route Table Entry not found */7373+#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_PN (0x00030200) /* Invalid Page Number */7474+#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_FORM (0x00030300) /* Invalid FORM */7575+#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_PT (0x00030400) /* Invalid Page Type */7676+#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_DNM (0x00030500) /* Device Not Mapped */7777+#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_PERSIST (0x00030600) /* Persistent Page not found */7878+#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_DEFAULT (0x00030700) /* Default Page not found */7979+#define IOP_LOGINFO_CODE_TASK_TERMINATED (0x00050000)8080+8181+8282+/****************************************************************************/8383+/* PL LOGINFO_CODE defines, valid if IOC_LOGINFO_ORIGINATOR = PL */8484+/****************************************************************************/8585+#define PL_LOGINFO_CODE_OPEN_FAILURE (0x00010000)8686+#define PL_LOGINFO_CODE_INVALID_SGL (0x00020000)8787+#define PL_LOGINFO_CODE_WRONG_REL_OFF_OR_FRAME_LENGTH (0x00030000)8888+#define PL_LOGINFO_CODE_FRAME_XFER_ERROR (0x00040000)8989+#define PL_LOGINFO_CODE_TX_FM_CONNECTED_LOW (0x00050000)9090+#define PL_LOGINFO_CODE_SATA_NON_NCQ_RW_ERR_BIT_SET (0x00060000)9191+#define PL_LOGINFO_CODE_SATA_READ_LOG_RECEIVE_DATA_ERR (0x00070000)9292+#define PL_LOGINFO_CODE_SATA_NCQ_FAIL_ALL_CMDS_AFTR_ERR (0x00080000)9393+#define PL_LOGINFO_CODE_SATA_ERR_IN_RCV_SET_DEV_BIT_FIS (0x00090000)9494+#define PL_LOGINFO_CODE_RX_FM_INVALID_MESSAGE (0x000A0000)9595+#define PL_LOGINFO_CODE_RX_CTX_MESSAGE_VALID_ERROR (0x000B0000)9696+#define PL_LOGINFO_CODE_RX_FM_CURRENT_FRAME_ERROR (0x000C0000)9797+#define PL_LOGINFO_CODE_SATA_LINK_DOWN (0x000D0000)9898+#define PL_LOGINFO_CODE_DISCOVERY_SATA_INIT_W_IOS (0x000E0000)9999+#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE (0x000F0000)100100+#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_PT (0x000F0100) /* Invalid Page Type */101101+#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_NUM_PHYS (0x000F0200) /* Invalid Number of Phys */102102+#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_NOT_IMP (0x000F0300) /* Case Not Handled */103103+#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_NO_DEV (0x000F0400) /* No Device Found */104104+#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_FORM (0x000F0500) /* Invalid FORM */105105+#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_PHY (0x000F0600) /* Invalid Phy */106106+#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_NO_OWNER (0x000F0700) /* No Owner Found */107107+#define PL_LOGINFO_CODE_DSCVRY_SATA_INIT_TIMEOUT (0x00100000)108108+#define PL_LOGINFO_CODE_RESET (0x00110000)109109+#define PL_LOGINFO_CODE_ABORT (0x00120000)110110+#define PL_LOGINFO_CODE_IO_NOT_YET_EXECUTED (0x00130000)111111+#define PL_LOGINFO_CODE_IO_EXECUTED (0x00140000)112112+#define PL_LOGINFO_SUB_CODE_OPEN_FAILURE (0x00000100)113113+#define PL_LOGINFO_SUB_CODE_INVALID_SGL (0x00000200)114114+#define PL_LOGINFO_SUB_CODE_WRONG_REL_OFF_OR_FRAME_LENGTH (0x00000300)115115+#define PL_LOGINFO_SUB_CODE_FRAME_XFER_ERROR (0x00000400)116116+#define PL_LOGINFO_SUB_CODE_TX_FM_CONNECTED_LOW (0x00000500)117117+#define PL_LOGINFO_SUB_CODE_SATA_NON_NCQ_RW_ERR_BIT_SET (0x00000600)118118+#define PL_LOGINFO_SUB_CODE_SATA_READ_LOG_RECEIVE_DATA_ERR (0x00000700)119119+#define PL_LOGINFO_SUB_CODE_SATA_NCQ_FAIL_ALL_CMDS_AFTR_ERR (0x00000800)120120+#define PL_LOGINFO_SUB_CODE_SATA_ERR_IN_RCV_SET_DEV_BIT_FIS (0x00000900)121121+#define PL_LOGINFO_SUB_CODE_RX_FM_INVALID_MESSAGE (0x00000A00)122122+#define PL_LOGINFO_SUB_CODE_RX_CTX_MESSAGE_VALID_ERROR (0x00000B00)123123+#define PL_LOGINFO_SUB_CODE_RX_FM_CURRENT_FRAME_ERROR (0x00000C00)124124+#define PL_LOGINFO_SUB_CODE_SATA_LINK_DOWN (0x00000D00)125125+#define PL_LOGINFO_SUB_CODE_DISCOVERY_SATA_INIT_W_IOS (0x00000E00)126126+#define PL_LOGINFO_SUB_CODE_DSCVRY_SATA_INIT_TIMEOUT (0x00001000)127127+128128+129129+#define PL_LOGINFO_CODE_ENCL_MGMT_SMP_FRAME_FAILURE (0x00200000) /* Can't get SMP Frame */130130+#define PL_LOGINFO_CODE_ENCL_MGMT_SMP_READ_ERROR (0x00200001) /* Error occured on SMP Read */131131+#define PL_LOGINFO_CODE_ENCL_MGMT_SMP_WRITE_ERROR (0x00200002) /* Error occured on SMP Write */132132+#define PL_LOGINFO_CODE_ENCL_MGMT_NOT_SUPPORTED_ON_ENCL (0x00200004) /* Encl Mgmt services not available for this WWID */133133+#define PL_LOGINFO_CODE_ENCL_MGMT_ADDR_MODE_NOT_SUPPORTED (0x00200005) /* Address Mode not suppored */134134+#define PL_LOGINFO_CODE_ENCL_MGMT_BAD_SLOT_NUM (0x00200006) /* Invalid Slot Number in SEP Msg */135135+#define PL_LOGINFO_CODE_ENCL_MGMT_SGPIO_NOT_PRESENT (0x00200007) /* SGPIO not present/enabled */136136+137137+#define PL_LOGINFO_DA_SEP_NOT_PRESENT (0x00200100) /* SEP not present when msg received */138138+#define PL_LOGINFO_DA_SEP_SINGLE_THREAD_ERROR (0x00200101) /* Can only accept 1 msg at a time */139139+#define PL_LOGINFO_DA_SEP_ISTWI_INTR_IN_IDLE_STATE (0x00200102) /* ISTWI interrupt recvd. while IDLE */140140+#define PL_LOGINFO_DA_SEP_RECEIVED_NACK_FROM_SLAVE (0x00200103) /* SEP NACK'd, it is busy */141141+#define PL_LOGINFO_DA_SEP_BAD_STATUS_HDR_CHKSUM (0x00200104) /* SEP stopped or sent bad chksum in Hdr */142142+#define PL_LOGINFO_DA_SEP_UNSUPPORTED_SCSI_STATUS_1 (0x00200105) /* SEP returned unknown scsi status */143143+#define PL_LOGINFO_DA_SEP_UNSUPPORTED_SCSI_STATUS_2 (0x00200106) /* SEP returned unknown scsi status */144144+#define PL_LOGINFO_DA_SEP_CHKSUM_ERROR_AFTER_STOP (0x00200107) /* SEP returned bad chksum after STOP */145145+#define PL_LOGINFO_DA_SEP_CHKSUM_ERROR_AFTER_STOP_GETDATA (0x00200108) /* SEP returned bad chksum after STOP while gettin data*/146146+147147+148148+/****************************************************************************/149149+/* IR LOGINFO_CODE defines, valid if IOC_LOGINFO_ORIGINATOR = IR */150150+/****************************************************************************/151151+#define IR_LOGINFO_CODE_UNUSED1 (0x00010000)152152+#define IR_LOGINFO_CODE_UNUSED2 (0x00020000)153153+154154+/****************************************************************************/155155+/* Defines for convienence */156156+/****************************************************************************/157157+#define IOC_LOGINFO_PREFIX_IOP ((MPI_IOCLOGINFO_TYPE_SAS << MPI_IOCLOGINFO_TYPE_SHIFT) | IOC_LOGINFO_ORIGINATOR_IOP)158158+#define IOC_LOGINFO_PREFIX_PL ((MPI_IOCLOGINFO_TYPE_SAS << MPI_IOCLOGINFO_TYPE_SHIFT) | IOC_LOGINFO_ORIGINATOR_PL)159159+#define IOC_LOGINFO_PREFIX_IR ((MPI_IOCLOGINFO_TYPE_SAS << MPI_IOCLOGINFO_TYPE_SHIFT) | IOC_LOGINFO_ORIGINATOR_IR)160160+161161+#endif /* end of file */162162+
+20-10
drivers/message/fusion/lsi/mpi_sas.h
···66 * Title: MPI Serial Attached SCSI structures and definitions77 * Creation Date: August 19, 200488 *99- * mpi_sas.h Version: 01.05.0199+ * mpi_sas.h Version: 01.05.021010 *1111 * Version History1212 * ---------------···1414 * Date Version Description1515 * -------- -------- ------------------------------------------------------1616 * 08-19-04 01.05.01 Original release.1717+ * 08-30-05 01.05.02 Added DeviceInfo bit for SEP.1818+ * Added PrimFlags and Primitive field to SAS IO Unit1919+ * Control request, and added a new operation code.1720 * --------------------------------------------------------------------------1821 */1922···5451 * Values for the SAS DeviceInfo field used in SAS Device Status Change Event5552 * data and SAS IO Unit Configuration pages.5653 */5454+#define MPI_SAS_DEVICE_INFO_SEP (0x00004000)5755#define MPI_SAS_DEVICE_INFO_ATAPI_DEVICE (0x00002000)5856#define MPI_SAS_DEVICE_INFO_LSI_DEVICE (0x00001000)5957#define MPI_SAS_DEVICE_INFO_DIRECT_ATTACH (0x00000800)···216212 U8 TargetID; /* 0Ch */217213 U8 Bus; /* 0Dh */218214 U8 PhyNum; /* 0Eh */219219- U8 Reserved4; /* 0Fh */220220- U32 Reserved5; /* 10h */215215+ U8 PrimFlags; /* 0Fh */216216+ U32 Primitive; /* 10h */221217 U64 SASAddress; /* 14h */222222- U32 Reserved6; /* 1Ch */218218+ U32 Reserved4; /* 1Ch */223219} MSG_SAS_IOUNIT_CONTROL_REQUEST, MPI_POINTER PTR_MSG_SAS_IOUNIT_CONTROL_REQUEST,224220 SasIoUnitControlRequest_t, MPI_POINTER pSasIoUnitControlRequest_t;225221226222/* values for the Operation field */227227-#define MPI_SAS_OP_CLEAR_NOT_PRESENT (0x01)228228-#define MPI_SAS_OP_CLEAR_ALL_PERSISTENT (0x02)229229-#define MPI_SAS_OP_PHY_LINK_RESET (0x06)230230-#define MPI_SAS_OP_PHY_HARD_RESET (0x07)231231-#define MPI_SAS_OP_PHY_CLEAR_ERROR_LOG (0x08)232232-#define MPI_SAS_OP_MAP_CURRENT (0x09)223223+#define MPI_SAS_OP_CLEAR_NOT_PRESENT (0x01)224224+#define MPI_SAS_OP_CLEAR_ALL_PERSISTENT (0x02)225225+#define MPI_SAS_OP_PHY_LINK_RESET (0x06)226226+#define MPI_SAS_OP_PHY_HARD_RESET (0x07)227227+#define MPI_SAS_OP_PHY_CLEAR_ERROR_LOG (0x08)228228+#define MPI_SAS_OP_MAP_CURRENT (0x09)229229+#define MPI_SAS_OP_SEND_PRIMITIVE (0x0A)230230+231231+/* values for the PrimFlags field */232232+#define MPI_SAS_PRIMFLAGS_SINGLE (0x08)233233+#define MPI_SAS_PRIMFLAGS_TRIPLE (0x02)234234+#define MPI_SAS_PRIMFLAGS_REDUNDANT (0x01)233235234236235237/* SAS IO Unit Control Reply */
+37-11
drivers/message/fusion/mptbase.c
···148148static int WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag);149149static int WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag);150150static int GetLanConfigPages(MPT_ADAPTER *ioc);151151-static int GetFcPortPage0(MPT_ADAPTER *ioc, int portnum);152151static int GetIoUnitPage2(MPT_ADAPTER *ioc);153152int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);154153static int mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum);···12311232 dprintk((KERN_INFO MYNAM12321233 ": Not using 64 bit consistent mask\n"));1233123412341234- ioc = kmalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC);12351235+ ioc = kzalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC);12351236 if (ioc == NULL) {12361237 printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n");12371238 return -ENOMEM;12381239 }12391239- memset(ioc, 0, sizeof(MPT_ADAPTER));12401240 ioc->alloc_total = sizeof(MPT_ADAPTER);12411241 ioc->req_sz = MPT_DEFAULT_FRAME_SIZE; /* avoid div by zero! */12421242 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;···12431245 ioc->pcidev = pdev;12441246 ioc->diagPending = 0;12451247 spin_lock_init(&ioc->diagLock);12481248+ spin_lock_init(&ioc->fc_rescan_work_lock);12491249+ spin_lock_init(&ioc->fc_rport_lock);12461250 spin_lock_init(&ioc->initializing_hba_lock);1247125112481252 /* Initialize the event logging.···12671267 /* Initialize the running configQ head.12681268 */12691269 INIT_LIST_HEAD(&ioc->configQ);12701270+12711271+ /* Initialize the fc rport list head.12721272+ */12731273+ INIT_LIST_HEAD(&ioc->fc_rports);1270127412711275 /* Find lookup slot. */12721276 INIT_LIST_HEAD(&ioc->list);···13771373 ioc->prod_name = "LSIFC949X";13781374 ioc->bus_type = FC;13791375 ioc->errata_flag_1064 = 1;13761376+ }13771377+ else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC949E) {13781378+ ioc->prod_name = "LSIFC949E";13791379+ ioc->bus_type = FC;13801380 }13811381 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_53C1030) {13821382 ioc->prod_name = "LSI53C1030";···16301622 pci_enable_device(pdev);1631162316321624 /* enable interrupts */16331633- CHIPREG_WRITE32(&ioc->chip->IntMask, ~(MPI_HIM_RIM));16251625+ CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);16341626 ioc->active = 1;1635162716361628 /* F/W not running */···17231715 /* (re)Enable alt-IOC! (reply interrupt, FreeQ) */17241716 dprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",17251717 ioc->alt_ioc->name));17261726- CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, ~(MPI_HIM_RIM));17181718+ CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);17271719 ioc->alt_ioc->active = 1;17281720 }17291721···1839183118401832 if (ret == 0) {18411833 /* Enable! (reply interrupt) */18421842- CHIPREG_WRITE32(&ioc->chip->IntMask, ~(MPI_HIM_RIM));18341834+ CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);18431835 ioc->active = 1;18441836 }18451837···18471839 /* (re)Enable alt-IOC! (reply interrupt) */18481840 dinitprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",18491841 ioc->alt_ioc->name));18501850- CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, ~(MPI_HIM_RIM));18421842+ CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);18511843 ioc->alt_ioc->active = 1;18521844 }18531845···18881880 * (FCPortPage0_t stuff)18891881 */18901882 for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {18911891- (void) GetFcPortPage0(ioc, ii);18831883+ (void) mptbase_GetFcPortPage0(ioc, ii);18921884 }1893188518941886 if ((ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) &&···4207419942084200/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/42094201/*42104210- * GetFcPortPage0 - Fetch FCPort config Page0.42024202+ * mptbase_GetFcPortPage0 - Fetch FCPort config Page0.42114203 * @ioc: Pointer to MPT_ADAPTER structure42124204 * @portnum: IOC Port number42134205 *···42174209 * -EAGAIN if no msg frames currently available42184210 * -EFAULT for non-successful reply or no reply (timeout)42194211 */42204220-static int42214221-GetFcPortPage0(MPT_ADAPTER *ioc, int portnum)42124212+int42134213+mptbase_GetFcPortPage0(MPT_ADAPTER *ioc, int portnum)42224214{42234215 ConfigPageHeader_t hdr;42244216 CONFIGPARMS cfg;···42284220 int data_sz;42294221 int copy_sz;42304222 int rc;42234223+ int count = 400;42244224+4231422542324226 /* Get FCPort Page 0 header */42334227 hdr.PageVersion = 0;···42534243 rc = -ENOMEM;42544244 ppage0_alloc = (FCPortPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);42554245 if (ppage0_alloc) {42464246+42474247+ try_again:42564248 memset((u8 *)ppage0_alloc, 0, data_sz);42574249 cfg.physAddr = page0_dma;42584250 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;···42864274 pp0dest->DiscoveredPortsCount = le32_to_cpu(pp0dest->DiscoveredPortsCount);42874275 pp0dest->MaxInitiators = le32_to_cpu(pp0dest->MaxInitiators);4288427642774277+ /*42784278+ * if still doing discovery,42794279+ * hang loose a while until finished42804280+ */42814281+ if (pp0dest->PortState == MPI_FCPORTPAGE0_PORTSTATE_UNKNOWN) {42824282+ if (count-- > 0) {42834283+ msleep_interruptible(100);42844284+ goto try_again;42854285+ }42864286+ printk(MYIOC_s_INFO_FMT "Firmware discovery not"42874287+ " complete.\n",42884288+ ioc->name);42894289+ }42894290 }4290429142914292 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);···63836358EXPORT_SYMBOL(mpt_free_fw_memory);63846359EXPORT_SYMBOL(mptbase_sas_persist_operation);63856360EXPORT_SYMBOL(mpt_alt_ioc_wait);63616361+EXPORT_SYMBOL(mptbase_GetFcPortPage0);638663626387636363886364/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+30-4
drivers/message/fusion/mptbase.h
···7676#define COPYRIGHT "Copyright (c) 1999-2005 " MODULEAUTHOR7777#endif78787979-#define MPT_LINUX_VERSION_COMMON "3.03.05"8080-#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.03.05"7979+#define MPT_LINUX_VERSION_COMMON "3.03.06"8080+#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.03.06"8181#define WHAT_MAGIC_STRING "@" "(" "#" ")"82828383#define show_mptmod_ver(s,ver) \···413413 u8 status; /* current command status */414414 u8 reset; /* 1 if bus reset allowed */415415 u8 target; /* target for reset */416416- struct semaphore sem_ioc;416416+ struct mutex ioctl_mutex;417417} MPT_IOCTL;418418419419#define MPT_SAS_MGMT_STATUS_RF_VALID 0x02 /* The Reply Frame is VALID */···421421#define MPT_SAS_MGMT_STATUS_TM_FAILED 0x40 /* User TM request failed */422422423423typedef struct _MPT_SAS_MGMT {424424- struct semaphore mutex;424424+ struct mutex mutex;425425 struct completion done;426426 u8 reply[MPT_DEFAULT_FRAME_SIZE]; /* reply frame data */427427 u8 status; /* current command status */···498498 IOCPage3_t *pIocPg3; /* table of physical disks */499499 int isRaid; /* bit field, 1 if RAID */500500}RaidCfgData;501501+502502+#define MPT_RPORT_INFO_FLAGS_REGISTERED 0x01 /* rport registered */503503+#define MPT_RPORT_INFO_FLAGS_MISSING 0x02 /* missing from DevPage0 scan */504504+#define MPT_RPORT_INFO_FLAGS_MAPPED_VDEV 0x04 /* target mapped in vdev */505505+506506+/*507507+ * data allocated for each fc rport device508508+ */509509+struct mptfc_rport_info510510+{511511+ struct list_head list;512512+ struct fc_rport *rport;513513+ VirtDevice *vdev;514514+ FCDevicePage0_t pg0;515515+ u8 flags;516516+};501517502518/*503519 * Adapter Structure - pci_dev specific. Maximum: MPT_MAX_ADAPTERS···628612 struct list_head list;629613 struct net_device *netdev;630614 struct list_head sas_topology;615615+ struct mutex sas_topology_mutex;631616 MPT_SAS_MGMT sas_mgmt;617617+ int num_ports;618618+619619+ struct list_head fc_rports;620620+ spinlock_t fc_rport_lock; /* list and ri flags */621621+ spinlock_t fc_rescan_work_lock;622622+ int fc_rescan_work_count;623623+ struct work_struct fc_rescan_work;624624+632625} MPT_ADAPTER;633626634627/*···1024999extern int mpt_findImVolumes(MPT_ADAPTER *ioc);10251000extern int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc);10261001extern int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);10021002+extern int mptbase_GetFcPortPage0(MPT_ADAPTER *ioc, int portnum);10271003extern int mpt_alt_ioc_wait(MPT_ADAPTER *ioc);1028100410291005/*
+6-6
drivers/message/fusion/mptctl.c
···177177 dctlprintk((KERN_INFO MYNAM "::mptctl_syscall_down(%p,%d) called\n", ioc, nonblock));178178179179 if (nonblock) {180180- if (down_trylock(&ioc->ioctl->sem_ioc))180180+ if (!mutex_trylock(&ioc->ioctl->ioctl_mutex))181181 rc = -EAGAIN;182182 } else {183183- if (down_interruptible(&ioc->ioctl->sem_ioc))183183+ if (mutex_lock_interruptible(&ioc->ioctl->ioctl_mutex))184184 rc = -ERESTARTSYS;185185 }186186 dctlprintk((KERN_INFO MYNAM "::mptctl_syscall_down return %d\n", rc));···557557 else558558 ret = -EINVAL;559559560560- up(&iocp->ioctl->sem_ioc);560560+ mutex_unlock(&iocp->ioctl->ioctl_mutex);561561562562 return ret;563563}···2619261926202620 ret = mptctl_do_fw_download(kfw.iocnum, kfw.bufp, kfw.fwlen);2621262126222622- up(&iocp->ioctl->sem_ioc);26222622+ mutex_unlock(&iocp->ioctl->ioctl_mutex);2623262326242624 return ret;26252625}···26732673 */26742674 ret = mptctl_do_mpt_command (karg, &uarg->MF);2675267526762676- up(&iocp->ioctl->sem_ioc);26762676+ mutex_unlock(&iocp->ioctl->ioctl_mutex);2677267726782678 return ret;26792679}···27432743 memset(mem, 0, sz);27442744 ioc->ioctl = (MPT_IOCTL *) mem;27452745 ioc->ioctl->ioc = ioc;27462746- sema_init(&ioc->ioctl->sem_ioc, 1);27462746+ mutex_init(&ioc->ioctl->ioctl_mutex);27472747 return 0;2748274827492749out_fail:
+546-35
drivers/message/fusion/mptfc.c
···5555#include <linux/reboot.h> /* notifier code */5656#include <linux/sched.h>5757#include <linux/workqueue.h>5858+#include <linux/sort.h>58595960#include <scsi/scsi.h>6061#include <scsi/scsi_cmnd.h>6162#include <scsi/scsi_device.h>6263#include <scsi/scsi_host.h>6364#include <scsi/scsi_tcq.h>6565+#include <scsi/scsi_transport_fc.h>64666567#include "mptbase.h"6668#include "mptscsih.h"···8179module_param(mpt_pq_filter, int, 0);8280MODULE_PARM_DESC(mpt_pq_filter, " Enable peripheral qualifier filter: enable=1 (default=0)");83818282+#define MPTFC_DEV_LOSS_TMO (60)8383+static int mptfc_dev_loss_tmo = MPTFC_DEV_LOSS_TMO; /* reasonable default */8484+module_param(mptfc_dev_loss_tmo, int, 0);8585+MODULE_PARM_DESC(mptfc_dev_loss_tmo, " Initial time the driver programs the "8686+ " transport to wait for an rport to "8787+ " return following a device loss event."8888+ " Default=60.");8989+8490static int mptfcDoneCtx = -1;8591static int mptfcTaskCtx = -1;8692static int mptfcInternalCtx = -1; /* Used only for internal commands */9393+9494+int mptfc_slave_alloc(struct scsi_device *device);9595+static int mptfc_qcmd(struct scsi_cmnd *SCpnt,9696+ void (*done)(struct scsi_cmnd *));9797+9898+static void mptfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout);9999+static void __devexit mptfc_remove(struct pci_dev *pdev);8710088101static struct scsi_host_template mptfc_driver_template = {89102 .module = THIS_MODULE,···10689 .proc_info = mptscsih_proc_info,10790 .name = "MPT FC Host",10891 .info = mptscsih_info,109109- .queuecommand = mptscsih_qcmd,9292+ .queuecommand = mptfc_qcmd,11093 .target_alloc = mptscsih_target_alloc,111111- .slave_alloc = mptscsih_slave_alloc,9494+ .slave_alloc = mptfc_slave_alloc,11295 .slave_configure = mptscsih_slave_configure,11396 .target_destroy = mptscsih_target_destroy,11497 .slave_destroy = mptscsih_slave_destroy,···145128 PCI_ANY_ID, PCI_ANY_ID },146129 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC949X,147130 PCI_ANY_ID, PCI_ANY_ID },131131+ { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC949ES,132132+ PCI_ANY_ID, PCI_ANY_ID },148133 {0} /* Terminating entry */149134};150135MODULE_DEVICE_TABLE(pci, mptfc_pci_table);151136152152-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/153153-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/154154-/*155155- * mptfc_probe - Installs scsi devices per bus.156156- * @pdev: Pointer to pci_dev structure157157- *158158- * Returns 0 for success, non-zero for failure.159159- *137137+static struct scsi_transport_template *mptfc_transport_template = NULL;138138+139139+struct fc_function_template mptfc_transport_functions = {140140+ .dd_fcrport_size = 8,141141+ .show_host_node_name = 1,142142+ .show_host_port_name = 1,143143+ .show_host_supported_classes = 1,144144+ .show_host_port_id = 1,145145+ .show_rport_supported_classes = 1,146146+ .show_starget_node_name = 1,147147+ .show_starget_port_name = 1,148148+ .show_starget_port_id = 1,149149+ .set_rport_dev_loss_tmo = mptfc_set_rport_loss_tmo,150150+ .show_rport_dev_loss_tmo = 1,151151+152152+};153153+154154+/* FIXME! values controlling firmware RESCAN event155155+ * need to be set low to allow dev_loss_tmo to156156+ * work as expected. Currently, firmware doesn't157157+ * notify driver of RESCAN event until some number158158+ * of seconds elapse. This value can be set via159159+ * lsiutil.160160 */161161+static void162162+mptfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout)163163+{164164+ if (timeout > 0)165165+ rport->dev_loss_tmo = timeout;166166+ else167167+ rport->dev_loss_tmo = mptfc_dev_loss_tmo;168168+}169169+170170+static int171171+mptfc_FcDevPage0_cmp_func(const void *a, const void *b)172172+{173173+ FCDevicePage0_t **aa = (FCDevicePage0_t **)a;174174+ FCDevicePage0_t **bb = (FCDevicePage0_t **)b;175175+176176+ if ((*aa)->CurrentBus == (*bb)->CurrentBus) {177177+ if ((*aa)->CurrentTargetID == (*bb)->CurrentTargetID)178178+ return 0;179179+ if ((*aa)->CurrentTargetID < (*bb)->CurrentTargetID)180180+ return -1;181181+ return 1;182182+ }183183+ if ((*aa)->CurrentBus < (*bb)->CurrentBus)184184+ return -1;185185+ return 1;186186+}187187+188188+static int189189+mptfc_GetFcDevPage0(MPT_ADAPTER *ioc, int ioc_port,190190+ void(*func)(MPT_ADAPTER *ioc,int channel, FCDevicePage0_t *arg))191191+{192192+ ConfigPageHeader_t hdr;193193+ CONFIGPARMS cfg;194194+ FCDevicePage0_t *ppage0_alloc, *fc;195195+ dma_addr_t page0_dma;196196+ int data_sz;197197+ int ii;198198+199199+ FCDevicePage0_t *p0_array=NULL, *p_p0;200200+ FCDevicePage0_t **pp0_array=NULL, **p_pp0;201201+202202+ int rc = -ENOMEM;203203+ U32 port_id = 0xffffff;204204+ int num_targ = 0;205205+ int max_bus = ioc->facts.MaxBuses;206206+ int max_targ = ioc->facts.MaxDevices;207207+208208+ if (max_bus == 0 || max_targ == 0)209209+ goto out;210210+211211+ data_sz = sizeof(FCDevicePage0_t) * max_bus * max_targ;212212+ p_p0 = p0_array = kzalloc(data_sz, GFP_KERNEL);213213+ if (!p0_array)214214+ goto out;215215+216216+ data_sz = sizeof(FCDevicePage0_t *) * max_bus * max_targ;217217+ p_pp0 = pp0_array = kzalloc(data_sz, GFP_KERNEL);218218+ if (!pp0_array)219219+ goto out;220220+221221+ do {222222+ /* Get FC Device Page 0 header */223223+ hdr.PageVersion = 0;224224+ hdr.PageLength = 0;225225+ hdr.PageNumber = 0;226226+ hdr.PageType = MPI_CONFIG_PAGETYPE_FC_DEVICE;227227+ cfg.cfghdr.hdr = &hdr;228228+ cfg.physAddr = -1;229229+ cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;230230+ cfg.dir = 0;231231+ cfg.pageAddr = port_id;232232+ cfg.timeout = 0;233233+234234+ if ((rc = mpt_config(ioc, &cfg)) != 0)235235+ break;236236+237237+ if (hdr.PageLength <= 0)238238+ break;239239+240240+ data_sz = hdr.PageLength * 4;241241+ ppage0_alloc = pci_alloc_consistent(ioc->pcidev, data_sz,242242+ &page0_dma);243243+ rc = -ENOMEM;244244+ if (!ppage0_alloc)245245+ break;246246+247247+ cfg.physAddr = page0_dma;248248+ cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;249249+250250+ if ((rc = mpt_config(ioc, &cfg)) == 0) {251251+ ppage0_alloc->PortIdentifier =252252+ le32_to_cpu(ppage0_alloc->PortIdentifier);253253+254254+ ppage0_alloc->WWNN.Low =255255+ le32_to_cpu(ppage0_alloc->WWNN.Low);256256+257257+ ppage0_alloc->WWNN.High =258258+ le32_to_cpu(ppage0_alloc->WWNN.High);259259+260260+ ppage0_alloc->WWPN.Low =261261+ le32_to_cpu(ppage0_alloc->WWPN.Low);262262+263263+ ppage0_alloc->WWPN.High =264264+ le32_to_cpu(ppage0_alloc->WWPN.High);265265+266266+ ppage0_alloc->BBCredit =267267+ le16_to_cpu(ppage0_alloc->BBCredit);268268+269269+ ppage0_alloc->MaxRxFrameSize =270270+ le16_to_cpu(ppage0_alloc->MaxRxFrameSize);271271+272272+ port_id = ppage0_alloc->PortIdentifier;273273+ num_targ++;274274+ *p_p0 = *ppage0_alloc; /* save data */275275+ *p_pp0++ = p_p0++; /* save addr */276276+ }277277+ pci_free_consistent(ioc->pcidev, data_sz,278278+ (u8 *) ppage0_alloc, page0_dma);279279+ if (rc != 0)280280+ break;281281+282282+ } while (port_id <= 0xff0000);283283+284284+ if (num_targ) {285285+ /* sort array */286286+ if (num_targ > 1)287287+ sort (pp0_array, num_targ, sizeof(FCDevicePage0_t *),288288+ mptfc_FcDevPage0_cmp_func, NULL);289289+ /* call caller's func for each targ */290290+ for (ii = 0; ii < num_targ; ii++) {291291+ fc = *(pp0_array+ii);292292+ func(ioc, ioc_port, fc);293293+ }294294+ }295295+296296+ out:297297+ if (pp0_array)298298+ kfree(pp0_array);299299+ if (p0_array)300300+ kfree(p0_array);301301+ return rc;302302+}303303+304304+static int305305+mptfc_generate_rport_ids(FCDevicePage0_t *pg0, struct fc_rport_identifiers *rid)306306+{307307+ /* not currently usable */308308+ if (pg0->Flags & (MPI_FC_DEVICE_PAGE0_FLAGS_PLOGI_INVALID |309309+ MPI_FC_DEVICE_PAGE0_FLAGS_PRLI_INVALID))310310+ return -1;311311+312312+ if (!(pg0->Flags & MPI_FC_DEVICE_PAGE0_FLAGS_TARGETID_BUS_VALID))313313+ return -1;314314+315315+ if (!(pg0->Protocol & MPI_FC_DEVICE_PAGE0_PROT_FCP_TARGET))316316+ return -1;317317+318318+ /*319319+ * board data structure already normalized to platform endianness320320+ * shifted to avoid unaligned access on 64 bit architecture321321+ */322322+ rid->node_name = ((u64)pg0->WWNN.High) << 32 | (u64)pg0->WWNN.Low;323323+ rid->port_name = ((u64)pg0->WWPN.High) << 32 | (u64)pg0->WWPN.Low;324324+ rid->port_id = pg0->PortIdentifier;325325+ rid->roles = FC_RPORT_ROLE_UNKNOWN;326326+ rid->roles |= FC_RPORT_ROLE_FCP_TARGET;327327+ if (pg0->Protocol & MPI_FC_DEVICE_PAGE0_PROT_FCP_INITIATOR)328328+ rid->roles |= FC_RPORT_ROLE_FCP_INITIATOR;329329+330330+ return 0;331331+}332332+333333+static void334334+mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0)335335+{336336+ struct fc_rport_identifiers rport_ids;337337+ struct fc_rport *rport;338338+ struct mptfc_rport_info *ri;339339+ int match = 0;340340+ u64 port_name;341341+ unsigned long flags;342342+343343+ if (mptfc_generate_rport_ids(pg0, &rport_ids) < 0)344344+ return;345345+346346+ /* scan list looking for a match */347347+ spin_lock_irqsave(&ioc->fc_rport_lock, flags);348348+ list_for_each_entry(ri, &ioc->fc_rports, list) {349349+ port_name = (u64)ri->pg0.WWPN.High << 32 | (u64)ri->pg0.WWPN.Low;350350+ if (port_name == rport_ids.port_name) { /* match */351351+ list_move_tail(&ri->list, &ioc->fc_rports);352352+ match = 1;353353+ break;354354+ }355355+ }356356+ if (!match) { /* allocate one */357357+ spin_unlock_irqrestore(&ioc->fc_rport_lock, flags);358358+ ri = kzalloc(sizeof(struct mptfc_rport_info), GFP_KERNEL);359359+ if (!ri)360360+ return;361361+ spin_lock_irqsave(&ioc->fc_rport_lock, flags);362362+ list_add_tail(&ri->list, &ioc->fc_rports);363363+ }364364+365365+ ri->pg0 = *pg0; /* add/update pg0 data */366366+ ri->flags &= ~MPT_RPORT_INFO_FLAGS_MISSING;367367+368368+ if (!(ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED)) {369369+ ri->flags |= MPT_RPORT_INFO_FLAGS_REGISTERED;370370+ spin_unlock_irqrestore(&ioc->fc_rport_lock, flags);371371+ rport = fc_remote_port_add(ioc->sh,channel, &rport_ids);372372+ spin_lock_irqsave(&ioc->fc_rport_lock, flags);373373+ if (rport) {374374+ if (*((struct mptfc_rport_info **)rport->dd_data) != ri) {375375+ ri->flags &= ~MPT_RPORT_INFO_FLAGS_MAPPED_VDEV;376376+ ri->vdev = NULL;377377+ ri->rport = rport;378378+ *((struct mptfc_rport_info **)rport->dd_data) = ri;379379+ }380380+ rport->dev_loss_tmo = mptfc_dev_loss_tmo;381381+ /*382382+ * if already mapped, remap here. If not mapped,383383+ * slave_alloc will allocate vdev and map384384+ */385385+ if (ri->flags & MPT_RPORT_INFO_FLAGS_MAPPED_VDEV) {386386+ ri->vdev->target_id = ri->pg0.CurrentTargetID;387387+ ri->vdev->bus_id = ri->pg0.CurrentBus;388388+ ri->vdev->vtarget->target_id = ri->vdev->target_id;389389+ ri->vdev->vtarget->bus_id = ri->vdev->bus_id;390390+ }391391+ #ifdef MPT_DEBUG392392+ printk ("mptfc_reg_dev.%d: %x, %llx / %llx, tid %d, "393393+ "rport tid %d, tmo %d\n",394394+ ioc->sh->host_no,395395+ pg0->PortIdentifier,396396+ pg0->WWNN,397397+ pg0->WWPN,398398+ pg0->CurrentTargetID,399399+ ri->rport->scsi_target_id,400400+ ri->rport->dev_loss_tmo);401401+ #endif402402+ } else {403403+ list_del(&ri->list);404404+ kfree(ri);405405+ ri = NULL;406406+ }407407+ }408408+ spin_unlock_irqrestore(&ioc->fc_rport_lock,flags);409409+410410+}411411+412412+/*413413+ * OS entry point to allow host driver to alloc memory414414+ * for each scsi device. Called once per device the bus scan.415415+ * Return non-zero if allocation fails.416416+ * Init memory once per LUN.417417+ */418418+int419419+mptfc_slave_alloc(struct scsi_device *sdev)420420+{421421+ MPT_SCSI_HOST *hd;422422+ VirtTarget *vtarget;423423+ VirtDevice *vdev;424424+ struct scsi_target *starget;425425+ struct fc_rport *rport;426426+ struct mptfc_rport_info *ri;427427+ unsigned long flags;428428+429429+430430+ rport = starget_to_rport(scsi_target(sdev));431431+432432+ if (!rport || fc_remote_port_chkready(rport))433433+ return -ENXIO;434434+435435+ hd = (MPT_SCSI_HOST *)sdev->host->hostdata;436436+437437+ vdev = kmalloc(sizeof(VirtDevice), GFP_KERNEL);438438+ if (!vdev) {439439+ printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",440440+ hd->ioc->name, sizeof(VirtDevice));441441+ return -ENOMEM;442442+ }443443+ memset(vdev, 0, sizeof(VirtDevice));444444+445445+ spin_lock_irqsave(&hd->ioc->fc_rport_lock,flags);446446+447447+ if (!(ri = *((struct mptfc_rport_info **)rport->dd_data))) {448448+ spin_unlock_irqrestore(&hd->ioc->fc_rport_lock,flags);449449+ kfree(vdev);450450+ return -ENODEV;451451+ }452452+453453+ sdev->hostdata = vdev;454454+ starget = scsi_target(sdev);455455+ vtarget = starget->hostdata;456456+ if (vtarget->num_luns == 0) {457457+ vtarget->tflags = MPT_TARGET_FLAGS_Q_YES |458458+ MPT_TARGET_FLAGS_VALID_INQUIRY;459459+ hd->Targets[sdev->id] = vtarget;460460+ }461461+462462+ vtarget->target_id = vdev->target_id;463463+ vtarget->bus_id = vdev->bus_id;464464+465465+ vdev->vtarget = vtarget;466466+ vdev->ioc_id = hd->ioc->id;467467+ vdev->lun = sdev->lun;468468+ vdev->target_id = ri->pg0.CurrentTargetID;469469+ vdev->bus_id = ri->pg0.CurrentBus;470470+471471+ ri->flags |= MPT_RPORT_INFO_FLAGS_MAPPED_VDEV;472472+ ri->vdev = vdev;473473+474474+ spin_unlock_irqrestore(&hd->ioc->fc_rport_lock,flags);475475+476476+ vtarget->num_luns++;477477+478478+#ifdef MPT_DEBUG479479+ printk ("mptfc_slv_alloc.%d: num_luns %d, sdev.id %d, "480480+ "CurrentTargetID %d, %x %llx %llx\n",481481+ sdev->host->host_no,482482+ vtarget->num_luns,483483+ sdev->id, ri->pg0.CurrentTargetID,484484+ ri->pg0.PortIdentifier, ri->pg0.WWPN, ri->pg0.WWNN);485485+#endif486486+487487+ return 0;488488+}489489+490490+static int491491+mptfc_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))492492+{493493+ struct fc_rport *rport = starget_to_rport(scsi_target(SCpnt->device));494494+ int err;495495+496496+ err = fc_remote_port_chkready(rport);497497+ if (unlikely(err)) {498498+ SCpnt->result = err;499499+ done(SCpnt);500500+ return 0;501501+ }502502+ return mptscsih_qcmd(SCpnt,done);503503+}504504+505505+static void506506+mptfc_init_host_attr(MPT_ADAPTER *ioc,int portnum)507507+{508508+ unsigned class = 0, cos = 0;509509+510510+ /* don't know what to do as only one scsi (fc) host was allocated */511511+ if (portnum != 0)512512+ return;513513+514514+ class = ioc->fc_port_page0[portnum].SupportedServiceClass;515515+ if (class & MPI_FCPORTPAGE0_SUPPORT_CLASS_1)516516+ cos |= FC_COS_CLASS1;517517+ if (class & MPI_FCPORTPAGE0_SUPPORT_CLASS_2)518518+ cos |= FC_COS_CLASS2;519519+ if (class & MPI_FCPORTPAGE0_SUPPORT_CLASS_3)520520+ cos |= FC_COS_CLASS3;521521+522522+ fc_host_node_name(ioc->sh) =523523+ (u64)ioc->fc_port_page0[portnum].WWNN.High << 32524524+ | (u64)ioc->fc_port_page0[portnum].WWNN.Low;525525+526526+ fc_host_port_name(ioc->sh) =527527+ (u64)ioc->fc_port_page0[portnum].WWPN.High << 32528528+ | (u64)ioc->fc_port_page0[portnum].WWPN.Low;529529+530530+ fc_host_port_id(ioc->sh) = ioc->fc_port_page0[portnum].PortIdentifier;531531+532532+ fc_host_supported_classes(ioc->sh) = cos;533533+534534+ fc_host_tgtid_bind_type(ioc->sh) = FC_TGTID_BIND_BY_WWPN;535535+}536536+537537+static void538538+mptfc_rescan_devices(void *arg)539539+{540540+ MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg;541541+ int ii;542542+ int work_to_do;543543+ unsigned long flags;544544+ struct mptfc_rport_info *ri;545545+546546+ do {547547+ /* start by tagging all ports as missing */548548+ spin_lock_irqsave(&ioc->fc_rport_lock,flags);549549+ list_for_each_entry(ri, &ioc->fc_rports, list) {550550+ if (ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED) {551551+ ri->flags |= MPT_RPORT_INFO_FLAGS_MISSING;552552+ }553553+ }554554+ spin_unlock_irqrestore(&ioc->fc_rport_lock,flags);555555+556556+ /*557557+ * now rescan devices known to adapter,558558+ * will reregister existing rports559559+ */560560+ for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {561561+ (void) mptbase_GetFcPortPage0(ioc, ii);562562+ mptfc_init_host_attr(ioc,ii); /* refresh */563563+ mptfc_GetFcDevPage0(ioc,ii,mptfc_register_dev);564564+ }565565+566566+ /* delete devices still missing */567567+ spin_lock_irqsave(&ioc->fc_rport_lock, flags);568568+ list_for_each_entry(ri, &ioc->fc_rports, list) {569569+ /* if newly missing, delete it */570570+ if ((ri->flags & (MPT_RPORT_INFO_FLAGS_REGISTERED |571571+ MPT_RPORT_INFO_FLAGS_MISSING))572572+ == (MPT_RPORT_INFO_FLAGS_REGISTERED |573573+ MPT_RPORT_INFO_FLAGS_MISSING)) {574574+575575+ ri->flags &= ~(MPT_RPORT_INFO_FLAGS_REGISTERED|576576+ MPT_RPORT_INFO_FLAGS_MISSING);577577+ fc_remote_port_delete(ri->rport);578578+ /*579579+ * remote port not really deleted 'cause580580+ * binding is by WWPN and driver only581581+ * registers FCP_TARGETs582582+ */583583+ #ifdef MPT_DEBUG584584+ printk ("mptfc_rescan.%d: %llx deleted\n",585585+ ioc->sh->host_no, ri->pg0.WWPN);586586+ #endif587587+ }588588+ }589589+ spin_unlock_irqrestore(&ioc->fc_rport_lock,flags);590590+591591+ /*592592+ * allow multiple passes as target state593593+ * might have changed during scan594594+ */595595+ spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);596596+ if (ioc->fc_rescan_work_count > 2) /* only need one more */597597+ ioc->fc_rescan_work_count = 2;598598+ work_to_do = --ioc->fc_rescan_work_count;599599+ spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);600600+ } while (work_to_do);601601+}602602+161603static int162604mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)163605{···624148 MPT_SCSI_HOST *hd;625149 MPT_ADAPTER *ioc;626150 unsigned long flags;627627- int sz, ii;151151+ int ii;628152 int numSGE = 0;629153 int scale;630154 int ioc_cap;631631- u8 *mem;632155 int error=0;633156 int r;634634-157157+635158 if ((r = mpt_attach(pdev,id)) != 0)636159 return r;637637-160160+638161 ioc = pci_get_drvdata(pdev);639162 ioc->DoneCtx = mptfcDoneCtx;640163 ioc->TaskCtx = mptfcTaskCtx;···669194 printk(MYIOC_s_WARN_FMT670195 "Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n",671196 ioc->name, ioc);672672- return 0;197197+ return -ENODEV;673198 }674199675200 sh = scsi_host_alloc(&mptfc_driver_template, sizeof(MPT_SCSI_HOST));···681206 error = -1;682207 goto out_mptfc_probe;683208 }209209+210210+ INIT_WORK(&ioc->fc_rescan_work, mptfc_rescan_devices,(void *)ioc);684211685212 spin_lock_irqsave(&ioc->FreeQlock, flags);686213···745268 /* SCSI needs scsi_cmnd lookup table!746269 * (with size equal to req_depth*PtrSz!)747270 */748748- sz = ioc->req_depth * sizeof(void *);749749- mem = kmalloc(sz, GFP_ATOMIC);750750- if (mem == NULL) {271271+ hd->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_ATOMIC);272272+ if (!hd->ScsiLookup) {751273 error = -ENOMEM;752274 goto out_mptfc_probe;753275 }754276755755- memset(mem, 0, sz);756756- hd->ScsiLookup = (struct scsi_cmnd **) mem;757757-758758- dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p, sz=%d\n",759759- ioc->name, hd->ScsiLookup, sz));277277+ dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p\n",278278+ ioc->name, hd->ScsiLookup));760279761280 /* Allocate memory for the device structures.762281 * A non-Null pointer at an offset763282 * indicates a device exists.764283 * max_id = 1 + maximum id (hosts.h)765284 */766766- sz = sh->max_id * sizeof(void *);767767- mem = kmalloc(sz, GFP_ATOMIC);768768- if (mem == NULL) {285285+ hd->Targets = kcalloc(sh->max_id, sizeof(void *), GFP_ATOMIC);286286+ if (!hd->Targets) {769287 error = -ENOMEM;770288 goto out_mptfc_probe;771289 }772290773773- memset(mem, 0, sz);774774- hd->Targets = (VirtTarget **) mem;775775-776776- dprintk((KERN_INFO777777- " vdev @ %p, sz=%d\n", hd->Targets, sz));291291+ dprintk((KERN_INFO " vdev @ %p\n", hd->Targets));778292779293 /* Clear the TM flags780294 */···800332 hd->scandv_wait_done = 0;801333 hd->last_queue_full = 0;802334335335+ sh->transportt = mptfc_transport_template;803336 error = scsi_add_host (sh, &ioc->pcidev->dev);804337 if(error) {805338 dprintk((KERN_ERR MYNAM···808339 goto out_mptfc_probe;809340 }810341811811- scsi_scan_host(sh);342342+ for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {343343+ mptfc_init_host_attr(ioc,ii);344344+ mptfc_GetFcDevPage0(ioc,ii,mptfc_register_dev);345345+ }346346+812347 return 0;813348814349out_mptfc_probe:···825352 .name = "mptfc",826353 .id_table = mptfc_pci_table,827354 .probe = mptfc_probe,828828- .remove = __devexit_p(mptscsih_remove),355355+ .remove = __devexit_p(mptfc_remove),829356 .shutdown = mptscsih_shutdown,830357#ifdef CONFIG_PM831358 .suspend = mptscsih_suspend,···843370static int __init844371mptfc_init(void)845372{373373+ int error;846374847375 show_mptmod_ver(my_NAME, my_VERSION);376376+377377+ /* sanity check module parameter */378378+ if (mptfc_dev_loss_tmo == 0)379379+ mptfc_dev_loss_tmo = MPTFC_DEV_LOSS_TMO;380380+381381+ mptfc_transport_template =382382+ fc_attach_transport(&mptfc_transport_functions);383383+384384+ if (!mptfc_transport_template)385385+ return -ENODEV;848386849387 mptfcDoneCtx = mpt_register(mptscsih_io_done, MPTFC_DRIVER);850388 mptfcTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTFC_DRIVER);···871387 ": Registered for IOC reset notifications\n"));872388 }873389874874- return pci_register_driver(&mptfc_driver);390390+ error = pci_register_driver(&mptfc_driver);391391+ if (error) {392392+ fc_release_transport(mptfc_transport_template);393393+ }394394+395395+ return error;396396+}397397+398398+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/399399+/**400400+ * mptfc_remove - Removed fc infrastructure for devices401401+ * @pdev: Pointer to pci_dev structure402402+ *403403+ */404404+static void __devexit mptfc_remove(struct pci_dev *pdev)405405+{406406+ MPT_ADAPTER *ioc = pci_get_drvdata(pdev);407407+ struct mptfc_rport_info *p, *n;408408+409409+ fc_remove_host(ioc->sh);410410+411411+ list_for_each_entry_safe(p, n, &ioc->fc_rports, list) {412412+ list_del(&p->list);413413+ kfree(p);414414+ }415415+416416+ mptscsih_remove(pdev);875417}876418877419/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/···910400mptfc_exit(void)911401{912402 pci_unregister_driver(&mptfc_driver);913913-403403+ fc_release_transport(mptfc_transport_template);404404+914405 mpt_reset_deregister(mptfcDoneCtx);915406 dprintk((KERN_INFO MYNAM916407 ": Deregistered for IOC reset notifications\n"));
+5-9
drivers/message/fusion/mptlan.c
···411411 goto out;412412 priv->mpt_txfidx_tail = -1;413413414414- priv->SendCtl = kmalloc(priv->tx_max_out * sizeof(struct BufferControl),414414+ priv->SendCtl = kcalloc(priv->tx_max_out, sizeof(struct BufferControl),415415 GFP_KERNEL);416416 if (priv->SendCtl == NULL)417417 goto out_mpt_txfidx;418418- for (i = 0; i < priv->tx_max_out; i++) {419419- memset(&priv->SendCtl[i], 0, sizeof(struct BufferControl));418418+ for (i = 0; i < priv->tx_max_out; i++)420419 priv->mpt_txfidx[++priv->mpt_txfidx_tail] = i;421421- }422420423421 dlprintk((KERN_INFO MYNAM "@lo: Finished initializing SendCtl\n"));424422···426428 goto out_SendCtl;427429 priv->mpt_rxfidx_tail = -1;428430429429- priv->RcvCtl = kmalloc(priv->max_buckets_out *430430- sizeof(struct BufferControl),431431+ priv->RcvCtl = kcalloc(priv->max_buckets_out,432432+ sizeof(struct BufferControl),431433 GFP_KERNEL);432434 if (priv->RcvCtl == NULL)433435 goto out_mpt_rxfidx;434434- for (i = 0; i < priv->max_buckets_out; i++) {435435- memset(&priv->RcvCtl[i], 0, sizeof(struct BufferControl));436436+ for (i = 0; i < priv->max_buckets_out; i++)436437 priv->mpt_rxfidx[++priv->mpt_rxfidx_tail] = i;437437- }438438439439/**/ dlprintk((KERN_INFO MYNAM "/lo: txfidx contains - "));440440/**/ for (i = 0; i < priv->tx_max_out; i++)
+346-58
drivers/message/fusion/mptsas.c
···55 *66 * Copyright (c) 1999-2005 LSI Logic Corporation77 * (mailto:mpt_linux_developer@lsil.com)88- * Copyright (c) 2005 Dell88+ * Copyright (c) 2005-2006 Dell99 */1010/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/1111/*···8686static int mptsasMgmtCtx = -1;878788888989+enum mptsas_hotplug_action {9090+ MPTSAS_ADD_DEVICE,9191+ MPTSAS_DEL_DEVICE,9292+};9393+9494+struct mptsas_hotplug_event {9595+ struct work_struct work;9696+ MPT_ADAPTER *ioc;9797+ enum mptsas_hotplug_action event_type;9898+ u64 sas_address;9999+ u32 channel;100100+ u32 id;101101+ u32 device_info;102102+ u16 handle;103103+ u16 parent_handle;104104+ u8 phy_id;105105+};106106+89107/*90108 * SAS topology structures91109 *···11799 u8 phy_id; /* phy number of parent device */118100 u8 port_id; /* sas physical port this device119101 is assoc'd with */120120- u8 target; /* logical target id of this device */121121- u8 bus; /* logical bus number of this device */102102+ u8 id; /* logical target id of this device */103103+ u8 channel; /* logical bus number of this device */122104 u64 sas_address; /* WWN of this device,123105 SATA is assigned by HBA,expander */124106 u32 device_info; /* bitfield detailed info about this device */···132114 u8 programmed_link_rate; /* programmed max/min phy link rate */133115 struct mptsas_devinfo identify; /* point to phy device info */134116 struct mptsas_devinfo attached; /* point to attached device info */117117+ struct sas_phy *phy;135118 struct sas_rphy *rphy;136119};137120···258239 struct scsi_target *starget;259240 int i;260241261261- vdev = kmalloc(sizeof(VirtDevice), GFP_KERNEL);242242+ vdev = kzalloc(sizeof(VirtDevice), GFP_KERNEL);262243 if (!vdev) {263244 printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",264245 hd->ioc->name, sizeof(VirtDevice));265246 return -ENOMEM;266247 }267267- memset(vdev, 0, sizeof(VirtDevice));268248 vdev->ioc_id = hd->ioc->id;269249 sdev->hostdata = vdev;270250 starget = scsi_target(sdev);···274256 hd->Targets[sdev->id] = vtarget;275257 }276258259259+ /*260260+ RAID volumes placed beyond the last expected port.261261+ */262262+ if (sdev->channel == hd->ioc->num_ports) {263263+ vdev->target_id = sdev->id;264264+ vdev->bus_id = 0;265265+ vdev->lun = 0;266266+ goto out;267267+ }268268+277269 rphy = dev_to_rphy(sdev->sdev_target->dev.parent);270270+ mutex_lock(&hd->ioc->sas_topology_mutex);278271 list_for_each_entry(p, &hd->ioc->sas_topology, list) {279272 for (i = 0; i < p->num_phys; i++) {280273 if (p->phy_info[i].attached.sas_address ==281274 rphy->identify.sas_address) {282275 vdev->target_id =283283- p->phy_info[i].attached.target;284284- vdev->bus_id = p->phy_info[i].attached.bus;276276+ p->phy_info[i].attached.id;277277+ vdev->bus_id = p->phy_info[i].attached.channel;285278 vdev->lun = sdev->lun;279279+ mutex_unlock(&hd->ioc->sas_topology_mutex);286280 goto out;287281 }288282 }289283 }284284+ mutex_unlock(&hd->ioc->sas_topology_mutex);290285291286 printk("No matching SAS device found!!\n");292287 kfree(vdev);···313282 return 0;314283}315284285285+static void286286+mptsas_slave_destroy(struct scsi_device *sdev)287287+{288288+ struct Scsi_Host *host = sdev->host;289289+ MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;290290+ struct sas_rphy *rphy;291291+ struct mptsas_portinfo *p;292292+ int i;293293+294294+ /*295295+ * Handle hotplug removal case.296296+ * We need to clear out attached data structure.297297+ */298298+ rphy = dev_to_rphy(sdev->sdev_target->dev.parent);299299+300300+ mutex_lock(&hd->ioc->sas_topology_mutex);301301+ list_for_each_entry(p, &hd->ioc->sas_topology, list) {302302+ for (i = 0; i < p->num_phys; i++) {303303+ if (p->phy_info[i].attached.sas_address ==304304+ rphy->identify.sas_address) {305305+ memset(&p->phy_info[i].attached, 0,306306+ sizeof(struct mptsas_devinfo));307307+ p->phy_info[i].rphy = NULL;308308+ goto out;309309+ }310310+ }311311+ }312312+313313+ out:314314+ mutex_unlock(&hd->ioc->sas_topology_mutex);315315+ /*316316+ * TODO: Issue target reset to flush firmware outstanding commands.317317+ */318318+ mptscsih_slave_destroy(sdev);319319+}320320+316321static struct scsi_host_template mptsas_driver_template = {317322 .module = THIS_MODULE,318323 .proc_name = "mptsas",···360293 .slave_alloc = mptsas_slave_alloc,361294 .slave_configure = mptscsih_slave_configure,362295 .target_destroy = mptscsih_target_destroy,363363- .slave_destroy = mptscsih_slave_destroy,296296+ .slave_destroy = mptsas_slave_destroy,364297 .change_queue_depth = mptscsih_change_queue_depth,365298 .eh_abort_handler = mptscsih_abort,366299 .eh_device_reset_handler = mptscsih_dev_reset,···466399 if (phy->identify.target_port_protocols & SAS_PROTOCOL_SMP)467400 return -ENXIO;468401469469- if (down_interruptible(&ioc->sas_mgmt.mutex))402402+ if (mutex_lock_interruptible(&ioc->sas_mgmt.mutex))470403 goto out;471404472405 mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);···517450 error = 0;518451519452 out_unlock:520520- up(&ioc->sas_mgmt.mutex);453453+ mutex_unlock(&ioc->sas_mgmt.mutex);521454 out:522455 return error;523456}···716649 device_info->handle = le16_to_cpu(buffer->DevHandle);717650 device_info->phy_id = buffer->PhyNum;718651 device_info->port_id = buffer->PhysicalPort;719719- device_info->target = buffer->TargetID;720720- device_info->bus = buffer->Bus;652652+ device_info->id = buffer->TargetID;653653+ device_info->channel = buffer->Bus;721654 memcpy(&sas_address, &buffer->SASAddress, sizeof(__le64));722655 device_info->sas_address = le64_to_cpu(sas_address);723656 device_info->device_info =···925858static int mptsas_probe_one_phy(struct device *dev,926859 struct mptsas_phyinfo *phy_info, int index, int local)927860{928928- struct sas_phy *port;861861+ struct sas_phy *phy;929862 int error;930863931931- port = sas_phy_alloc(dev, index);932932- if (!port)864864+ phy = sas_phy_alloc(dev, index);865865+ if (!phy)933866 return -ENOMEM;934867935935- port->port_identifier = phy_info->port_id;936936- mptsas_parse_device_info(&port->identify, &phy_info->identify);868868+ phy->port_identifier = phy_info->port_id;869869+ mptsas_parse_device_info(&phy->identify, &phy_info->identify);937870938871 /*939872 * Set Negotiated link rate.940873 */941874 switch (phy_info->negotiated_link_rate) {942875 case MPI_SAS_IOUNIT0_RATE_PHY_DISABLED:943943- port->negotiated_linkrate = SAS_PHY_DISABLED;876876+ phy->negotiated_linkrate = SAS_PHY_DISABLED;944877 break;945878 case MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION:946946- port->negotiated_linkrate = SAS_LINK_RATE_FAILED;879879+ phy->negotiated_linkrate = SAS_LINK_RATE_FAILED;947880 break;948881 case MPI_SAS_IOUNIT0_RATE_1_5:949949- port->negotiated_linkrate = SAS_LINK_RATE_1_5_GBPS;882882+ phy->negotiated_linkrate = SAS_LINK_RATE_1_5_GBPS;950883 break;951884 case MPI_SAS_IOUNIT0_RATE_3_0:952952- port->negotiated_linkrate = SAS_LINK_RATE_3_0_GBPS;885885+ phy->negotiated_linkrate = SAS_LINK_RATE_3_0_GBPS;953886 break;954887 case MPI_SAS_IOUNIT0_RATE_SATA_OOB_COMPLETE:955888 case MPI_SAS_IOUNIT0_RATE_UNKNOWN:956889 default:957957- port->negotiated_linkrate = SAS_LINK_RATE_UNKNOWN;890890+ phy->negotiated_linkrate = SAS_LINK_RATE_UNKNOWN;958891 break;959892 }960893···963896 */964897 switch (phy_info->hw_link_rate & MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {965898 case MPI_SAS_PHY0_HWRATE_MAX_RATE_1_5:966966- port->maximum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;899899+ phy->maximum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;967900 break;968901 case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:969969- port->maximum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;902902+ phy->maximum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;970903 break;971904 default:972905 break;···978911 switch (phy_info->programmed_link_rate &979912 MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {980913 case MPI_SAS_PHY0_PRATE_MAX_RATE_1_5:981981- port->maximum_linkrate = SAS_LINK_RATE_1_5_GBPS;914914+ phy->maximum_linkrate = SAS_LINK_RATE_1_5_GBPS;982915 break;983916 case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:984984- port->maximum_linkrate = SAS_LINK_RATE_3_0_GBPS;917917+ phy->maximum_linkrate = SAS_LINK_RATE_3_0_GBPS;985918 break;986919 default:987920 break;···992925 */993926 switch (phy_info->hw_link_rate & MPI_SAS_PHY0_HWRATE_MIN_RATE_MASK) {994927 case MPI_SAS_PHY0_HWRATE_MIN_RATE_1_5:995995- port->minimum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;928928+ phy->minimum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;996929 break;997930 case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:998998- port->minimum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;931931+ phy->minimum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;999932 break;1000933 default:1001934 break;···1007940 switch (phy_info->programmed_link_rate &1008941 MPI_SAS_PHY0_PRATE_MIN_RATE_MASK) {1009942 case MPI_SAS_PHY0_PRATE_MIN_RATE_1_5:10101010- port->minimum_linkrate = SAS_LINK_RATE_1_5_GBPS;943943+ phy->minimum_linkrate = SAS_LINK_RATE_1_5_GBPS;1011944 break;1012945 case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:10131013- port->minimum_linkrate = SAS_LINK_RATE_3_0_GBPS;946946+ phy->minimum_linkrate = SAS_LINK_RATE_3_0_GBPS;1014947 break;1015948 default:1016949 break;1017950 }10189511019952 if (local)10201020- port->local_attached = 1;953953+ phy->local_attached = 1;102195410221022- error = sas_phy_add(port);955955+ error = sas_phy_add(phy);1023956 if (error) {10241024- sas_phy_free(port);957957+ sas_phy_free(phy);1025958 return error;1026959 }960960+ phy_info->phy = phy;10279611028962 if (phy_info->attached.handle) {1029963 struct sas_rphy *rphy;103096410311031- rphy = sas_rphy_alloc(port);965965+ rphy = sas_rphy_alloc(phy);1032966 if (!rphy)1033967 return 0; /* non-fatal: an rphy can be added later */1034968···1053985 u32 handle = 0xFFFF;1054986 int error = -ENOMEM, i;105598710561056- port_info = kmalloc(sizeof(*port_info), GFP_KERNEL);988988+ port_info = kzalloc(sizeof(*port_info), GFP_KERNEL);1057989 if (!port_info)1058990 goto out;10591059- memset(port_info, 0, sizeof(*port_info));10609911061992 error = mptsas_sas_io_unit_pg0(ioc, port_info);1062993 if (error)1063994 goto out_free_port_info;1064995996996+ ioc->num_ports = port_info->num_phys;997997+ mutex_lock(&ioc->sas_topology_mutex);1065998 list_add_tail(&port_info->list, &ioc->sas_topology);999999+ mutex_unlock(&ioc->sas_topology_mutex);10001000+10661001 for (i = 0; i < port_info->num_phys; i++) {10671002 mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i],10681003 (MPI_SAS_PHY_PGAD_FORM_PHY_NUMBER <<···11051034 struct mptsas_portinfo *port_info, *p;11061035 int error = -ENOMEM, i, j;1107103611081108- port_info = kmalloc(sizeof(*port_info), GFP_KERNEL);10371037+ port_info = kzalloc(sizeof(*port_info), GFP_KERNEL);11091038 if (!port_info)11101039 goto out;11111111- memset(port_info, 0, sizeof(*port_info));1112104011131041 error = mptsas_sas_expander_pg0(ioc, port_info,11141042 (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE <<···1117104711181048 *handle = port_info->handle;1119104910501050+ mutex_lock(&ioc->sas_topology_mutex);11201051 list_add_tail(&port_info->list, &ioc->sas_topology);10521052+ mutex_unlock(&ioc->sas_topology_mutex);10531053+11211054 for (i = 0; i < port_info->num_phys; i++) {11221055 struct device *parent;11231056···11521079 * HBA phys.11531080 */11541081 parent = &ioc->sh->shost_gendev;10821082+ mutex_lock(&ioc->sas_topology_mutex);11551083 list_for_each_entry(p, &ioc->sas_topology, list) {11561084 for (j = 0; j < p->num_phys; j++) {11571085 if (port_info->phy_info[i].identify.handle ==···11601086 parent = &p->phy_info[j].rphy->dev;11611087 }11621088 }10891089+ mutex_unlock(&ioc->sas_topology_mutex);1163109011641091 mptsas_probe_one_phy(parent, &port_info->phy_info[i],11651092 *index, 0);···11861111 ;11871112}1188111311141114+static struct mptsas_phyinfo *11151115+mptsas_find_phyinfo_by_parent(MPT_ADAPTER *ioc, u16 parent_handle, u8 phy_id)11161116+{11171117+ struct mptsas_portinfo *port_info;11181118+ struct mptsas_devinfo device_info;11191119+ struct mptsas_phyinfo *phy_info = NULL;11201120+ int i, error;11211121+11221122+ /*11231123+ * Retrieve the parent sas_address11241124+ */11251125+ error = mptsas_sas_device_pg0(ioc, &device_info,11261126+ (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<11271127+ MPI_SAS_DEVICE_PGAD_FORM_SHIFT),11281128+ parent_handle);11291129+ if (error) {11301130+ printk("mptsas: failed to retrieve device page\n");11311131+ return NULL;11321132+ }11331133+11341134+ /*11351135+ * The phy_info structures are never deallocated during lifetime of11361136+ * a host, so the code below is safe without additional refcounting.11371137+ */11381138+ mutex_lock(&ioc->sas_topology_mutex);11391139+ list_for_each_entry(port_info, &ioc->sas_topology, list) {11401140+ for (i = 0; i < port_info->num_phys; i++) {11411141+ if (port_info->phy_info[i].identify.sas_address ==11421142+ device_info.sas_address &&11431143+ port_info->phy_info[i].phy_id == phy_id) {11441144+ phy_info = &port_info->phy_info[i];11451145+ break;11461146+ }11471147+ }11481148+ }11491149+ mutex_unlock(&ioc->sas_topology_mutex);11501150+11511151+ return phy_info;11521152+}11531153+11541154+static struct mptsas_phyinfo *11551155+mptsas_find_phyinfo_by_handle(MPT_ADAPTER *ioc, u16 handle)11561156+{11571157+ struct mptsas_portinfo *port_info;11581158+ struct mptsas_phyinfo *phy_info = NULL;11591159+ int i;11601160+11611161+ /*11621162+ * The phy_info structures are never deallocated during lifetime of11631163+ * a host, so the code below is safe without additional refcounting.11641164+ */11651165+ mutex_lock(&ioc->sas_topology_mutex);11661166+ list_for_each_entry(port_info, &ioc->sas_topology, list) {11671167+ for (i = 0; i < port_info->num_phys; i++) {11681168+ if (port_info->phy_info[i].attached.handle == handle) {11691169+ phy_info = &port_info->phy_info[i];11701170+ break;11711171+ }11721172+ }11731173+ }11741174+ mutex_unlock(&ioc->sas_topology_mutex);11751175+11761176+ return phy_info;11771177+}11781178+11791179+static void11801180+mptsas_hotplug_work(void *arg)11811181+{11821182+ struct mptsas_hotplug_event *ev = arg;11831183+ MPT_ADAPTER *ioc = ev->ioc;11841184+ struct mptsas_phyinfo *phy_info;11851185+ struct sas_rphy *rphy;11861186+ char *ds = NULL;11871187+11881188+ if (ev->device_info & MPI_SAS_DEVICE_INFO_SSP_TARGET)11891189+ ds = "ssp";11901190+ if (ev->device_info & MPI_SAS_DEVICE_INFO_STP_TARGET)11911191+ ds = "stp";11921192+ if (ev->device_info & MPI_SAS_DEVICE_INFO_SATA_DEVICE)11931193+ ds = "sata";11941194+11951195+ switch (ev->event_type) {11961196+ case MPTSAS_DEL_DEVICE:11971197+ printk(MYIOC_s_INFO_FMT11981198+ "removing %s device, channel %d, id %d, phy %d\n",11991199+ ioc->name, ds, ev->channel, ev->id, ev->phy_id);12001200+12011201+ phy_info = mptsas_find_phyinfo_by_handle(ioc, ev->handle);12021202+ if (!phy_info) {12031203+ printk("mptsas: remove event for non-existant PHY.\n");12041204+ break;12051205+ }12061206+12071207+ if (phy_info->rphy) {12081208+ sas_rphy_delete(phy_info->rphy);12091209+ phy_info->rphy = NULL;12101210+ }12111211+ break;12121212+ case MPTSAS_ADD_DEVICE:12131213+ printk(MYIOC_s_INFO_FMT12141214+ "attaching %s device, channel %d, id %d, phy %d\n",12151215+ ioc->name, ds, ev->channel, ev->id, ev->phy_id);12161216+12171217+ phy_info = mptsas_find_phyinfo_by_parent(ioc,12181218+ ev->parent_handle, ev->phy_id);12191219+ if (!phy_info) {12201220+ printk("mptsas: add event for non-existant PHY.\n");12211221+ break;12221222+ }12231223+12241224+ if (phy_info->rphy) {12251225+ printk("mptsas: trying to add existing device.\n");12261226+ break;12271227+ }12281228+12291229+ /* fill attached info */12301230+ phy_info->attached.handle = ev->handle;12311231+ phy_info->attached.phy_id = ev->phy_id;12321232+ phy_info->attached.port_id = phy_info->identify.port_id;12331233+ phy_info->attached.id = ev->id;12341234+ phy_info->attached.channel = ev->channel;12351235+ phy_info->attached.sas_address = ev->sas_address;12361236+ phy_info->attached.device_info = ev->device_info;12371237+12381238+ rphy = sas_rphy_alloc(phy_info->phy);12391239+ if (!rphy)12401240+ break; /* non-fatal: an rphy can be added later */12411241+12421242+ mptsas_parse_device_info(&rphy->identify, &phy_info->attached);12431243+ if (sas_rphy_add(rphy)) {12441244+ sas_rphy_free(rphy);12451245+ break;12461246+ }12471247+12481248+ phy_info->rphy = rphy;12491249+ break;12501250+ }12511251+12521252+ kfree(ev);12531253+}12541254+12551255+static void12561256+mptscsih_send_sas_event(MPT_ADAPTER *ioc,12571257+ EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data)12581258+{12591259+ struct mptsas_hotplug_event *ev;12601260+ u32 device_info = le32_to_cpu(sas_event_data->DeviceInfo);12611261+ __le64 sas_address;12621262+12631263+ if ((device_info &12641264+ (MPI_SAS_DEVICE_INFO_SSP_TARGET |12651265+ MPI_SAS_DEVICE_INFO_STP_TARGET |12661266+ MPI_SAS_DEVICE_INFO_SATA_DEVICE )) == 0)12671267+ return;12681268+12691269+ if ((sas_event_data->ReasonCode &12701270+ (MPI_EVENT_SAS_DEV_STAT_RC_ADDED |12711271+ MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING)) == 0)12721272+ return;12731273+12741274+ ev = kmalloc(sizeof(*ev), GFP_ATOMIC);12751275+ if (!ev) {12761276+ printk(KERN_WARNING "mptsas: lost hotplug event\n");12771277+ return;12781278+ }12791279+12801280+12811281+ INIT_WORK(&ev->work, mptsas_hotplug_work, ev);12821282+ ev->ioc = ioc;12831283+ ev->handle = le16_to_cpu(sas_event_data->DevHandle);12841284+ ev->parent_handle = le16_to_cpu(sas_event_data->ParentDevHandle);12851285+ ev->channel = sas_event_data->Bus;12861286+ ev->id = sas_event_data->TargetID;12871287+ ev->phy_id = sas_event_data->PhyNum;12881288+ memcpy(&sas_address, &sas_event_data->SASAddress, sizeof(__le64));12891289+ ev->sas_address = le64_to_cpu(sas_address);12901290+ ev->device_info = device_info;12911291+12921292+ if (sas_event_data->ReasonCode & MPI_EVENT_SAS_DEV_STAT_RC_ADDED)12931293+ ev->event_type = MPTSAS_ADD_DEVICE;12941294+ else12951295+ ev->event_type = MPTSAS_DEL_DEVICE;12961296+12971297+ schedule_work(&ev->work);12981298+}12991299+13001300+static int13011301+mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply)13021302+{13031303+ u8 event = le32_to_cpu(reply->Event) & 0xFF;13041304+13051305+ if (!ioc->sh)13061306+ return 1;13071307+13081308+ switch (event) {13091309+ case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:13101310+ mptscsih_send_sas_event(ioc,13111311+ (EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *)reply->Data);13121312+ return 1; /* currently means nothing really */13131313+13141314+ default:13151315+ return mptscsih_event_process(ioc, reply);13161316+ }13171317+}13181318+11891319static int11901320mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)11911321{···13981118 MPT_SCSI_HOST *hd;13991119 MPT_ADAPTER *ioc;14001120 unsigned long flags;14011401- int sz, ii;11211121+ int ii;14021122 int numSGE = 0;14031123 int scale;14041124 int ioc_cap;14051405- u8 *mem;14061125 int error=0;14071126 int r;14081127···14821203 sh->unique_id = ioc->id;1483120414841205 INIT_LIST_HEAD(&ioc->sas_topology);14851485- init_MUTEX(&ioc->sas_mgmt.mutex);12061206+ mutex_init(&ioc->sas_topology_mutex);12071207+12081208+ mutex_init(&ioc->sas_mgmt.mutex);14861209 init_completion(&ioc->sas_mgmt.done);1487121014881211 /* Verify that we won't exceed the maximum···15251244 /* SCSI needs scsi_cmnd lookup table!15261245 * (with size equal to req_depth*PtrSz!)15271246 */15281528- sz = ioc->req_depth * sizeof(void *);15291529- mem = kmalloc(sz, GFP_ATOMIC);15301530- if (mem == NULL) {12471247+ hd->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_ATOMIC);12481248+ if (!hd->ScsiLookup) {15311249 error = -ENOMEM;15321250 goto out_mptsas_probe;15331251 }1534125215351535- memset(mem, 0, sz);15361536- hd->ScsiLookup = (struct scsi_cmnd **) mem;15371537-15381538- dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p, sz=%d\n",15391539- ioc->name, hd->ScsiLookup, sz));12531253+ dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p\n",12541254+ ioc->name, hd->ScsiLookup));1540125515411256 /* Allocate memory for the device structures.15421257 * A non-Null pointer at an offset15431258 * indicates a device exists.15441259 * max_id = 1 + maximum id (hosts.h)15451260 */15461546- sz = sh->max_id * sizeof(void *);15471547- mem = kmalloc(sz, GFP_ATOMIC);15481548- if (mem == NULL) {12611261+ hd->Targets = kcalloc(sh->max_id, sizeof(void *), GFP_ATOMIC);12621262+ if (!hd->Targets) {15491263 error = -ENOMEM;15501264 goto out_mptsas_probe;15511265 }1552126615531553- memset(mem, 0, sz);15541554- hd->Targets = (VirtTarget **) mem;15551555-15561556- dprintk((KERN_INFO15571557- " vtarget @ %p, sz=%d\n", hd->Targets, sz));12671267+ dprintk((KERN_INFO " vtarget @ %p\n", hd->Targets));1558126815591269 /* Clear the TM flags15601270 */···1596132415971325 mptsas_scan_sas_topology(ioc);1598132613271327+ /*13281328+ Reporting RAID volumes.13291329+ */13301330+ if (!ioc->raid_data.pIocPg2)13311331+ return 0;13321332+ if (!ioc->raid_data.pIocPg2->NumActiveVolumes)13331333+ return 0;13341334+ for (ii=0;ii<ioc->raid_data.pIocPg2->NumActiveVolumes;ii++) {13351335+ scsi_add_device(sh,13361336+ ioc->num_ports,13371337+ ioc->raid_data.pIocPg2->RaidVolume[ii].VolumeID,13381338+ 0);13391339+ }13401340+15991341 return 0;1600134216011343out_mptsas_probe:···1625133916261340 sas_remove_host(ioc->sh);1627134113421342+ mutex_lock(&ioc->sas_topology_mutex);16281343 list_for_each_entry_safe(p, n, &ioc->sas_topology, list) {16291344 list_del(&p->list);16301345 kfree(p);16311346 }13471347+ mutex_unlock(&ioc->sas_topology_mutex);1632134816331349 mptscsih_remove(pdev);16341350}···16811393 mpt_register(mptscsih_scandv_complete, MPTSAS_DRIVER);16821394 mptsasMgmtCtx = mpt_register(mptsas_mgmt_done, MPTSAS_DRIVER);1683139516841684- if (mpt_event_register(mptsasDoneCtx, mptscsih_event_process) == 0) {13961396+ if (mpt_event_register(mptsasDoneCtx, mptsas_event_process) == 0) {16851397 devtprintk((KERN_INFO MYNAM16861398 ": Registered for IOC event notifications\n"));16871399 }
+26-8
drivers/message/fusion/mptscsih.c
···893893 * when a lun is disable by mid-layer.894894 * Do NOT access the referenced scsi_cmnd structure or895895 * members. Will cause either a paging or NULL ptr error.896896+ * (BUT, BUT, BUT, the code does reference it! - mdr)896897 * @hd: Pointer to a SCSI HOST structure897898 * @vdevice: per device private data898899 *···21632162{21642163 VirtTarget *vtarget;2165216421662166- vtarget = kmalloc(sizeof(VirtTarget), GFP_KERNEL);21652165+ vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL);21672166 if (!vtarget)21682167 return -ENOMEM;21692169- memset(vtarget, 0, sizeof(VirtTarget));21702168 starget->hostdata = vtarget;21712169 return 0;21722170}···21852185 VirtDevice *vdev;21862186 struct scsi_target *starget;2187218721882188- vdev = kmalloc(sizeof(VirtDevice), GFP_KERNEL);21882188+ vdev = kzalloc(sizeof(VirtDevice), GFP_KERNEL);21892189 if (!vdev) {21902190 printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",21912191 hd->ioc->name, sizeof(VirtDevice));21922192 return -ENOMEM;21932193 }2194219421952195- memset(vdev, 0, sizeof(VirtDevice));21962195 vdev->ioc_id = hd->ioc->id;21972196 vdev->target_id = sdev->id;21982197 vdev->bus_id = sdev->channel;···25582559 hd->cmdPtr = NULL;25592560 }2560256125612561- /* 7. Set flag to force DV and re-read IOC Page 325622562+ /* 7. SPI: Set flag to force DV and re-read IOC Page 325622563 */25632564 if (ioc->bus_type == SPI) {25642565 ioc->spi_data.forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3;25652566 ddvtprintk(("Set reload IOC Pg3 Flag\n"));25662567 }2567256825692569+ /* 7. FC: Rescan for blocked rports which might have returned.25702570+ */25712571+ else if (ioc->bus_type == FC) {25722572+ int work_count;25732573+ unsigned long flags;25742574+25752575+ spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);25762576+ work_count = ++ioc->fc_rescan_work_count;25772577+ spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);25782578+ if (work_count == 1)25792579+ schedule_work(&ioc->fc_rescan_work);25802580+ }25682581 dtmprintk((MYIOC_s_WARN_FMT "Post-Reset complete.\n", ioc->name));2569258225702583 }···26002589{26012590 MPT_SCSI_HOST *hd;26022591 u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;25922592+ int work_count;25932593+ unsigned long flags;2603259426042595 devtprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n",26052596 ioc->name, event));···26232610 /* FIXME! */26242611 break;2625261226132613+ case MPI_EVENT_RESCAN: /* 06 */26142614+ spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);26152615+ work_count = ++ioc->fc_rescan_work_count;26162616+ spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);26172617+ if (work_count == 1)26182618+ schedule_work(&ioc->fc_rescan_work);26192619+ break;26202620+26262621 /*26272622 * CHECKME! Don't think we need to do26282623 * anything for these, but...26292624 */26302630- case MPI_EVENT_RESCAN: /* 06 */26312625 case MPI_EVENT_LINK_STATUS_CHANGE: /* 07 */26322626 case MPI_EVENT_LOOP_STATE_CHANGE: /* 08 */26332627 /*···39723952 mptscsih_do_cmd(hd, &iocmd);39733953}3974395439753975-/* Search IOC page 3 to determine if this is hidden physical disk39763976- */39773955/* Search IOC page 3 to determine if this is hidden physical disk39783956 */39793957static int
+8-18
drivers/message/fusion/mptspi.c
···158158 MPT_SCSI_HOST *hd;159159 MPT_ADAPTER *ioc;160160 unsigned long flags;161161- int sz, ii;161161+ int ii;162162 int numSGE = 0;163163 int scale;164164 int ioc_cap;165165- u8 *mem;166165 int error=0;167166 int r;168167···287288 /* SCSI needs scsi_cmnd lookup table!288289 * (with size equal to req_depth*PtrSz!)289290 */290290- sz = ioc->req_depth * sizeof(void *);291291- mem = kmalloc(sz, GFP_ATOMIC);292292- if (mem == NULL) {291291+ hd->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_ATOMIC);292292+ if (!hd->ScsiLookup) {293293 error = -ENOMEM;294294 goto out_mptspi_probe;295295 }296296297297- memset(mem, 0, sz);298298- hd->ScsiLookup = (struct scsi_cmnd **) mem;299299-300300- dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p, sz=%d\n",301301- ioc->name, hd->ScsiLookup, sz));297297+ dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p\n",298298+ ioc->name, hd->ScsiLookup));302299303300 /* Allocate memory for the device structures.304301 * A non-Null pointer at an offset305302 * indicates a device exists.306303 * max_id = 1 + maximum id (hosts.h)307304 */308308- sz = sh->max_id * sizeof(void *);309309- mem = kmalloc(sz, GFP_ATOMIC);310310- if (mem == NULL) {305305+ hd->Targets = kcalloc(sh->max_id, sizeof(void *), GFP_ATOMIC);306306+ if (!hd->Targets) {311307 error = -ENOMEM;312308 goto out_mptspi_probe;313309 }314310315315- memset(mem, 0, sz);316316- hd->Targets = (VirtTarget **) mem;317317-318318- dprintk((KERN_INFO319319- " vdev @ %p, sz=%d\n", hd->Targets, sz));311311+ dprintk((KERN_INFO " vdev @ %p\n", hd->Targets));320312321313 /* Clear the TM flags322314 */
+5-5
drivers/message/i2o/pci.c
···8888 struct device *dev = &pdev->dev;8989 int i;90909191- if (pci_request_regions(pdev, OSM_DESCRIPTION)) {9292- printk(KERN_ERR "%s: device already claimed\n", c->name);9393- return -ENODEV;9494- }9595-9691 for (i = 0; i < 6; i++) {9792 /* Skip I/O spaces */9893 if (!(pci_resource_flags(pdev, i) & IORESOURCE_IO)) {···312317 printk(KERN_WARNING "i2o: couldn't enable device %s\n",313318 pci_name(pdev));314319 return rc;320320+ }321321+322322+ if (pci_request_regions(pdev, OSM_DESCRIPTION)) {323323+ printk(KERN_ERR "i2o: device already claimed\n");324324+ return -ENODEV;315325 }316326317327 if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
+2
drivers/s390/scsi/zfcp_aux.c
···11251125 zfcp_free_low_mem_buffers(adapter);11261126 /* free memory of adapter data structure and queues */11271127 zfcp_qdio_free_queues(adapter);11281128+ kfree(adapter->fc_stats);11291129+ kfree(adapter->stats_reset_data);11281130 ZFCP_LOG_TRACE("freeing adapter structure\n");11291131 kfree(adapter);11301132 out:
+3-1
drivers/s390/scsi/zfcp_def.h
···921921 u32 physical_s_id; /* local FC port ID */922922 struct ccw_device *ccw_device; /* S/390 ccw device */923923 u8 fc_service_class;924924- u32 fc_topology; /* FC topology */925924 u32 hydra_version; /* Hydra version */926925 u32 fsf_lic_version;927926 u32 adapter_features; /* FCP channel features */···977978 struct zfcp_adapter_mempool pool; /* Adapter memory pools */978979 struct qdio_initialize qdio_init_data; /* for qdio_establish */979980 struct device generic_services; /* directory for WKA ports */981981+ struct fc_host_statistics *fc_stats;982982+ struct fsf_qtcb_bottom_port *stats_reset_data;983983+ unsigned long stats_reset;980984};981985982986/*
+1-1
drivers/s390/scsi/zfcp_erp.c
···26132613 case ZFCP_ERP_STEP_UNINITIALIZED:26142614 case ZFCP_ERP_STEP_PHYS_PORT_CLOSING:26152615 case ZFCP_ERP_STEP_PORT_CLOSING:26162616- if (adapter->fc_topology == FSF_TOPO_P2P) {26162616+ if (fc_host_port_type(adapter->scsi_host) == FC_PORTTYPE_PTP) {26172617 if (port->wwpn != adapter->peer_wwpn) {26182618 ZFCP_LOG_NORMAL("Failed to open port 0x%016Lx "26192619 "on adapter %s.\nPeer WWPN "
+60-24
drivers/s390/scsi/zfcp_fsf.c
···964964 | ZFCP_STATUS_COMMON_ERP_FAILED);965965 break;966966967967+ case FSF_STATUS_READ_NOTIFICATION_LOST:968968+ ZFCP_LOG_NORMAL("Unsolicited status notification(s) lost: "969969+ "adapter %s%s%s%s%s%s%s%s%s\n",970970+ zfcp_get_busid_by_adapter(adapter),971971+ (status_buffer->status_subtype &972972+ FSF_STATUS_READ_SUB_INCOMING_ELS) ?973973+ ", incoming ELS" : "",974974+ (status_buffer->status_subtype &975975+ FSF_STATUS_READ_SUB_SENSE_DATA) ?976976+ ", sense data" : "",977977+ (status_buffer->status_subtype &978978+ FSF_STATUS_READ_SUB_LINK_STATUS) ?979979+ ", link status change" : "",980980+ (status_buffer->status_subtype &981981+ FSF_STATUS_READ_SUB_PORT_CLOSED) ?982982+ ", port close" : "",983983+ (status_buffer->status_subtype &984984+ FSF_STATUS_READ_SUB_BIT_ERROR_THRESHOLD) ?985985+ ", bit error exception" : "",986986+ (status_buffer->status_subtype &987987+ FSF_STATUS_READ_SUB_ACT_UPDATED) ?988988+ ", ACT update" : "",989989+ (status_buffer->status_subtype &990990+ FSF_STATUS_READ_SUB_ACT_HARDENED) ?991991+ ", ACT hardening" : "",992992+ (status_buffer->status_subtype &993993+ FSF_STATUS_READ_SUB_FEATURE_UPDATE_ALERT) ?994994+ ", adapter feature change" : "");995995+996996+ if (status_buffer->status_subtype &997997+ FSF_STATUS_READ_SUB_ACT_UPDATED)998998+ zfcp_erp_adapter_access_changed(adapter);999999+ break;10001000+9671001 case FSF_STATUS_READ_CFDC_UPDATED:9681002 ZFCP_LOG_NORMAL("CFDC has been updated on the adapter %s\n",9691003 zfcp_get_busid_by_adapter(adapter));···19881954 erp_action->fsf_req->qtcb->bottom.config.feature_selection =19891955 FSF_FEATURE_CFDC |19901956 FSF_FEATURE_LUN_SHARING |19571957+ FSF_FEATURE_NOTIFICATION_LOST |19911958 FSF_FEATURE_UPDATE_ALERT;1992195919931960 /* start QDIO request for this FSF request */···20432008 fc_host_port_id(shost) = bottom->s_id & ZFCP_DID_MASK;20442009 fc_host_speed(shost) = bottom->fc_link_speed;20452010 fc_host_supported_classes(shost) = FC_COS_CLASS2 | FC_COS_CLASS3;20462046- adapter->fc_topology = bottom->fc_topology;20472011 adapter->hydra_version = bottom->adapter_type;20482048- if (adapter->physical_wwpn == 0)20492049- adapter->physical_wwpn = fc_host_port_name(shost);20502050- if (adapter->physical_s_id == 0)20512051- adapter->physical_s_id = fc_host_port_id(shost);20122012+ if (fc_host_permanent_port_name(shost) == -1)20132013+ fc_host_permanent_port_name(shost) =20142014+ fc_host_port_name(shost);20152015+ if (bottom->fc_topology == FSF_TOPO_P2P) {20162016+ adapter->peer_d_id = bottom->peer_d_id & ZFCP_DID_MASK;20172017+ adapter->peer_wwpn = bottom->plogi_payload.wwpn;20182018+ adapter->peer_wwnn = bottom->plogi_payload.wwnn;20192019+ fc_host_port_type(shost) = FC_PORTTYPE_PTP;20202020+ } else if (bottom->fc_topology == FSF_TOPO_FABRIC)20212021+ fc_host_port_type(shost) = FC_PORTTYPE_NPORT;20222022+ else if (bottom->fc_topology == FSF_TOPO_AL)20232023+ fc_host_port_type(shost) = FC_PORTTYPE_NLPORT;20242024+ else20252025+ fc_host_port_type(shost) = FC_PORTTYPE_UNKNOWN;20522026 } else {20532027 fc_host_node_name(shost) = 0;20542028 fc_host_port_name(shost) = 0;20552029 fc_host_port_id(shost) = 0;20562030 fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN;20572057- adapter->fc_topology = 0;20312031+ fc_host_port_type(shost) = FC_PORTTYPE_UNKNOWN;20582032 adapter->hydra_version = 0;20592059- }20602060-20612061- if (adapter->fc_topology == FSF_TOPO_P2P) {20622062- adapter->peer_d_id = bottom->peer_d_id & ZFCP_DID_MASK;20632063- adapter->peer_wwpn = bottom->plogi_payload.wwpn;20642064- adapter->peer_wwnn = bottom->plogi_payload.wwnn;20652033 }2066203420672035 if (adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT) {···21352097 if (zfcp_fsf_exchange_config_evaluate(fsf_req, 1))21362098 return -EIO;2137209921382138- switch (adapter->fc_topology) {21392139- case FSF_TOPO_P2P:21002100+ switch (fc_host_port_type(adapter->scsi_host)) {21012101+ case FC_PORTTYPE_PTP:21402102 ZFCP_LOG_NORMAL("Point-to-Point fibrechannel "21412103 "configuration detected at adapter %s\n"21422104 "Peer WWNN 0x%016llx, "···21492111 debug_text_event(fsf_req->adapter->erp_dbf, 0,21502112 "top-p-to-p");21512113 break;21522152- case FSF_TOPO_AL:21142114+ case FC_PORTTYPE_NLPORT:21532115 ZFCP_LOG_NORMAL("error: Arbitrated loop fibrechannel "21542116 "topology detected at adapter %s "21552117 "unsupported, shutting down adapter\n",···21582120 "top-al");21592121 zfcp_erp_adapter_shutdown(adapter, 0);21602122 return -EIO;21612161- case FSF_TOPO_FABRIC:21232123+ case FC_PORTTYPE_NPORT:21622124 ZFCP_LOG_NORMAL("Switched fabric fibrechannel "21632125 "network detected at adapter %s.\n",21642126 zfcp_get_busid_by_adapter(adapter));···21712133 "of a type known to the zfcp "21722134 "driver, shutting down adapter\n",21732135 zfcp_get_busid_by_adapter(adapter));21742174- adapter->fc_topology = FSF_TOPO_ERROR;21752136 debug_text_exception(fsf_req->adapter->erp_dbf, 0,21762137 "unknown-topo");21772138 zfcp_erp_adapter_shutdown(adapter, 0);···23302293 data = (struct fsf_qtcb_bottom_port*) fsf_req->data;23312294 if (data)23322295 memcpy(data, bottom, sizeof(struct fsf_qtcb_bottom_port));23332333- if (adapter->connection_features & FSF_FEATURE_NPIV_MODE) {23342334- adapter->physical_wwpn = bottom->wwpn;23352335- adapter->physical_s_id = bottom->fc_port_id;23362336- } else {23372337- adapter->physical_wwpn = fc_host_port_name(shost);23382338- adapter->physical_s_id = fc_host_port_id(shost);23392339- }22962296+ if (adapter->connection_features & FSF_FEATURE_NPIV_MODE)22972297+ fc_host_permanent_port_name(shost) = bottom->wwpn;22982298+ else22992299+ fc_host_permanent_port_name(shost) =23002300+ fc_host_port_name(shost);23402301 fc_host_maxframe_size(shost) = bottom->maximum_frame_size;23022302+ fc_host_supported_speeds(shost) = bottom->supported_speed;23412303 break;2342230423432305 case FSF_EXCHANGE_CONFIG_DATA_INCOMPLETE:
+12-1
drivers/s390/scsi/zfcp_fsf.h
···166166#define FSF_STATUS_READ_BIT_ERROR_THRESHOLD 0x00000004167167#define FSF_STATUS_READ_LINK_DOWN 0x00000005168168#define FSF_STATUS_READ_LINK_UP 0x00000006169169+#define FSF_STATUS_READ_NOTIFICATION_LOST 0x00000009169170#define FSF_STATUS_READ_CFDC_UPDATED 0x0000000A170171#define FSF_STATUS_READ_CFDC_HARDENED 0x0000000B171172#define FSF_STATUS_READ_FEATURE_UPDATE_ALERT 0x0000000C···180179#define FSF_STATUS_READ_SUB_FDISC_FAILED 0x00000001181180#define FSF_STATUS_READ_SUB_FIRMWARE_UPDATE 0x00000002182181182182+/* status subtypes for unsolicited status notification lost */183183+#define FSF_STATUS_READ_SUB_INCOMING_ELS 0x00000001184184+#define FSF_STATUS_READ_SUB_SENSE_DATA 0x00000002185185+#define FSF_STATUS_READ_SUB_LINK_STATUS 0x00000004186186+#define FSF_STATUS_READ_SUB_PORT_CLOSED 0x00000008187187+#define FSF_STATUS_READ_SUB_BIT_ERROR_THRESHOLD 0x00000010188188+#define FSF_STATUS_READ_SUB_ACT_UPDATED 0x00000020189189+#define FSF_STATUS_READ_SUB_ACT_HARDENED 0x00000040190190+#define FSF_STATUS_READ_SUB_FEATURE_UPDATE_ALERT 0x00000080191191+183192/* status subtypes for CFDC */184193#define FSF_STATUS_READ_SUB_CFDC_HARDENED_ON_SE 0x00000002185194#define FSF_STATUS_READ_SUB_CFDC_HARDENED_ON_SE2 0x0000000F···199188#define FSF_TOPO_P2P 0x00000001200189#define FSF_TOPO_FABRIC 0x00000002201190#define FSF_TOPO_AL 0x00000003202202-#define FSF_TOPO_FABRIC_VIRT 0x00000004203191204192/* data direction for FCP commands */205193#define FSF_DATADIR_WRITE 0x00000001···221211/* channel features */222212#define FSF_FEATURE_CFDC 0x00000002223213#define FSF_FEATURE_LUN_SHARING 0x00000004214214+#define FSF_FEATURE_NOTIFICATION_LOST 0x00000008224215#define FSF_FEATURE_HBAAPI_MANAGEMENT 0x00000010225216#define FSF_FEATURE_ELS_CT_CHAINED_SBALS 0x00000020226217#define FSF_FEATURE_UPDATE_ALERT 0x00000100
···7373#include <linux/delay.h>7474#include <linux/pci.h>7575#include <linux/time.h>7676+#include <linux/mutex.h>7677#include <asm/io.h>7778#include <asm/irq.h>7879#include <asm/uaccess.h>···616615 void __user *argp = (void __user *)arg;617616618617 /* Only let one of these through at a time */619619- if (down_interruptible(&tw_dev->ioctl_sem)) {618618+ if (mutex_lock_interruptible(&tw_dev->ioctl_lock)) {620619 retval = TW_IOCTL_ERROR_OS_EINTR;621620 goto out;622621 }···853852 /* Now free ioctl buf memory */854853 dma_free_coherent(&tw_dev->tw_pci_dev->dev, data_buffer_length_adjusted+sizeof(TW_Ioctl_Buf_Apache) - 1, cpu_addr, dma_handle);855854out2:856856- up(&tw_dev->ioctl_sem);855855+ mutex_unlock(&tw_dev->ioctl_lock);857856out:858857 return retval;859858} /* End twa_chrdev_ioctl() */···11831182 tw_dev->error_sequence_id = 1;11841183 tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;1185118411861186- init_MUTEX(&tw_dev->ioctl_sem);11851185+ mutex_init(&tw_dev->ioctl_lock);11871186 init_waitqueue_head(&tw_dev->ioctl_wqueue);1188118711891188 retval = 0;
+1-1
drivers/scsi/3w-9xxx.h
···672672 u32 ioctl_msec;673673 int chrdev_request_id;674674 wait_queue_head_t ioctl_wqueue;675675- struct semaphore ioctl_sem;675675+ struct mutex ioctl_lock;676676 char aen_clobber;677677 unsigned short working_srl;678678 unsigned short working_branch;
+4-3
drivers/scsi/3w-xxxx.c
···203203#include <linux/delay.h>204204#include <linux/pci.h>205205#include <linux/time.h>206206+#include <linux/mutex.h>206207#include <asm/io.h>207208#include <asm/irq.h>208209#include <asm/uaccess.h>···889888 dprintk(KERN_WARNING "3w-xxxx: tw_chrdev_ioctl()\n");890889891890 /* Only let one of these through at a time */892892- if (down_interruptible(&tw_dev->ioctl_sem))891891+ if (mutex_lock_interruptible(&tw_dev->ioctl_lock))893892 return -EINTR;894893895894 /* First copy down the buffer length */···10301029 /* Now free ioctl buf memory */10311030 dma_free_coherent(&tw_dev->tw_pci_dev->dev, data_buffer_length_adjusted+sizeof(TW_New_Ioctl) - 1, cpu_addr, dma_handle);10321031out:10331033- up(&tw_dev->ioctl_sem);10321032+ mutex_unlock(&tw_dev->ioctl_lock);10341033 return retval;10351034} /* End tw_chrdev_ioctl() */10361035···12711270 tw_dev->pending_tail = TW_Q_START;12721271 tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;1273127212741274- init_MUTEX(&tw_dev->ioctl_sem);12731273+ mutex_init(&tw_dev->ioctl_lock);12751274 init_waitqueue_head(&tw_dev->ioctl_wqueue);1276127512771276 return 0;
···11-AACRAID Driver for Linux (take two)22-33-Introduction44--------------------------55-The aacraid driver adds support for Adaptec (http://www.adaptec.com)66-RAID controllers. This is a major rewrite from the original 77-Adaptec supplied driver. It has signficantly cleaned up both the code88-and the running binary size (the module is less than half the size of99-the original).1010-1111-Supported Cards/Chipsets1212--------------------------1313- Adaptec 2020S1414- Adaptec 2025S1515- Adaptec 2120S1616- Adaptec 2130S1717- Adaptec 2200S1818- Adaptec 2230S1919- Adaptec 2240S2020- Adaptec 2410SA2121- Adaptec 2610SA2222- Adaptec 2810SA2323- Adaptec 21610SA2424- Adaptec 3230S2525- Adaptec 3240S2626- Adaptec 4000SAS2727- Adaptec 4005SAS2828- Adaptec 4800SAS2929- Adaptec 4805SAS3030- Adaptec 5400S3131- Dell PERC 2 Quad Channel3232- Dell PERC 2/Si3333- Dell PERC 3/Si3434- Dell PERC 3/Di3535- Dell CERC 23636- HP NetRAID-4M3737- Legend S2203838- Legend S2303939- IBM ServeRAID 8i4040- ICP 9014R04141- ICP 9024R04242- ICP 9047MA4343- ICP 9087MA4444- ICP 9085LI4545- ICP 5085AU4646-4747-People4848--------------------------4949-Alan Cox <alan@redhat.com>5050-Christoph Hellwig <hch@infradead.org> (updates for new-style PCI probing and SCSI host registration,5151- small cleanups/fixes)5252-Matt Domsch <matt_domsch@dell.com> (revision ioctl, adapter messages)5353-Deanna Bonds (non-DASD support, PAE fibs and 64 bit, added new adaptec controllers5454- added new ioctls, changed scsi interface to use new error handler,5555- increased the number of fibs and outstanding commands to a container)5656-5757- (fixed 64bit and 64G memory model, changed confusing naming convention5858- where fibs that go to the hardware are consistently called hw_fibs and5959- not just fibs like the name of the driver tracking structure)6060-Mark Salyzyn <Mark_Salyzyn@adaptec.com> Fixed panic issues and added some new product ids for upcoming hbas. Performance tuning, card failover and bug mitigations.6161-6262-Original Driver6363--------------------------6464-Adaptec Unix OEM Product Group6565-6666-Mailing List6767--------------------------6868-linux-scsi@vger.kernel.org (Interested parties troll here)6969-Also note this is very different to Brian's original driver7070-so don't expect him to support it.7171-Adaptec does support this driver. Contact either tech support or Mark Salyzyn.7272-7373-Original by Brian Boerner February 20017474-Rewritten by Alan Cox, November 2001
+7
drivers/scsi/aacraid/aacraid.h
···532532#define AAC_QUIRK_MASTER 0x0008533533534534/*535535+ * Some adapter firmware perform poorly when it must split up scatter gathers536536+ * in order to deal with the limits of the underlying CHIM. This limit in this537537+ * class of adapters is 17 scatter gather elements.538538+ */539539+#define AAC_QUIRK_17SG 0x0010540540+541541+/*535542 * The adapter interface specs all queues to be located in the same536543 * physically contigous block. The host structure that defines the537544 * commuication queues will assume they are each a separate physically
+4
drivers/scsi/aacraid/commctrl.c
···8585 if (size < le16_to_cpu(kfib->header.SenderSize))8686 size = le16_to_cpu(kfib->header.SenderSize);8787 if (size > dev->max_fib_size) {8888+ if (size > 2048) {8989+ retval = -EINVAL;9090+ goto cleanup;9191+ }8892 /* Highjack the hw_fib */8993 hw_fib = fibptr->hw_fib;9094 hw_fib_pa = fibptr->hw_fib_pa;
···4242config AIC7XXX_RESET_DELAY_MS4343 int "Initial bus reset delay in milli-seconds"4444 depends on SCSI_AIC7XXX4545- default "15000"4545+ default "5000"4646 ---help---4747 The number of milliseconds to delay after an initial bus reset.4848 The bus settle delay following all error recovery actions is4949 dictated by the SCSI layer and is not affected by this value.50505151- Default: 15000 (15 seconds)5151+ Default: 5000 (5 seconds)52525353config AIC7XXX_PROBE_EISA_VL5454 bool "Probe for EISA and VL AIC7XXX Adapters"
+26-13
drivers/scsi/aic7xxx/aic79xx.h
···3737 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE3838 * POSSIBILITY OF SUCH DAMAGES.3939 *4040- * $Id: //depot/aic7xxx/aic7xxx/aic79xx.h#95 $4040+ * $Id: //depot/aic7xxx/aic7xxx/aic79xx.h#108 $4141 *4242 * $FreeBSD$4343 */···7575#define INITIATOR_WILDCARD (~0)7676#define SCB_LIST_NULL 0xFF007777#define SCB_LIST_NULL_LE (ahd_htole16(SCB_LIST_NULL))7878-#define QOUTFIFO_ENTRY_VALID 0x80007979-#define QOUTFIFO_ENTRY_VALID_LE (ahd_htole16(0x8000))7878+#define QOUTFIFO_ENTRY_VALID 0x808079#define SCBID_IS_NULL(scbid) (((scbid) & 0xFF00 ) == SCB_LIST_NULL)81808281#define SCSIID_TARGET(ahd, scsiid) \···1052105310531054typedef void ahd_callback_t (void *);1054105510561056+struct ahd_completion10571057+{10581058+ uint16_t tag;10591059+ uint8_t sg_status;10601060+ uint8_t valid_tag;10611061+};10621062+10551063struct ahd_softc {10561064 bus_space_tag_t tags[2];10571065 bus_space_handle_t bshs[2];···10681062 struct scb_data scb_data;1069106310701064 struct hardware_scb *next_queued_hscb;10651065+ struct map_node *next_queued_hscb_map;1071106610721067 /*10731068 * SCBs that have been sent to the controller···11471140 ahd_flag flags;11481141 struct seeprom_config *seep_config;1149114211501150- /* Values to store in the SEQCTL register for pause and unpause */11511151- uint8_t unpause;11521152- uint8_t pause;11531153-11541143 /* Command Queues */11441144+ struct ahd_completion *qoutfifo;11551145 uint16_t qoutfifonext;11561146 uint16_t qoutfifonext_valid_tag;11571147 uint16_t qinfifonext;11581148 uint16_t qinfifo[AHD_SCB_MAX];11591159- uint16_t *qoutfifo;11491149+11501150+ /*11511151+ * Our qfreeze count. The sequencer compares11521152+ * this value with its own counter to determine11531153+ * whether to allow selections to occur.11541154+ */11551155+ uint16_t qfreeze_cnt;11561156+11571157+ /* Values to store in the SEQCTL register for pause and unpause */11581158+ uint8_t unpause;11591159+ uint8_t pause;1160116011611161 /* Critical Section Data */11621162 struct cs *critical_sections;···12111197 */12121198 bus_dma_tag_t parent_dmat;12131199 bus_dma_tag_t shared_data_dmat;12141214- bus_dmamap_t shared_data_dmamap;12151215- dma_addr_t shared_data_busaddr;12001200+ struct map_node shared_data_map;1216120112171202 /* Information saved through suspend/resume cycles */12181203 struct ahd_suspend_state suspend_state;···13091296};1310129713111298/****************************** PCI Structures ********************************/13121312-#define AHD_PCI_IOADDR0 PCIR_MAPS /* I/O BAR*/13131313-#define AHD_PCI_MEMADDR (PCIR_MAPS + 4) /* Memory BAR */13141314-#define AHD_PCI_IOADDR1 (PCIR_MAPS + 12)/* Second I/O BAR */12991299+#define AHD_PCI_IOADDR0 PCIR_BAR(0) /* I/O BAR*/13001300+#define AHD_PCI_MEMADDR PCIR_BAR(1) /* Memory BAR */13011301+#define AHD_PCI_IOADDR1 PCIR_BAR(3) /* Second I/O BAR */1315130213161303typedef int (ahd_device_setup_t)(struct ahd_softc *);13171304
+39-21
drivers/scsi/aic7xxx/aic79xx.reg
···3939 *4040 * $FreeBSD$4141 */4242-VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#70 $"4242+VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#76 $"43434444/*4545 * This file is processed by the aic7xxx_asm utility for use in assembling···6565 mvi MODE_PTR, MK_MODE(src, dst); \6666 }67676868-#define TOGGLE_DFF_MODE \6969- if ((ahd->bugs & AHD_SET_MODE_BUG) != 0) { \7070- call toggle_dff_mode_work_around; \7171- } else { \7272- xor MODE_PTR, MK_MODE(M_DFF1, M_DFF1); \7373- }7474-7568#define RESTORE_MODE(mode) \7669 if ((ahd->bugs & AHD_SET_MODE_BUG) != 0) { \7770 mov mode call set_mode_work_around; \···1192119911931200/*11941201 * LQ Packet In11951195- * The last LQ Packet received12021202+ * The last LQ Packet recieved11961203 */11971204register LQIN {11981205 address 0x020···35353542 COMPLETE_DMA_SCB_HEAD {35363543 size 235373544 }35383538- /* Counting semaphore to prevent new select-outs */35453545+ /*35463546+ * tail of list of SCBs that have35473547+ * completed but need to be uploaded35483548+ * to the host prior to being completed.35493549+ */35503550+ COMPLETE_DMA_SCB_TAIL {35513551+ size 235523552+ }35533553+ /*35543554+ * head of list of SCBs that have35553555+ * been uploaded to the host, but cannot35563556+ * be completed until the QFREEZE is in35573557+ * full effect (i.e. no selections pending).35583558+ */35593559+ COMPLETE_ON_QFREEZE_HEAD {35603560+ size 235613561+ }35623562+ /*35633563+ * Counting semaphore to prevent new select-outs35643564+ * The queue is frozen so long as the sequencer35653565+ * and kernel freeze counts differ.35663566+ */35393567 QFREEZE_COUNT {35683568+ size 235693569+ }35703570+ KERNEL_QFREEZE_COUNT {35403571 size 235413572 }35423573 /*···36423625 size 136433626 }36443627 /*36283628+ * Kernel and sequencer offsets into the queue of36293629+ * incoming target mode command descriptors. The36303630+ * queue is full when the KERNEL_TQINPOS == TQINPOS.36313631+ */36323632+ KERNEL_TQINPOS {36333633+ size 136343634+ }36353635+ TQINPOS { 36363636+ size 136373637+ }36383638+ /*36453639 * Base address of our shared data with the kernel driver in host36463640 * memory. This includes the qoutfifo and target mode36473641 * incoming command queue.···36663638 */36673639 QOUTFIFO_NEXT_ADDR {36683640 size 436693669- }36703670- /*36713671- * Kernel and sequencer offsets into the queue of36723672- * incoming target mode command descriptors. The36733673- * queue is full when the KERNEL_TQINPOS == TQINPOS.36743674- */36753675- KERNEL_TQINPOS {36763676- size 136773677- }36783678- TQINPOS { 36793679- size 136803641 }36813642 ARG_1 {36823643 size 1···39683951const SG_SIZEOF download39693952const PKT_OVERRUN_BUFOFFSET download39703953const SCB_TRANSFER_SIZE download39543954+const CACHELINE_MASK download3971395539723956/*39733957 * BIOS SCB offsets
+188-53
drivers/scsi/aic7xxx/aic79xx.seq
···4040 * $FreeBSD$4141 */42424343-VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#99 $"4343+VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#119 $"4444PATCH_ARG_LIST = "struct ahd_softc *ahd"4545PREFIX = "ahd_"4646···6868 }6969 SET_MODE(M_SCSI, M_SCSI)7070 test SCSISEQ0, ENSELO|ENARBO jnz idle_loop_checkbus;7171- test SEQ_FLAGS2, SELECTOUT_QFROZEN jnz idle_loop_checkbus;7171+ test SEQ_FLAGS2, SELECTOUT_QFROZEN jz check_waiting_list;7272+ /*7373+ * If the kernel has caught up with us, thaw the queue.7474+ */7575+ mov A, KERNEL_QFREEZE_COUNT;7676+ cmp QFREEZE_COUNT, A jne check_frozen_completions;7777+ mov A, KERNEL_QFREEZE_COUNT[1];7878+ cmp QFREEZE_COUNT[1], A jne check_frozen_completions;7979+ and SEQ_FLAGS2, ~SELECTOUT_QFROZEN;8080+ jmp check_waiting_list;8181+check_frozen_completions:8282+ test SSTAT0, SELDO|SELINGO jnz idle_loop_checkbus;8383+BEGIN_CRITICAL;8484+ /*8585+ * If we have completions stalled waiting for the qfreeze8686+ * to take effect, move them over to the complete_scb list8787+ * now that no selections are pending.8888+ */8989+ cmp COMPLETE_ON_QFREEZE_HEAD[1],SCB_LIST_NULL je idle_loop_checkbus;9090+ /*9191+ * Find the end of the qfreeze list. The first element has9292+ * to be treated specially.9393+ */9494+ bmov SCBPTR, COMPLETE_ON_QFREEZE_HEAD, 2;9595+ cmp SCB_NEXT_COMPLETE[1], SCB_LIST_NULL je join_lists;9696+ /*9797+ * Now the normal loop.9898+ */9999+ bmov SCBPTR, SCB_NEXT_COMPLETE, 2;100100+ cmp SCB_NEXT_COMPLETE[1], SCB_LIST_NULL jne . - 1;101101+join_lists:102102+ bmov SCB_NEXT_COMPLETE, COMPLETE_SCB_HEAD, 2;103103+ bmov COMPLETE_SCB_HEAD, COMPLETE_ON_QFREEZE_HEAD, 2;104104+ mvi COMPLETE_ON_QFREEZE_HEAD[1], SCB_LIST_NULL;105105+ jmp idle_loop_checkbus;106106+check_waiting_list:72107 cmp WAITING_TID_HEAD[1], SCB_LIST_NULL je idle_loop_checkbus;73108 /*74109 * ENSELO is cleared by a SELDO, so we must test for SELDO75110 * one last time.76111 */7777-BEGIN_CRITICAL;78112 test SSTAT0, SELDO jnz select_out;79113END_CRITICAL;80114 call start_selection;···12490 test SSTAT2, NONPACKREQ jz . + 2;12591 call unexpected_nonpkt_phase_find_ctxt;12692 if ((ahd->bugs & AHD_FAINT_LED_BUG) != 0) {9393+ /*9494+ * On Rev A. hardware, the busy LED is only9595+ * turned on automaically during selections9696+ * and re-selections. Make the LED status9797+ * more useful by forcing it to be on so9898+ * long as one of our data FIFOs is active.9999+ */127100 and A, FIFO0FREE|FIFO1FREE, DFFSTAT;128101 cmp A, FIFO0FREE|FIFO1FREE jne . + 3;129102 and SBLKCTL, ~DIAGLEDEN|DIAGLEDON;···142101 call idle_loop_cchan;143102 jmp idle_loop;144103145145-BEGIN_CRITICAL;146104idle_loop_gsfifo:147105 SET_MODE(M_SCSI, M_SCSI)106106+BEGIN_CRITICAL;148107idle_loop_gsfifo_in_scsi_mode:149108 test LQISTAT2, LQIGSAVAIL jz return;150109 /*···193152194153idle_loop_service_fifos:195154 SET_MODE(M_DFF0, M_DFF0)155155+BEGIN_CRITICAL;196156 test LONGJMP_ADDR[1], INVALID_ADDR jnz idle_loop_next_fifo;197157 call longjmp;158158+END_CRITICAL;198159idle_loop_next_fifo:199160 SET_MODE(M_DFF1, M_DFF1)161161+BEGIN_CRITICAL;200162 test LONGJMP_ADDR[1], INVALID_ADDR jz longjmp;163163+END_CRITICAL;201164return:202165 ret;203166···215170 test CCSCBCTL, CCARREN|CCSCBEN jz scbdma_idle;216171 test CCSCBCTL, CCSCBDIR jnz fetch_new_scb_inprog;217172 test CCSCBCTL, CCSCBDONE jz return;218218-END_CRITICAL;219173 /* FALLTHROUGH */220174scbdma_tohost_done:221175 test CCSCBCTL, CCARREN jz fill_qoutfifo_dmadone;···224180 * bad SCSI status (currently only for underruns), we225181 * queue the SCB for normal completion. Otherwise, we226182 * wait until any select-out activity has halted, and227227- * then notify the host so that the transaction can be228228- * dealt with.183183+ * then queue the completion.229184 */230230- test SCB_SCSI_STATUS, 0xff jnz scbdma_notify_host;231185 and CCSCBCTL, ~(CCARREN|CCSCBEN);232186 bmov COMPLETE_DMA_SCB_HEAD, SCB_NEXT_COMPLETE, 2;187187+ cmp SCB_NEXT_COMPLETE[1], SCB_LIST_NULL jne . + 2;188188+ mvi COMPLETE_DMA_SCB_TAIL[1], SCB_LIST_NULL;189189+ test SCB_SCSI_STATUS, 0xff jz scbdma_queue_completion;190190+ bmov SCB_NEXT_COMPLETE, COMPLETE_ON_QFREEZE_HEAD, 2;191191+ bmov COMPLETE_ON_QFREEZE_HEAD, SCBPTR, 2 ret;192192+scbdma_queue_completion:233193 bmov SCB_NEXT_COMPLETE, COMPLETE_SCB_HEAD, 2;234194 bmov COMPLETE_SCB_HEAD, SCBPTR, 2 ret;235235-scbdma_notify_host:236236- SET_MODE(M_SCSI, M_SCSI)237237- test SCSISEQ0, ENSELO jnz return;238238- test SSTAT0, (SELDO|SELINGO) jnz return;239239- SET_MODE(M_CCHAN, M_CCHAN)240240- /*241241- * Remove SCB and notify host.242242- */243243- and CCSCBCTL, ~(CCARREN|CCSCBEN);244244- bmov COMPLETE_DMA_SCB_HEAD, SCB_NEXT_COMPLETE, 2;245245- SET_SEQINTCODE(BAD_SCB_STATUS)246246- ret;247195fill_qoutfifo_dmadone:248196 and CCSCBCTL, ~(CCARREN|CCSCBEN);249197 call qoutfifo_updated;···244208 test QOFF_CTLSTA, SDSCB_ROLLOVR jz return;245209 bmov QOUTFIFO_NEXT_ADDR, SHARED_DATA_ADDR, 4;246210 xor QOUTFIFO_ENTRY_VALID_TAG, QOUTFIFO_ENTRY_VALID_TOGGLE ret;211211+END_CRITICAL;247212248213qoutfifo_updated:249214 /*···361324 * Keep track of the SCBs we are dmaing just362325 * in case the DMA fails or is aborted.363326 */364364- mov A, QOUTFIFO_ENTRY_VALID_TAG;365327 bmov COMPLETE_SCB_DMAINPROG_HEAD, COMPLETE_SCB_HEAD, 2;366328 mvi CCSCBCTL, CCSCBRESET;367329 bmov SCBHADDR, QOUTFIFO_NEXT_ADDR, 4;330330+ mov A, QOUTFIFO_NEXT_ADDR;368331 bmov SCBPTR, COMPLETE_SCB_HEAD, 2;369332fill_qoutfifo_loop:370370- mov CCSCBRAM, SCBPTR;371371- or CCSCBRAM, A, SCBPTR[1];333333+ bmov CCSCBRAM, SCBPTR, 2;334334+ mov CCSCBRAM, SCB_SGPTR[0];335335+ mov CCSCBRAM, QOUTFIFO_ENTRY_VALID_TAG;372336 mov NONE, SDSCB_QOFF;373337 inc INT_COALESCING_CMDCOUNT;374338 add CMDS_PENDING, -1;···377339 cmp SCB_NEXT_COMPLETE[1], SCB_LIST_NULL je fill_qoutfifo_done;378340 cmp CCSCBADDR, CCSCBADDR_MAX je fill_qoutfifo_done;379341 test QOFF_CTLSTA, SDSCB_ROLLOVR jnz fill_qoutfifo_done;342342+ /*343343+ * Don't cross an ADB or Cachline boundary when DMA'ing344344+ * completion entries. In PCI mode, at least in 32/33345345+ * configurations, the SCB DMA engine may lose its place346346+ * in the data-stream should the target force a retry on347347+ * something other than an 8byte aligned boundary. In348348+ * PCI-X mode, we do this to avoid split transactions since349349+ * many chipsets seem to be unable to format proper split350350+ * completions to continue the data transfer.351351+ */352352+ add SINDEX, A, CCSCBADDR;353353+ test SINDEX, CACHELINE_MASK jz fill_qoutfifo_done;380354 bmov SCBPTR, SCB_NEXT_COMPLETE, 2;381355 jmp fill_qoutfifo_loop;382356fill_qoutfifo_done:···404354 bmov SCBPTR, COMPLETE_DMA_SCB_HEAD, 2;405355 bmov SCBHADDR, SCB_BUSADDR, 4;406356 mvi CCARREN|CCSCBEN|CCSCBRESET jmp dma_scb;407407-END_CRITICAL;408357409358/*410359 * Either post or fetch an SCB from host memory. The caller···420371 mvi SCBHCNT, SCB_TRANSFER_SIZE;421372 mov CCSCBCTL, SINDEX ret;422373423423-BEGIN_CRITICAL;424374setjmp:425425- bmov LONGJMP_ADDR, STACK, 2 ret;375375+ /*376376+ * At least on the A, a return in the same377377+ * instruction as the bmov results in a return378378+ * to the caller, not to the new address at the379379+ * top of the stack. Since we want the latter380380+ * (we use setjmp to register a handler from an381381+ * interrupt context but not invoke that handler382382+ * until we return to our idle loop), use a383383+ * separate ret instruction.384384+ */385385+ bmov LONGJMP_ADDR, STACK, 2;386386+ ret;426387setjmp_inline:427388 bmov LONGJMP_ADDR, STACK, 2;428389longjmp:···450391set_mode_work_around:451392 mvi SEQINTCTL, INTVEC1DSL;452393 mov MODE_PTR, SINDEX;453453- clr SEQINTCTL ret;454454-455455-toggle_dff_mode_work_around:456456- mvi SEQINTCTL, INTVEC1DSL;457457- xor MODE_PTR, MK_MODE(M_DFF1, M_DFF1);458394 clr SEQINTCTL ret;459395}460396···544490SET_SRC_MODE M_SCSI;545491SET_DST_MODE M_SCSI;546492select_in:493493+ if ((ahd->bugs & AHD_FAINT_LED_BUG) != 0) {494494+ /*495495+ * On Rev A. hardware, the busy LED is only496496+ * turned on automaically during selections497497+ * and re-selections. Make the LED status498498+ * more useful by forcing it to be on from499499+ * the point of selection until our idle500500+ * loop determines that neither of our FIFOs501501+ * are busy. This handles the non-packetized502502+ * case nicely as we will not return to the503503+ * idle loop until the busfree at the end of504504+ * each transaction.505505+ */506506+ or SBLKCTL, DIAGLEDEN|DIAGLEDON;507507+ }547508 if ((ahd->bugs & AHD_BUSFREEREV_BUG) != 0) {548509 /*549510 * Test to ensure that the bus has not···597528SET_DST_MODE M_SCSI;598529select_out:599530BEGIN_CRITICAL;531531+ if ((ahd->bugs & AHD_FAINT_LED_BUG) != 0) {532532+ /*533533+ * On Rev A. hardware, the busy LED is only534534+ * turned on automaically during selections535535+ * and re-selections. Make the LED status536536+ * more useful by forcing it to be on from537537+ * the point of re-selection until our idle538538+ * loop determines that neither of our FIFOs539539+ * are busy. This handles the non-packetized540540+ * case nicely as we will not return to the541541+ * idle loop until the busfree at the end of542542+ * each transaction.543543+ */544544+ or SBLKCTL, DIAGLEDEN|DIAGLEDON;545545+ }600546 /* Clear out all SCBs that have been successfully sent. */601547 if ((ahd->bugs & AHD_SENT_SCB_UPDATE_BUG) != 0) {602548 /*···10841000/*10851001 * We received a "command complete" message. Put the SCB on the complete10861002 * queue and trigger a completion interrupt via the idle loop. Before doing10871087- * so, check to see if there10881088- * is a residual or the status byte is something other than STATUS_GOOD (0).10891089- * In either of these conditions, we upload the SCB back to the host so it can10901090- * process this information. In the case of a non zero status byte, we 10911091- * additionally interrupt the kernel driver synchronously, allowing it to10921092- * decide if sense should be retrieved. If the kernel driver wishes to request10931093- * sense, it will fill the kernel SCB with a request sense command, requeue10941094- * it to the QINFIFO and tell us not to post to the QOUTFIFO by setting 10951095- * RETURN_1 to SEND_SENSE.10031003+ * so, check to see if there is a residual or the status byte is something10041004+ * other than STATUS_GOOD (0). In either of these conditions, we upload the10051005+ * SCB back to the host so it can process this information.10961006 */10971007mesgin_complete:10981008···11311053 call queue_scb_completion;11321054 jmp await_busfree;1133105510561056+BEGIN_CRITICAL;11341057freeze_queue:11351058 /* Cancel any pending select-out. */11361059 test SSTAT0, SELDO|SELINGO jnz . + 2;···11421063 adc QFREEZE_COUNT[1], A;11431064 or SEQ_FLAGS2, SELECTOUT_QFROZEN;11441065 mov A, ACCUM_SAVE ret;10661066+END_CRITICAL;1145106711461068/*11471069 * Complete the current FIFO's SCB if data for this same···11651085 test SCB_SGPTR, SG_FULL_RESID jnz upload_scb;/* Never xfered */11661086 test SCB_RESIDUAL_SGPTR, SG_LIST_NULL jz upload_scb;11671087complete:10881088+BEGIN_CRITICAL;11681089 bmov SCB_NEXT_COMPLETE, COMPLETE_SCB_HEAD, 2;11691090 bmov COMPLETE_SCB_HEAD, SCBPTR, 2 ret;10911091+END_CRITICAL;11701092bad_status:11711093 cmp SCB_SCSI_STATUS, STATUS_PKT_SENSE je upload_scb;11721094 call freeze_queue;···11791097 * it on the host.11801098 */11811099 bmov SCB_TAG, SCBPTR, 2;11821182- bmov SCB_NEXT_COMPLETE, COMPLETE_DMA_SCB_HEAD, 2;11001100+BEGIN_CRITICAL;11011101+ or SCB_SGPTR, SG_STATUS_VALID;11021102+ mvi SCB_NEXT_COMPLETE[1], SCB_LIST_NULL;11031103+ cmp COMPLETE_DMA_SCB_HEAD[1], SCB_LIST_NULL jne add_dma_scb_tail;11831104 bmov COMPLETE_DMA_SCB_HEAD, SCBPTR, 2;11841184- or SCB_SGPTR, SG_STATUS_VALID ret;11051105+ bmov COMPLETE_DMA_SCB_TAIL, SCBPTR, 2 ret;11061106+add_dma_scb_tail:11071107+ bmov REG0, SCBPTR, 2;11081108+ bmov SCBPTR, COMPLETE_DMA_SCB_TAIL, 2;11091109+ bmov SCB_NEXT_COMPLETE, REG0, 2;11101110+ bmov COMPLETE_DMA_SCB_TAIL, REG0, 2 ret;11111111+END_CRITICAL;1185111211861113/*11871114 * Is it a disconnect message? Set a flag in the SCB to remind us···12371146await_busfree_clrchn:12381147 mvi DFFSXFRCTL, CLRCHN;12391148await_busfree_not_m_dff:12401240- call clear_target_state;11491149+ /* clear target specific flags */11501150+ mvi SEQ_FLAGS, NOT_IDENTIFIED|NO_CDB_SENT;12411151 test SSTAT1,REQINIT|BUSFREE jz .;11521152+ /*11531153+ * We only set BUSFREE status once either a new11541154+ * phase has been detected or we are really11551155+ * BUSFREE. This allows the driver to know11561156+ * that we are active on the bus even though11571157+ * no identified transaction exists should a11581158+ * timeout occur while awaiting busfree.11591159+ */11601160+ mvi LASTPHASE, P_BUSFREE;12421161 test SSTAT1, BUSFREE jnz idle_loop;12431162 SET_SEQINTCODE(MISSED_BUSFREE)12441163···13021201msgin_rdptrs_get_fifo:13031202 call allocate_fifo;13041203 jmp mesgin_done;13051305-13061306-clear_target_state:13071307- mvi LASTPHASE, P_BUSFREE;13081308- /* clear target specific flags */13091309- mvi SEQ_FLAGS, NOT_IDENTIFIED|NO_CDB_SENT ret;1310120413111205phase_lock: 13121206 if ((ahd->bugs & AHD_EARLY_REQ_BUG) != 0) {···13941298 test CCSGCTL, CCSGENACK jnz return;1395129913961300 /*13011301+ * Should the other FIFO get the S/G cache first? If13021302+ * both FIFOs have been allocated since we last checked13031303+ * any FIFO, it is important that we service a FIFO13041304+ * that is not actively on the bus first. This guarantees13051305+ * that a FIFO will be freed to handle snapshot requests for13061306+ * any FIFO that is still on the bus. Chips with RTI do not13071307+ * perform snapshots, so don't bother with this test there.13081308+ */13091309+ if ((ahd->features & AHD_RTI) == 0) {13101310+ /*13111311+ * If we're not still receiving SCSI data,13121312+ * it is safe to allocate the S/G cache to13131313+ * this FIFO.13141314+ */13151315+ test DFCNTRL, SCSIEN jz idle_sgfetch_start;13161316+13171317+ /*13181318+ * Switch to the other FIFO. Non-RTI chips13191319+ * also have the "set mode" bug, so we must13201320+ * disable interrupts during the switch.13211321+ */13221322+ mvi SEQINTCTL, INTVEC1DSL;13231323+ xor MODE_PTR, MK_MODE(M_DFF1, M_DFF1);13241324+13251325+ /*13261326+ * If the other FIFO needs loading, then it13271327+ * must not have claimed the S/G cache yet13281328+ * (SG_CACHE_AVAIL would have been cleared in13291329+ * the orginal FIFO mode and we test this above).13301330+ * Return to the idle loop so we can process the13311331+ * FIFO not currently on the bus first.13321332+ */13331333+ test SG_STATE, LOADING_NEEDED jz idle_sgfetch_okay;13341334+ clr SEQINTCTL ret;13351335+idle_sgfetch_okay:13361336+ xor MODE_PTR, MK_MODE(M_DFF1, M_DFF1);13371337+ clr SEQINTCTL;13381338+ }13391339+13401340+idle_sgfetch_start:13411341+ /*13971342 * We fetch a "cacheline aligned" and sized amount of data13981343 * so we don't end up referencing a non-existant page.13991344 * Cacheline aligned is in quotes because the kernel will···14451308 mvi SGHCNT, SG_PREFETCH_CNT;14461309 if ((ahd->bugs & AHD_REG_SLOW_SETTLE_BUG) != 0) {14471310 /*14481448- * Need two instruction between "touches" of SGHADDR.13111311+ * Need two instructions between "touches" of SGHADDR.14491312 */14501313 nop;14511314 }···17951658 * savepointer in the current FIFO. We do this so that17961659 * a pending CTXTDONE or SAVEPTR is visible in the active17971660 * FIFO. This status is the only way we can detect if we17981798- * have lost the race (e.g. host paused us) and our attepts16611661+ * have lost the race (e.g. host paused us) and our attempts17991662 * to disable the channel occurred after all REQs were18001663 * already seen and acked (REQINIT never comes true).18011664 */···18041667 test DFCNTRL, DIRECTION jz interrupt_return;18051668 and DFCNTRL, ~SCSIEN;18061669snapshot_wait_data_valid:18071807- test SEQINTSRC, (CTXTDONE|SAVEPTRS) jnz snapshot_data_valid;16701670+ test SEQINTSRC, (CTXTDONE|SAVEPTRS) jnz interrupt_return;18081671 test SSTAT1, REQINIT jz snapshot_wait_data_valid;18091672snapshot_data_valid:18101673 or DFCNTRL, SCSIEN;···19711834 dec SCB_FIFO_USE_COUNT;19721835 test SCB_CONTROL, STATUS_RCVD jnz pkt_complete_scb_if_fifos_idle;19731836 mvi DFFSXFRCTL, CLRCHN ret;19741974-END_CRITICAL;1975183719761838/*19771839 * LAST_SEG_DONE status has been seen in the current FIFO.···19791843 * Check for overrun and see if we can complete this command.19801844 */19811845pkt_last_seg_done:19821982-BEGIN_CRITICAL;19831846 /*19841847 * Mark transfer as completed.19851848 */
+418-365
drivers/scsi/aic7xxx/aic79xx_core.c
···3737 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE3838 * POSSIBILITY OF SUCH DAMAGES.3939 *4040- * $Id: //depot/aic7xxx/aic7xxx/aic79xx.c#202 $4141- *4242- * $FreeBSD$4040+ * $Id: //depot/aic7xxx/aic7xxx/aic79xx.c#247 $4341 */44424543#ifdef __linux__···330332 ahd_outb(ahd, SCSISEQ1,331333 ahd_inb(ahd, SCSISEQ_TEMPLATE) & (ENSELI|ENRSELI|ENAUTOATNP));332334 ahd_set_modes(ahd, AHD_MODE_CCHAN, AHD_MODE_CCHAN);335335+336336+ /*337337+ * Clear any pending sequencer interrupt. It is no338338+ * longer relevant since we're resetting the Program339339+ * Counter.340340+ */341341+ ahd_outb(ahd, CLRINT, CLRSEQINT);342342+333343 ahd_outb(ahd, SEQCTL0, FASTMODE|SEQRESET);334344 ahd_unpause(ahd);335345}···379373 saved_modes = ahd_save_modes(ahd);380374381375 /*382382- * Complete any SCBs that just finished being383383- * DMA'ed into the qoutfifo.384384- */385385- ahd_run_qoutfifo(ahd);386386-387387- /*388388- * Flush the good status FIFO for compelted packetized commands.376376+ * Flush the good status FIFO for completed packetized commands.389377 */390378 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);391379 saved_scbptr = ahd_get_scbptr(ahd);···387387 u_int fifo_mode;388388 u_int i;389389390390- scbid = (ahd_inb(ahd, GSFIFO+1) << 8)391391- | ahd_inb(ahd, GSFIFO);390390+ scbid = ahd_inw(ahd, GSFIFO);392391 scb = ahd_lookup_scb(ahd, scbid);393392 if (scb == NULL) {394393 printf("%s: Warning - GSFIFO SCB %d invalid\n",···400401 * the host before completing the command.401402 */402403 fifo_mode = 0;404404+rescan_fifos:403405 for (i = 0; i < 2; i++) {404406 /* Toggle to the other mode. */405407 fifo_mode ^= 1;406408 ahd_set_modes(ahd, fifo_mode, fifo_mode);409409+407410 if (ahd_scb_active_in_fifo(ahd, scb) == 0)408411 continue;409412410413 ahd_run_data_fifo(ahd, scb);411414412415 /*413413- * Clearing this transaction in this FIFO may414414- * cause a CFG4DATA for this same transaction415415- * to assert in the other FIFO. Make sure we416416- * loop one more time and check the other FIFO.416416+ * Running this FIFO may cause a CFG4DATA for417417+ * this same transaction to assert in the other418418+ * FIFO or a new snapshot SAVEPTRS interrupt419419+ * in this FIFO. Even running a FIFO may not420420+ * clear the transaction if we are still waiting421421+ * for data to drain to the host. We must loop422422+ * until the transaction is not active in either423423+ * FIFO just to be sure. Reset our loop counter424424+ * so we will visit both FIFOs again before425425+ * declaring this transaction finished. We426426+ * also delay a bit so that status has a chance427427+ * to change before we look at this FIFO again.417428 */418418- i = 0;429429+ ahd_delay(200);430430+ goto rescan_fifos;419431 }420432 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);421433 ahd_set_scbptr(ahd, scbid);···439429 /*440430 * The transfer completed with a residual.441431 * Place this SCB on the complete DMA list442442- * so that we Update our in-core copy of the432432+ * so that we update our in-core copy of the443433 * SCB before completing the command.444434 */445435 ahd_outb(ahd, SCB_SCSI_STATUS, 0);446436 ahd_outb(ahd, SCB_SGPTR,447437 ahd_inb_scbram(ahd, SCB_SGPTR)448438 | SG_STATUS_VALID);449449- ahd_outw(ahd, SCB_TAG, SCB_GET_TAG(scb));439439+ ahd_outw(ahd, SCB_TAG, scbid);440440+ ahd_outw(ahd, SCB_NEXT_COMPLETE, SCB_LIST_NULL);450441 comp_head = ahd_inw(ahd, COMPLETE_DMA_SCB_HEAD);451451- ahd_outw(ahd, SCB_NEXT_COMPLETE, comp_head);452452- if (SCBID_IS_NULL(comp_head))453453- ahd_outw(ahd, COMPLETE_DMA_SCB_HEAD,454454- SCB_GET_TAG(scb));442442+ if (SCBID_IS_NULL(comp_head)) {443443+ ahd_outw(ahd, COMPLETE_DMA_SCB_HEAD, scbid);444444+ ahd_outw(ahd, COMPLETE_DMA_SCB_TAIL, scbid);445445+ } else {446446+ u_int tail;447447+448448+ tail = ahd_inw(ahd, COMPLETE_DMA_SCB_TAIL);449449+ ahd_set_scbptr(ahd, tail);450450+ ahd_outw(ahd, SCB_NEXT_COMPLETE, scbid);451451+ ahd_outw(ahd, COMPLETE_DMA_SCB_TAIL, scbid);452452+ ahd_set_scbptr(ahd, scbid);453453+ }455454 } else456455 ahd_complete_scb(ahd, scb);457456 }···484465 break;485466 ahd_delay(200);486467 }487487- if ((ccscbctl & CCSCBDIR) != 0)468468+ /*469469+ * We leave the sequencer to cleanup in the case of DMA's to470470+ * update the qoutfifo. In all other cases (DMA's to the471471+ * chip or a push of an SCB from the COMPLETE_DMA_SCB list),472472+ * we disable the DMA engine so that the sequencer will not473473+ * attempt to handle the DMA completion.474474+ */475475+ if ((ccscbctl & CCSCBDIR) != 0 || (ccscbctl & ARRDONE) != 0)488476 ahd_outb(ahd, CCSCBCTL, ccscbctl & ~(CCARREN|CCSCBEN));477477+478478+ /*479479+ * Complete any SCBs that just finished480480+ * being DMA'ed into the qoutfifo.481481+ */482482+ ahd_run_qoutfifo(ahd);489483490484 saved_scbptr = ahd_get_scbptr(ahd);491485 /*···526494 scbid = next_scbid;527495 }528496 ahd_outw(ahd, COMPLETE_DMA_SCB_HEAD, SCB_LIST_NULL);497497+ ahd_outw(ahd, COMPLETE_DMA_SCB_TAIL, SCB_LIST_NULL);498498+499499+ scbid = ahd_inw(ahd, COMPLETE_ON_QFREEZE_HEAD);500500+ while (!SCBID_IS_NULL(scbid)) {501501+502502+ ahd_set_scbptr(ahd, scbid);503503+ next_scbid = ahd_inw_scbram(ahd, SCB_NEXT_COMPLETE);504504+ scb = ahd_lookup_scb(ahd, scbid);505505+ if (scb == NULL) {506506+ printf("%s: Warning - Complete Qfrz SCB %d invalid\n",507507+ ahd_name(ahd), scbid);508508+ continue;509509+ }510510+511511+ ahd_complete_scb(ahd, scb);512512+ scbid = next_scbid;513513+ }514514+ ahd_outw(ahd, COMPLETE_ON_QFREEZE_HEAD, SCB_LIST_NULL);529515530516 scbid = ahd_inw(ahd, COMPLETE_SCB_HEAD);531517 while (!SCBID_IS_NULL(scbid)) {···608558{609559 u_int seqintsrc;610560611611- while (1) {612612- seqintsrc = ahd_inb(ahd, SEQINTSRC);613613- if ((seqintsrc & CFG4DATA) != 0) {614614- uint32_t datacnt;615615- uint32_t sgptr;561561+ seqintsrc = ahd_inb(ahd, SEQINTSRC);562562+ if ((seqintsrc & CFG4DATA) != 0) {563563+ uint32_t datacnt;564564+ uint32_t sgptr;616565617617- /*618618- * Clear full residual flag.619619- */620620- sgptr = ahd_inl_scbram(ahd, SCB_SGPTR) & ~SG_FULL_RESID;621621- ahd_outb(ahd, SCB_SGPTR, sgptr);566566+ /*567567+ * Clear full residual flag.568568+ */569569+ sgptr = ahd_inl_scbram(ahd, SCB_SGPTR) & ~SG_FULL_RESID;570570+ ahd_outb(ahd, SCB_SGPTR, sgptr);622571623623- /*624624- * Load datacnt and address.625625- */626626- datacnt = ahd_inl_scbram(ahd, SCB_DATACNT);627627- if ((datacnt & AHD_DMA_LAST_SEG) != 0) {628628- sgptr |= LAST_SEG;629629- ahd_outb(ahd, SG_STATE, 0);630630- } else631631- ahd_outb(ahd, SG_STATE, LOADING_NEEDED);632632- ahd_outq(ahd, HADDR, ahd_inq_scbram(ahd, SCB_DATAPTR));633633- ahd_outl(ahd, HCNT, datacnt & AHD_SG_LEN_MASK);634634- ahd_outb(ahd, SG_CACHE_PRE, sgptr);635635- ahd_outb(ahd, DFCNTRL, PRELOADEN|SCSIEN|HDMAEN);636636-637637- /*638638- * Initialize Residual Fields.639639- */640640- ahd_outb(ahd, SCB_RESIDUAL_DATACNT+3, datacnt >> 24);641641- ahd_outl(ahd, SCB_RESIDUAL_SGPTR, sgptr & SG_PTR_MASK);642642-643643- /*644644- * Mark the SCB as having a FIFO in use.645645- */646646- ahd_outb(ahd, SCB_FIFO_USE_COUNT,647647- ahd_inb_scbram(ahd, SCB_FIFO_USE_COUNT) + 1);648648-649649- /*650650- * Install a "fake" handler for this FIFO.651651- */652652- ahd_outw(ahd, LONGJMP_ADDR, 0);653653-654654- /*655655- * Notify the hardware that we have satisfied656656- * this sequencer interrupt.657657- */658658- ahd_outb(ahd, CLRSEQINTSRC, CLRCFG4DATA);659659- } else if ((seqintsrc & SAVEPTRS) != 0) {660660- uint32_t sgptr;661661- uint32_t resid;662662-663663- if ((ahd_inb(ahd, LONGJMP_ADDR+1)&INVALID_ADDR) != 0) {664664- /*665665- * Snapshot Save Pointers. Clear666666- * the snapshot and continue.667667- */668668- ahd_outb(ahd, DFFSXFRCTL, CLRCHN);669669- continue;670670- }671671-672672- /*673673- * Disable S/G fetch so the DMA engine674674- * is available to future users.675675- */676676- if ((ahd_inb(ahd, SG_STATE) & FETCH_INPROG) != 0)677677- ahd_outb(ahd, CCSGCTL, 0);572572+ /*573573+ * Load datacnt and address.574574+ */575575+ datacnt = ahd_inl_scbram(ahd, SCB_DATACNT);576576+ if ((datacnt & AHD_DMA_LAST_SEG) != 0) {577577+ sgptr |= LAST_SEG;678578 ahd_outb(ahd, SG_STATE, 0);579579+ } else580580+ ahd_outb(ahd, SG_STATE, LOADING_NEEDED);581581+ ahd_outq(ahd, HADDR, ahd_inq_scbram(ahd, SCB_DATAPTR));582582+ ahd_outl(ahd, HCNT, datacnt & AHD_SG_LEN_MASK);583583+ ahd_outb(ahd, SG_CACHE_PRE, sgptr);584584+ ahd_outb(ahd, DFCNTRL, PRELOADEN|SCSIEN|HDMAEN);679585680680- /*681681- * Flush the data FIFO. Strickly only682682- * necessary for Rev A parts.683683- */684684- ahd_outb(ahd, DFCNTRL,685685- ahd_inb(ahd, DFCNTRL) | FIFOFLUSH);586586+ /*587587+ * Initialize Residual Fields.588588+ */589589+ ahd_outb(ahd, SCB_RESIDUAL_DATACNT+3, datacnt >> 24);590590+ ahd_outl(ahd, SCB_RESIDUAL_SGPTR, sgptr & SG_PTR_MASK);686591687687- /*688688- * Calculate residual.689689- */690690- sgptr = ahd_inl_scbram(ahd, SCB_RESIDUAL_SGPTR);691691- resid = ahd_inl(ahd, SHCNT);692692- resid |=693693- ahd_inb_scbram(ahd, SCB_RESIDUAL_DATACNT+3) << 24;694694- ahd_outl(ahd, SCB_RESIDUAL_DATACNT, resid);695695- if ((ahd_inb(ahd, SG_CACHE_SHADOW) & LAST_SEG) == 0) {696696- /*697697- * Must back up to the correct S/G element.698698- * Typically this just means resetting our699699- * low byte to the offset in the SG_CACHE,700700- * but if we wrapped, we have to correct701701- * the other bytes of the sgptr too.702702- */703703- if ((ahd_inb(ahd, SG_CACHE_SHADOW) & 0x80) != 0704704- && (sgptr & 0x80) == 0)705705- sgptr -= 0x100;706706- sgptr &= ~0xFF;707707- sgptr |= ahd_inb(ahd, SG_CACHE_SHADOW)708708- & SG_ADDR_MASK;709709- ahd_outl(ahd, SCB_RESIDUAL_SGPTR, sgptr);710710- ahd_outb(ahd, SCB_RESIDUAL_DATACNT + 3, 0);711711- } else if ((resid & AHD_SG_LEN_MASK) == 0) {712712- ahd_outb(ahd, SCB_RESIDUAL_SGPTR,713713- sgptr | SG_LIST_NULL);714714- }715715- /*716716- * Save Pointers.717717- */718718- ahd_outq(ahd, SCB_DATAPTR, ahd_inq(ahd, SHADDR));719719- ahd_outl(ahd, SCB_DATACNT, resid);720720- ahd_outl(ahd, SCB_SGPTR, sgptr);721721- ahd_outb(ahd, CLRSEQINTSRC, CLRSAVEPTRS);722722- ahd_outb(ahd, SEQIMODE,723723- ahd_inb(ahd, SEQIMODE) | ENSAVEPTRS);724724- /*725725- * If the data is to the SCSI bus, we are726726- * done, otherwise wait for FIFOEMP.727727- */728728- if ((ahd_inb(ahd, DFCNTRL) & DIRECTION) != 0)729729- break;730730- } else if ((ahd_inb(ahd, SG_STATE) & LOADING_NEEDED) != 0) {731731- uint32_t sgptr;732732- uint64_t data_addr;733733- uint32_t data_len;734734- u_int dfcntrl;592592+ /*593593+ * Mark the SCB as having a FIFO in use.594594+ */595595+ ahd_outb(ahd, SCB_FIFO_USE_COUNT,596596+ ahd_inb_scbram(ahd, SCB_FIFO_USE_COUNT) + 1);735597736736- /*737737- * Disable S/G fetch so the DMA engine738738- * is available to future users.739739- */740740- if ((ahd_inb(ahd, SG_STATE) & FETCH_INPROG) != 0) {741741- ahd_outb(ahd, CCSGCTL, 0);742742- ahd_outb(ahd, SG_STATE, LOADING_NEEDED);743743- }598598+ /*599599+ * Install a "fake" handler for this FIFO.600600+ */601601+ ahd_outw(ahd, LONGJMP_ADDR, 0);744602603603+ /*604604+ * Notify the hardware that we have satisfied605605+ * this sequencer interrupt.606606+ */607607+ ahd_outb(ahd, CLRSEQINTSRC, CLRCFG4DATA);608608+ } else if ((seqintsrc & SAVEPTRS) != 0) {609609+ uint32_t sgptr;610610+ uint32_t resid;611611+612612+ if ((ahd_inb(ahd, LONGJMP_ADDR+1)&INVALID_ADDR) != 0) {745613 /*746746- * Wait for the DMA engine to notice that the747747- * host transfer is enabled and that there is748748- * space in the S/G FIFO for new segments before749749- * loading more segments.614614+ * Snapshot Save Pointers. All that615615+ * is necessary to clear the snapshot616616+ * is a CLRCHN.750617 */751751- if ((ahd_inb(ahd, DFSTATUS) & PRELOAD_AVAIL) == 0)752752- continue;753753- if ((ahd_inb(ahd, DFCNTRL) & HDMAENACK) == 0)754754- continue;618618+ goto clrchn;619619+ }620620+621621+ /*622622+ * Disable S/G fetch so the DMA engine623623+ * is available to future users.624624+ */625625+ if ((ahd_inb(ahd, SG_STATE) & FETCH_INPROG) != 0)626626+ ahd_outb(ahd, CCSGCTL, 0);627627+ ahd_outb(ahd, SG_STATE, 0);628628+629629+ /*630630+ * Flush the data FIFO. Strickly only631631+ * necessary for Rev A parts.632632+ */633633+ ahd_outb(ahd, DFCNTRL, ahd_inb(ahd, DFCNTRL) | FIFOFLUSH);634634+635635+ /*636636+ * Calculate residual.637637+ */638638+ sgptr = ahd_inl_scbram(ahd, SCB_RESIDUAL_SGPTR);639639+ resid = ahd_inl(ahd, SHCNT);640640+ resid |= ahd_inb_scbram(ahd, SCB_RESIDUAL_DATACNT+3) << 24;641641+ ahd_outl(ahd, SCB_RESIDUAL_DATACNT, resid);642642+ if ((ahd_inb(ahd, SG_CACHE_SHADOW) & LAST_SEG) == 0) {643643+ /*644644+ * Must back up to the correct S/G element.645645+ * Typically this just means resetting our646646+ * low byte to the offset in the SG_CACHE,647647+ * but if we wrapped, we have to correct648648+ * the other bytes of the sgptr too.649649+ */650650+ if ((ahd_inb(ahd, SG_CACHE_SHADOW) & 0x80) != 0651651+ && (sgptr & 0x80) == 0)652652+ sgptr -= 0x100;653653+ sgptr &= ~0xFF;654654+ sgptr |= ahd_inb(ahd, SG_CACHE_SHADOW)655655+ & SG_ADDR_MASK;656656+ ahd_outl(ahd, SCB_RESIDUAL_SGPTR, sgptr);657657+ ahd_outb(ahd, SCB_RESIDUAL_DATACNT + 3, 0);658658+ } else if ((resid & AHD_SG_LEN_MASK) == 0) {659659+ ahd_outb(ahd, SCB_RESIDUAL_SGPTR,660660+ sgptr | SG_LIST_NULL);661661+ }662662+ /*663663+ * Save Pointers.664664+ */665665+ ahd_outq(ahd, SCB_DATAPTR, ahd_inq(ahd, SHADDR));666666+ ahd_outl(ahd, SCB_DATACNT, resid);667667+ ahd_outl(ahd, SCB_SGPTR, sgptr);668668+ ahd_outb(ahd, CLRSEQINTSRC, CLRSAVEPTRS);669669+ ahd_outb(ahd, SEQIMODE,670670+ ahd_inb(ahd, SEQIMODE) | ENSAVEPTRS);671671+ /*672672+ * If the data is to the SCSI bus, we are673673+ * done, otherwise wait for FIFOEMP.674674+ */675675+ if ((ahd_inb(ahd, DFCNTRL) & DIRECTION) != 0)676676+ goto clrchn;677677+ } else if ((ahd_inb(ahd, SG_STATE) & LOADING_NEEDED) != 0) {678678+ uint32_t sgptr;679679+ uint64_t data_addr;680680+ uint32_t data_len;681681+ u_int dfcntrl;682682+683683+ /*684684+ * Disable S/G fetch so the DMA engine685685+ * is available to future users. We won't686686+ * be using the DMA engine to load segments.687687+ */688688+ if ((ahd_inb(ahd, SG_STATE) & FETCH_INPROG) != 0) {689689+ ahd_outb(ahd, CCSGCTL, 0);690690+ ahd_outb(ahd, SG_STATE, LOADING_NEEDED);691691+ }692692+693693+ /*694694+ * Wait for the DMA engine to notice that the695695+ * host transfer is enabled and that there is696696+ * space in the S/G FIFO for new segments before697697+ * loading more segments.698698+ */699699+ if ((ahd_inb(ahd, DFSTATUS) & PRELOAD_AVAIL) != 0700700+ && (ahd_inb(ahd, DFCNTRL) & HDMAENACK) != 0) {755701756702 /*757703 * Determine the offset of the next S/G···794748 * Advertise the segment to the hardware.795749 */796750 dfcntrl = ahd_inb(ahd, DFCNTRL)|PRELOADEN|HDMAEN;797797- if ((ahd->features & AHD_NEW_DFCNTRL_OPTS)!=0) {751751+ if ((ahd->features & AHD_NEW_DFCNTRL_OPTS) != 0) {798752 /*799753 * Use SCSIENWRDIS so that SCSIEN800754 * is never modified by this···803757 dfcntrl |= SCSIENWRDIS;804758 }805759 ahd_outb(ahd, DFCNTRL, dfcntrl);806806- } else if ((ahd_inb(ahd, SG_CACHE_SHADOW)807807- & LAST_SEG_DONE) != 0) {808808-809809- /*810810- * Transfer completed to the end of SG list811811- * and has flushed to the host.812812- */813813- ahd_outb(ahd, SCB_SGPTR,814814- ahd_inb_scbram(ahd, SCB_SGPTR) | SG_LIST_NULL);815815- break;816816- } else if ((ahd_inb(ahd, DFSTATUS) & FIFOEMP) != 0) {817817- break;818760 }819819- ahd_delay(200);761761+ } else if ((ahd_inb(ahd, SG_CACHE_SHADOW) & LAST_SEG_DONE) != 0) {762762+763763+ /*764764+ * Transfer completed to the end of SG list765765+ * and has flushed to the host.766766+ */767767+ ahd_outb(ahd, SCB_SGPTR,768768+ ahd_inb_scbram(ahd, SCB_SGPTR) | SG_LIST_NULL);769769+ goto clrchn;770770+ } else if ((ahd_inb(ahd, DFSTATUS) & FIFOEMP) != 0) {771771+clrchn:772772+ /*773773+ * Clear any handler for this FIFO, decrement774774+ * the FIFO use count for the SCB, and release775775+ * the FIFO.776776+ */777777+ ahd_outb(ahd, LONGJMP_ADDR + 1, INVALID_ADDR);778778+ ahd_outb(ahd, SCB_FIFO_USE_COUNT,779779+ ahd_inb_scbram(ahd, SCB_FIFO_USE_COUNT) - 1);780780+ ahd_outb(ahd, DFFSXFRCTL, CLRCHN);820781 }821821- /*822822- * Clear any handler for this FIFO, decrement823823- * the FIFO use count for the SCB, and release824824- * the FIFO.825825- */826826- ahd_outb(ahd, LONGJMP_ADDR + 1, INVALID_ADDR);827827- ahd_outb(ahd, SCB_FIFO_USE_COUNT,828828- ahd_inb_scbram(ahd, SCB_FIFO_USE_COUNT) - 1);829829- ahd_outb(ahd, DFFSXFRCTL, CLRCHN);830782}831783784784+/*785785+ * Look for entries in the QoutFIFO that have completed.786786+ * The valid_tag completion field indicates the validity787787+ * of the entry - the valid value toggles each time through788788+ * the queue. We use the sg_status field in the completion789789+ * entry to avoid referencing the hscb if the completion790790+ * occurred with no errors and no residual. sg_status is791791+ * a copy of the first byte (little endian) of the sgptr792792+ * hscb field.793793+ */832794void833795ahd_run_qoutfifo(struct ahd_softc *ahd)834796{797797+ struct ahd_completion *completion;835798 struct scb *scb;836799 u_int scb_index;837800···848793 panic("ahd_run_qoutfifo recursion");849794 ahd->flags |= AHD_RUNNING_QOUTFIFO;850795 ahd_sync_qoutfifo(ahd, BUS_DMASYNC_POSTREAD);851851- while ((ahd->qoutfifo[ahd->qoutfifonext]852852- & QOUTFIFO_ENTRY_VALID_LE) == ahd->qoutfifonext_valid_tag) {796796+ for (;;) {797797+ completion = &ahd->qoutfifo[ahd->qoutfifonext];853798854854- scb_index = ahd_le16toh(ahd->qoutfifo[ahd->qoutfifonext]855855- & ~QOUTFIFO_ENTRY_VALID_LE);799799+ if (completion->valid_tag != ahd->qoutfifonext_valid_tag)800800+ break;801801+802802+ scb_index = ahd_le16toh(completion->tag);856803 scb = ahd_lookup_scb(ahd, scb_index);857804 if (scb == NULL) {858805 printf("%s: WARNING no command for scb %d "···862805 ahd_name(ahd), scb_index,863806 ahd->qoutfifonext);864807 ahd_dump_card_state(ahd);865865- } else866866- ahd_complete_scb(ahd, scb);808808+ } else if ((completion->sg_status & SG_STATUS_VALID) != 0) {809809+ ahd_handle_scb_status(ahd, scb);810810+ } else {811811+ ahd_done(ahd, scb);812812+ }867813868814 ahd->qoutfifonext = (ahd->qoutfifonext+1) & (AHD_QOUT_SIZE-1);869815 if (ahd->qoutfifonext == 0)870870- ahd->qoutfifonext_valid_tag ^= QOUTFIFO_ENTRY_VALID_LE;816816+ ahd->qoutfifonext_valid_tag ^= QOUTFIFO_ENTRY_VALID;871817 }872818 ahd->flags &= ~AHD_RUNNING_QOUTFIFO;873819}···936876 ahd_name(ahd), seqintcode);937877#endif938878 switch (seqintcode) {939939- case BAD_SCB_STATUS:940940- {941941- struct scb *scb;942942- u_int scbid;943943- int cmds_pending;944944-945945- scbid = ahd_get_scbptr(ahd);946946- scb = ahd_lookup_scb(ahd, scbid);947947- if (scb != NULL) {948948- ahd_complete_scb(ahd, scb);949949- } else {950950- printf("%s: WARNING no command for scb %d "951951- "(bad status)\n", ahd_name(ahd), scbid);952952- ahd_dump_card_state(ahd);953953- }954954- cmds_pending = ahd_inw(ahd, CMDS_PENDING);955955- if (cmds_pending > 0)956956- ahd_outw(ahd, CMDS_PENDING, cmds_pending - 1);957957- break;958958- }959879 case ENTERING_NONPACK:960880 {961881 struct scb *scb;···11001060 ahd_outb(ahd, SAVED_LUN, 0);11011061 ahd_outb(ahd, SEQ_FLAGS, 0);11021062 ahd_assert_atn(ahd);11031103- scb->flags &= ~(SCB_PACKETIZED);10631063+ scb->flags &= ~SCB_PACKETIZED;11041064 scb->flags |= SCB_ABORT|SCB_CMDPHASE_ABORT;11051065 ahd_freeze_devq(ahd, scb);11061066 ahd_set_transaction_status(scb, CAM_REQUEUE_REQ);···15431503 && (ahd_inb(ahd, SEQ_FLAGS) & NOT_IDENTIFIED) != 0)15441504 scb = NULL;1545150515461546- /* Make sure the sequencer is in a safe location. */15471547- ahd_clear_critical_section(ahd);15481548-15491506 if ((status0 & IOERR) != 0) {15501507 u_int now_lvd;15511508···15581521 ahd_setup_iocell_workaround(ahd);15591522 ahd_unpause(ahd);15601523 } else if ((status0 & OVERRUN) != 0) {15241524+15611525 printf("%s: SCSI offset overrun detected. Resetting bus.\n",15621526 ahd_name(ahd));15631527 ahd_reset_channel(ahd, 'A', /*Initiate Reset*/TRUE);15641528 } else if ((status & SCSIRSTI) != 0) {15291529+15651530 printf("%s: Someone reset channel A\n", ahd_name(ahd));15661531 ahd_reset_channel(ahd, 'A', /*Initiate Reset*/FALSE);15671532 } else if ((status & SCSIPERR) != 0) {15331533+15341534+ /* Make sure the sequencer is in a safe location. */15351535+ ahd_clear_critical_section(ahd);15361536+15681537 ahd_handle_transmission_error(ahd);15691538 } else if (lqostat0 != 0) {15391539+15701540 printf("%s: lqostat0 == 0x%x!\n", ahd_name(ahd), lqostat0);15711541 ahd_outb(ahd, CLRLQOINT0, lqostat0);15721572- if ((ahd->bugs & AHD_CLRLQO_AUTOCLR_BUG) != 0) {15421542+ if ((ahd->bugs & AHD_CLRLQO_AUTOCLR_BUG) != 0)15731543 ahd_outb(ahd, CLRLQOINT1, 0);15741574- }15751544 } else if ((status & SELTO) != 0) {15761545 u_int scbid;1577154615781547 /* Stop the selection */15791548 ahd_outb(ahd, SCSISEQ0, 0);15491549+15501550+ /* Make sure the sequencer is in a safe location. */15511551+ ahd_clear_critical_section(ahd);1580155215811553 /* No more pending messages */15821554 ahd_clear_msg_state(ahd);···16191573 scbid);16201574 }16211575#endif16221622- /*16231623- * Force a renegotiation with this target just in16241624- * case the cable was pulled and will later be16251625- * re-attached. The target may forget its negotiation16261626- * settings with us should it attempt to reselect16271627- * during the interruption. The target will not issue16281628- * a unit attention in this case, so we must always16291629- * renegotiate.16301630- */16311576 ahd_scb_devinfo(ahd, &devinfo, scb);16321632- ahd_force_renegotiation(ahd, &devinfo);16331577 ahd_set_transaction_status(scb, CAM_SEL_TIMEOUT);16341578 ahd_freeze_devq(ahd, scb);15791579+15801580+ /*15811581+ * Cancel any pending transactions on the device15821582+ * now that it seems to be missing. This will15831583+ * also revert us to async/narrow transfers until15841584+ * we can renegotiate with the device.15851585+ */15861586+ ahd_handle_devreset(ahd, &devinfo,15871587+ CAM_LUN_WILDCARD,15881588+ CAM_SEL_TIMEOUT,15891589+ "Selection Timeout",15901590+ /*verbose_level*/1);16351591 }16361592 ahd_outb(ahd, CLRINT, CLRSCSIINT);16371593 ahd_iocell_first_selection(ahd);16381594 ahd_unpause(ahd);16391595 } else if ((status0 & (SELDI|SELDO)) != 0) {15961596+16401597 ahd_iocell_first_selection(ahd);16411598 ahd_unpause(ahd);16421599 } else if (status3 != 0) {···16471598 ahd_name(ahd), status3);16481599 ahd_outb(ahd, CLRSINT3, status3);16491600 } else if ((lqistat1 & (LQIPHASE_LQ|LQIPHASE_NLQ)) != 0) {16011601+16021602+ /* Make sure the sequencer is in a safe location. */16031603+ ahd_clear_critical_section(ahd);16041604+16501605 ahd_handle_lqiphase_error(ahd, lqistat1);16511606 } else if ((lqistat1 & LQICRCI_NLQ) != 0) {16521607 /*···16741621 * go about selecting the target while we handle the event.16751622 */16761623 ahd_outb(ahd, SCSISEQ0, 0);16241624+16251625+ /* Make sure the sequencer is in a safe location. */16261626+ ahd_clear_critical_section(ahd);1677162716781628 /*16791629 * Determine what we were up to at the time of···17151659 clear_fifo = 0;17161660 packetized = (lqostat1 & LQOBUSFREE) != 0;17171661 if (!packetized17181718- && ahd_inb(ahd, LASTPHASE) == P_BUSFREE)16621662+ && ahd_inb(ahd, LASTPHASE) == P_BUSFREE16631663+ && (ahd_inb(ahd, SSTAT0) & SELDI) == 016641664+ && ((ahd_inb(ahd, SSTAT0) & SELDO) == 016651665+ || (ahd_inb(ahd, SCSISEQ0) & ENSELO) == 0))16661666+ /*16671667+ * Assume packetized if we are not16681668+ * on the bus in a non-packetized16691669+ * capacity and any pending selection16701670+ * was a packetized selection.16711671+ */17191672 packetized = 1;17201673 break;17211674 }···23752310 "PRGMCNT == 0x%x\n",23762311 ahd_lookup_phase_entry(lastphase)->phasemsg,23772312 aborted,23782378- ahd_inb(ahd, PRGMCNT)23792379- | (ahd_inb(ahd, PRGMCNT+1) << 8));23132313+ ahd_inw(ahd, PRGMCNT));23802314 ahd_dump_card_state(ahd);23812315 }23822316 /* Always restart the sequencer. */···25382474 u_int i;2539247525402476 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);25412541- seqaddr = ahd_inb(ahd, CURADDR)25422542- | (ahd_inb(ahd, CURADDR+1) << 8);24772477+ seqaddr = ahd_inw(ahd, CURADDR);2543247825442479 cs = ahd->critical_sections;25452480 for (i = 0; i < ahd->num_critical_sections; i++, cs++) {···32593196 iocell_opts[AHD_PRECOMP_SLEW_INDEX] &= ~AHD_PRECOMP_MASK;3260319732613198 if ((ahd->features & AHD_NEW_IOCELL_OPTS) != 032623262- && (ppr_opts & MSG_EXT_PPR_DT_REQ) != 0) {31993199+ && (ppr_opts & MSG_EXT_PPR_DT_REQ) != 032003200+ && (ppr_opts & MSG_EXT_PPR_IU_REQ) == 0) {32633201 /*32643202 * Slow down our CRC interval to be32653265- * compatible with devices that can't32663266- * handle a CRC at full speed.32033203+ * compatible with non-packetized32043204+ * U160 devices that can't handle a32053205+ * CRC at full speed.32673206 */32683207 con_opts |= ENSLOWCRC;32083208+ }32093209+32103210+ if ((ahd->bugs & AHD_PACED_NEGTABLE_BUG) != 0) {32113211+ /*32123212+ * On H2A4, revert to a slower slewrate32133213+ * on non-paced transfers.32143214+ */32153215+ iocell_opts[AHD_PRECOMP_SLEW_INDEX] &=32163216+ ~AHD_SLEWRATE_MASK;32693217 }32703218 }32713219···33663292 * Force the sequencer to reinitialize the selection for33673293 * the command at the head of the execution queue if it33683294 * has already been setup. The negotiation changes may33693369- * effect whether we select-out with ATN.32953295+ * effect whether we select-out with ATN. It is only32963296+ * safe to clear ENSELO when the bus is not free and no32973297+ * selection is in progres or completed.33703298 */33713299 saved_modes = ahd_save_modes(ahd);33723300 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);33733373- ahd_outb(ahd, SCSISEQ0, ahd_inb(ahd, SCSISEQ0) & ~ENSELO);33013301+ if ((ahd_inb(ahd, SCSISIGI) & BSYI) != 033023302+ && (ahd_inb(ahd, SSTAT0) & (SELDO|SELINGO)) == 0)33033303+ ahd_outb(ahd, SCSISEQ0, ahd_inb(ahd, SCSISEQ0) & ~ENSELO);33743304 saved_scbptr = ahd_get_scbptr(ahd);33753305 /* Ensure that the hscbs down on the card match the new information */33763306 for (scb_tag = 0; scb_tag < ahd->scb_data.maxhscbs; scb_tag++) {···49874909 * Determine initial values for data_addr and data_cnt49884910 * for resuming the data phase.49894911 */49904990- sgptr = (ahd_inb_scbram(ahd, SCB_RESIDUAL_SGPTR + 3) << 24)49914991- | (ahd_inb_scbram(ahd, SCB_RESIDUAL_SGPTR + 2) << 16)49924992- | (ahd_inb_scbram(ahd, SCB_RESIDUAL_SGPTR + 1) << 8)49934993- | ahd_inb_scbram(ahd, SCB_RESIDUAL_SGPTR);49124912+ sgptr = ahd_inl_scbram(ahd, SCB_RESIDUAL_SGPTR);49944913 sgptr &= SG_PTR_MASK;4995491449964915 resid = (ahd_inb_scbram(ahd, SCB_RESIDUAL_DATACNT + 2) << 16)···50054930 dataptr = ahd_le64toh(sg->addr)50064931 + (ahd_le32toh(sg->len) & AHD_SG_LEN_MASK)50074932 - resid;50085008- ahd_outb(ahd, HADDR + 7, dataptr >> 56);50095009- ahd_outb(ahd, HADDR + 6, dataptr >> 48);50105010- ahd_outb(ahd, HADDR + 5, dataptr >> 40);50115011- ahd_outb(ahd, HADDR + 4, dataptr >> 32);49334933+ ahd_outl(ahd, HADDR + 4, dataptr >> 32);50124934 } else {50134935 struct ahd_dma_seg *sg;50144936···50204948 ahd_outb(ahd, HADDR + 4,50214949 (ahd_le32toh(sg->len) & ~AHD_SG_LEN_MASK) >> 24);50224950 }50235023- ahd_outb(ahd, HADDR + 3, dataptr >> 24);50245024- ahd_outb(ahd, HADDR + 2, dataptr >> 16);50255025- ahd_outb(ahd, HADDR + 1, dataptr >> 8);50265026- ahd_outb(ahd, HADDR, dataptr);49514951+ ahd_outl(ahd, HADDR, dataptr);50274952 ahd_outb(ahd, HCNT + 2, resid >> 16);50284953 ahd_outb(ahd, HCNT + 1, resid >> 8);50294954 ahd_outb(ahd, HCNT, resid);···50805011 ahd_set_width(ahd, devinfo, MSG_EXT_WDTR_BUS_8_BIT,50815012 AHD_TRANS_CUR, /*paused*/TRUE);50825013 ahd_set_syncrate(ahd, devinfo, /*period*/0, /*offset*/0,50835083- /*ppr_options*/0, AHD_TRANS_CUR, /*paused*/TRUE);50145014+ /*ppr_options*/0, AHD_TRANS_CUR,50155015+ /*paused*/TRUE);5084501650855085- ahd_send_async(ahd, devinfo->channel, devinfo->target,50865086- lun, AC_SENT_BDR, NULL);50175017+ if (status != CAM_SEL_TIMEOUT)50185018+ ahd_send_async(ahd, devinfo->channel, devinfo->target,50195019+ CAM_LUN_WILDCARD, AC_SENT_BDR, NULL);5087502050885088- if (message != NULL50895089- && (verbose_level <= bootverbose))50215021+ if (message != NULL && bootverbose)50905022 printf("%s: %s on %c:%d. %d SCBs aborted\n", ahd_name(ahd),50915023 message, devinfo->channel, devinfo->target, found);50925024}···52735203 /* FALLTHROUGH */52745204 case 4:52755205 ahd_dmamap_unload(ahd, ahd->shared_data_dmat,52765276- ahd->shared_data_dmamap);52065206+ ahd->shared_data_map.dmamap);52775207 /* FALLTHROUGH */52785208 case 3:52795209 ahd_dmamem_free(ahd, ahd->shared_data_dmat, ahd->qoutfifo,52805280- ahd->shared_data_dmamap);52105210+ ahd->shared_data_map.dmamap);52815211 ahd_dmamap_destroy(ahd, ahd->shared_data_dmat,52825282- ahd->shared_data_dmamap);52125212+ ahd->shared_data_map.dmamap);52835213 /* FALLTHROUGH */52845214 case 2:52855215 ahd_dma_tag_destroy(ahd, ahd->shared_data_dmat);···60455975 newcount = MIN(scb_data->sense_left, scb_data->scbs_left);60465976 newcount = MIN(newcount, scb_data->sgs_left);60475977 newcount = MIN(newcount, (AHD_SCB_MAX_ALLOC - scb_data->numscbs));60486048- scb_data->sense_left -= newcount;60496049- scb_data->scbs_left -= newcount;60506050- scb_data->sgs_left -= newcount;60515978 for (i = 0; i < newcount; i++) {60526052- u_int col_tag;60536053-60545979 struct scb_platform_data *pdata;59805980+ u_int col_tag;60555981#ifndef __linux__60565982 int error;60575983#endif59845984+60585985 next_scb = (struct scb *)malloc(sizeof(*next_scb),60595986 M_DEVBUF, M_NOWAIT);60605987 if (next_scb == NULL)···61086041 sense_data += AHD_SENSE_BUFSIZE;61096042 sense_busaddr += AHD_SENSE_BUFSIZE;61106043 scb_data->numscbs++;60446044+ scb_data->sense_left--;60456045+ scb_data->scbs_left--;60466046+ scb_data->sgs_left--;61116047 }61126048}61136049···61586088int61596089ahd_init(struct ahd_softc *ahd)61606090{61616161- uint8_t *base_vaddr;61626091 uint8_t *next_vaddr;61636092 dma_addr_t next_baddr;61646093 size_t driver_data_size;···62256156 * for the target mode role, we must additionally provide space for62266157 * the incoming target command fifo.62276158 */62286228- driver_data_size = AHD_SCB_MAX * sizeof(uint16_t)61596159+ driver_data_size = AHD_SCB_MAX * sizeof(*ahd->qoutfifo)62296160 + sizeof(struct hardware_scb);62306161 if ((ahd->features & AHD_TARGETMODE) != 0)62316162 driver_data_size += AHD_TMODE_CMDS * sizeof(struct target_cmd);···6247617862486179 /* Allocation of driver data */62496180 if (ahd_dmamem_alloc(ahd, ahd->shared_data_dmat,62506250- (void **)&base_vaddr,62516251- BUS_DMA_NOWAIT, &ahd->shared_data_dmamap) != 0) {61816181+ (void **)&ahd->shared_data_map.vaddr,61826182+ BUS_DMA_NOWAIT,61836183+ &ahd->shared_data_map.dmamap) != 0) {62526184 return (ENOMEM);62536185 }6254618662556187 ahd->init_level++;6256618862576189 /* And permanently map it in */62586258- ahd_dmamap_load(ahd, ahd->shared_data_dmat, ahd->shared_data_dmamap,62596259- base_vaddr, driver_data_size, ahd_dmamap_cb,62606260- &ahd->shared_data_busaddr, /*flags*/0);62616261- ahd->qoutfifo = (uint16_t *)base_vaddr;61906190+ ahd_dmamap_load(ahd, ahd->shared_data_dmat, ahd->shared_data_map.dmamap,61916191+ ahd->shared_data_map.vaddr, driver_data_size,61926192+ ahd_dmamap_cb, &ahd->shared_data_map.physaddr,61936193+ /*flags*/0);61946194+ ahd->qoutfifo = (struct ahd_completion *)ahd->shared_data_map.vaddr;62626195 next_vaddr = (uint8_t *)&ahd->qoutfifo[AHD_QOUT_SIZE];62636263- next_baddr = ahd->shared_data_busaddr + AHD_QOUT_SIZE*sizeof(uint16_t);61966196+ next_baddr = ahd->shared_data_map.physaddr61976197+ + AHD_QOUT_SIZE*sizeof(struct ahd_completion);62646198 if ((ahd->features & AHD_TARGETMODE) != 0) {62656199 ahd->targetcmds = (struct target_cmd *)next_vaddr;62666200 next_vaddr += AHD_TMODE_CMDS * sizeof(struct target_cmd);···62846212 * specially from the DMA safe memory chunk used for the QOUTFIFO.62856213 */62866214 ahd->next_queued_hscb = (struct hardware_scb *)next_vaddr;62156215+ ahd->next_queued_hscb_map = &ahd->shared_data_map;62876216 ahd->next_queued_hscb->hscb_busaddr = ahd_htole32(next_baddr);6288621762896218 ahd->init_level++;···6590651765916518 /* All of our queues are empty */65926519 ahd->qoutfifonext = 0;65936593- ahd->qoutfifonext_valid_tag = QOUTFIFO_ENTRY_VALID_LE;65946594- ahd_outb(ahd, QOUTFIFO_ENTRY_VALID_TAG, QOUTFIFO_ENTRY_VALID >> 8);65206520+ ahd->qoutfifonext_valid_tag = QOUTFIFO_ENTRY_VALID;65216521+ ahd_outb(ahd, QOUTFIFO_ENTRY_VALID_TAG, QOUTFIFO_ENTRY_VALID);65956522 for (i = 0; i < AHD_QOUT_SIZE; i++)65966596- ahd->qoutfifo[i] = 0;65236523+ ahd->qoutfifo[i].valid_tag = 0;65976524 ahd_sync_qoutfifo(ahd, BUS_DMASYNC_PREREAD);6598652565996526 ahd->qinfifonext = 0;···66266553 ahd_outw(ahd, COMPLETE_SCB_HEAD, SCB_LIST_NULL);66276554 ahd_outw(ahd, COMPLETE_SCB_DMAINPROG_HEAD, SCB_LIST_NULL);66286555 ahd_outw(ahd, COMPLETE_DMA_SCB_HEAD, SCB_LIST_NULL);65566556+ ahd_outw(ahd, COMPLETE_DMA_SCB_TAIL, SCB_LIST_NULL);65576557+ ahd_outw(ahd, COMPLETE_ON_QFREEZE_HEAD, SCB_LIST_NULL);6629655866306559 /*66316560 * The Freeze Count is 0.66326561 */65626562+ ahd->qfreeze_cnt = 0;66336563 ahd_outw(ahd, QFREEZE_COUNT, 0);65646564+ ahd_outw(ahd, KERNEL_QFREEZE_COUNT, 0);6634656566356566 /*66366567 * Tell the sequencer where it can find our arrays in memory.66376568 */66386638- busaddr = ahd->shared_data_busaddr;66396639- ahd_outb(ahd, SHARED_DATA_ADDR, busaddr & 0xFF);66406640- ahd_outb(ahd, SHARED_DATA_ADDR + 1, (busaddr >> 8) & 0xFF);66416641- ahd_outb(ahd, SHARED_DATA_ADDR + 2, (busaddr >> 16) & 0xFF);66426642- ahd_outb(ahd, SHARED_DATA_ADDR + 3, (busaddr >> 24) & 0xFF);66436643- ahd_outb(ahd, QOUTFIFO_NEXT_ADDR, busaddr & 0xFF);66446644- ahd_outb(ahd, QOUTFIFO_NEXT_ADDR + 1, (busaddr >> 8) & 0xFF);66456645- ahd_outb(ahd, QOUTFIFO_NEXT_ADDR + 2, (busaddr >> 16) & 0xFF);66466646- ahd_outb(ahd, QOUTFIFO_NEXT_ADDR + 3, (busaddr >> 24) & 0xFF);65696569+ busaddr = ahd->shared_data_map.physaddr;65706570+ ahd_outl(ahd, SHARED_DATA_ADDR, busaddr);65716571+ ahd_outl(ahd, QOUTFIFO_NEXT_ADDR, busaddr);6647657266486573 /*66496574 * Setup the allowed SCSI Sequences based on operational mode.···66906619 * Tell the sequencer which SCB will be the next one it receives.66916620 */66926621 busaddr = ahd_le32toh(ahd->next_queued_hscb->hscb_busaddr);66936693- ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 0, busaddr & 0xFF);66946694- ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 1, (busaddr >> 8) & 0xFF);66956695- ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 2, (busaddr >> 16) & 0xFF);66966696- ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 3, (busaddr >> 24) & 0xFF);66226622+ ahd_outl(ahd, NEXT_QUEUED_SCB_ADDR, busaddr);6697662366986624 /*66996625 * Default to coalescing disabled.···69946926{69956927 u_int intstat;69966928 u_int maxloops;69976997- u_int qfreeze_cnt;6998692969996930 maxloops = 1000;70006931 ahd->flags |= AHD_ALL_INTERRUPTS;70016932 ahd_pause(ahd);70026933 /*70037003- * Increment the QFreeze Count so that the sequencer70047004- * will not start new selections. We do this only69346934+ * Freeze the outgoing selections. We do this only70056935 * until we are safely paused without further selections70066936 * pending.70076937 */70087008- ahd_outw(ahd, QFREEZE_COUNT, ahd_inw(ahd, QFREEZE_COUNT) + 1);69386938+ ahd->qfreeze_cnt--;69396939+ ahd_outw(ahd, KERNEL_QFREEZE_COUNT, ahd->qfreeze_cnt);70096940 ahd_outb(ahd, SEQ_FLAGS2, ahd_inb(ahd, SEQ_FLAGS2) | SELECTOUT_QFROZEN);70106941 do {70117011- struct scb *waiting_scb;7012694270136943 ahd_unpause(ahd);69446944+ /*69456945+ * Give the sequencer some time to service69466946+ * any active selections.69476947+ */69486948+ ahd_delay(500);69496949+70146950 ahd_intr(ahd);70156951 ahd_pause(ahd);70167016- ahd_clear_critical_section(ahd);70176952 intstat = ahd_inb(ahd, INTSTAT);70187018- ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);70197019- if ((ahd_inb(ahd, SSTAT0) & (SELDO|SELINGO)) == 0)70207020- ahd_outb(ahd, SCSISEQ0,70217021- ahd_inb(ahd, SCSISEQ0) & ~ENSELO);70227022- /*70237023- * In the non-packetized case, the sequencer (for Rev A),70247024- * relies on ENSELO remaining set after SELDO. The hardware70257025- * auto-clears ENSELO in the packetized case.70267026- */70277027- waiting_scb = ahd_lookup_scb(ahd,70287028- ahd_inw(ahd, WAITING_TID_HEAD));70297029- if (waiting_scb != NULL70307030- && (waiting_scb->flags & SCB_PACKETIZED) == 070317031- && (ahd_inb(ahd, SSTAT0) & (SELDO|SELINGO)) != 0)70327032- ahd_outb(ahd, SCSISEQ0,70337033- ahd_inb(ahd, SCSISEQ0) | ENSELO);69536953+ if ((intstat & INT_PEND) == 0) {69546954+ ahd_clear_critical_section(ahd);69556955+ intstat = ahd_inb(ahd, INTSTAT);69566956+ }70346957 } while (--maxloops70356958 && (intstat != 0xFF || (ahd->features & AHD_REMOVABLE) == 0)70366959 && ((intstat & INT_PEND) != 0···70326973 printf("Infinite interrupt loop, INTSTAT = %x",70336974 ahd_inb(ahd, INTSTAT));70346975 }70357035- qfreeze_cnt = ahd_inw(ahd, QFREEZE_COUNT);70367036- if (qfreeze_cnt == 0) {70377037- printf("%s: ahd_pause_and_flushwork with 0 qfreeze count!\n",70387038- ahd_name(ahd));70397039- } else {70407040- qfreeze_cnt--;70417041- }70427042- ahd_outw(ahd, QFREEZE_COUNT, qfreeze_cnt);70437043- if (qfreeze_cnt == 0)70447044- ahd_outb(ahd, SEQ_FLAGS2,70457045- ahd_inb(ahd, SEQ_FLAGS2) & ~SELECTOUT_QFROZEN);69766976+ ahd->qfreeze_cnt++;69776977+ ahd_outw(ahd, KERNEL_QFREEZE_COUNT, ahd->qfreeze_cnt);7046697870476979 ahd_flush_qoutfifo(ahd);70486980···72057155 uint32_t busaddr;7206715672077157 busaddr = ahd_le32toh(scb->hscb->hscb_busaddr);72087208- ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 0, busaddr & 0xFF);72097209- ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 1, (busaddr >> 8) & 0xFF);72107210- ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 2, (busaddr >> 16) & 0xFF);72117211- ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 3, (busaddr >> 24) & 0xFF);71587158+ ahd_outl(ahd, NEXT_QUEUED_SCB_ADDR, busaddr);72127159 } else {72137160 prev_scb->hscb->next_hscb_busaddr = scb->hscb->hscb_busaddr;72147161 ahd_sync_scb(ahd, prev_scb, ···73127265 */73137266 ahd->qinfifonext = qinstart;73147267 busaddr = ahd_le32toh(ahd->next_queued_hscb->hscb_busaddr);73157315- ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 0, busaddr & 0xFF);73167316- ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 1, (busaddr >> 8) & 0xFF);73177317- ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 2, (busaddr >> 16) & 0xFF);73187318- ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 3, (busaddr >> 24) & 0xFF);72687268+ ahd_outl(ahd, NEXT_QUEUED_SCB_ADDR, busaddr);7319726973207270 while (qinpos != qintail) {73217271 scb = ahd_lookup_scb(ahd, ahd->qinfifo[qinpos]);···73747330 * appropriate, traverse the SCBs of each "their id"73757331 * looking for matches.73767332 */73337333+ ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);73777334 savedscbptr = ahd_get_scbptr(ahd);73787335 tid_next = ahd_inw(ahd, WAITING_TID_HEAD);73797336 tid_prev = SCB_LIST_NULL;···74447399 u_int prev;74457400 int found;7446740174477447- AHD_ASSERT_MODES(ahd, AHD_MODE_CCHAN_MSK, AHD_MODE_CCHAN_MSK);74027402+ AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);74487403 found = 0;74497404 prev = SCB_LIST_NULL;74507405 next = *list_head;···75117466ahd_stitch_tid_list(struct ahd_softc *ahd, u_int tid_prev,75127467 u_int tid_cur, u_int tid_next)75137468{75147514- AHD_ASSERT_MODES(ahd, AHD_MODE_CCHAN_MSK, AHD_MODE_CCHAN_MSK);74697469+ AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);7515747075167471 if (SCBID_IS_NULL(tid_cur)) {75177472···75517506{75527507 u_int tail_offset;7553750875547554- AHD_ASSERT_MODES(ahd, AHD_MODE_CCHAN_MSK, AHD_MODE_CCHAN_MSK);75097509+ AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);75557510 if (!SCBID_IS_NULL(prev)) {75567511 ahd_set_scbptr(ahd, prev);75577512 ahd_outw(ahd, SCB_NEXT, next);···77847739 */77857740 ahd_clear_msg_state(ahd);77867741 ahd_outb(ahd, SIMODE1,77877787- ahd_inb(ahd, SIMODE1) & ~(ENBUSFREE|ENSCSIRST|ENBUSFREE));77427742+ ahd_inb(ahd, SIMODE1) & ~(ENBUSFREE|ENSCSIRST));7788774377897744 if (initiate_reset)77907745 ahd_reset_current_bus(ahd);···79557910void79567911ahd_handle_scsi_status(struct ahd_softc *ahd, struct scb *scb)79577912{79587958- struct hardware_scb *hscb;79597959- u_int qfreeze_cnt;79137913+ struct hardware_scb *hscb;79147914+ int paused;7960791579617916 /*79627917 * The sequencer freezes its select-out queue79637918 * anytime a SCSI status error occurs. We must79647964- * handle the error and decrement the QFREEZE count79657965- * to allow the sequencer to continue.79197919+ * handle the error and increment our qfreeze count79207920+ * to allow the sequencer to continue. We don't79217921+ * bother clearing critical sections here since all79227922+ * operations are on data structures that the sequencer79237923+ * is not touching once the queue is frozen.79667924 */79677925 hscb = scb->hscb; 79267926+79277927+ if (ahd_is_paused(ahd)) {79287928+ paused = 1;79297929+ } else {79307930+ paused = 0;79317931+ ahd_pause(ahd);79327932+ }7968793379697934 /* Freeze the queue until the client sees the error. */79707935 ahd_freeze_devq(ahd, scb);79717936 ahd_freeze_scb(scb);79727972- qfreeze_cnt = ahd_inw(ahd, QFREEZE_COUNT);79737973- if (qfreeze_cnt == 0) {79747974- printf("%s: Bad status with 0 qfreeze count!\n", ahd_name(ahd));79757975- } else {79767976- qfreeze_cnt--;79777977- ahd_outw(ahd, QFREEZE_COUNT, qfreeze_cnt);79787978- }79797979- if (qfreeze_cnt == 0)79807980- ahd_outb(ahd, SEQ_FLAGS2,79817981- ahd_inb(ahd, SEQ_FLAGS2) & ~SELECTOUT_QFROZEN);79377937+ ahd->qfreeze_cnt++;79387938+ ahd_outw(ahd, KERNEL_QFREEZE_COUNT, ahd->qfreeze_cnt);79397939+79407940+ if (paused == 0)79417941+ ahd_unpause(ahd);7982794279837943 /* Don't want to clobber the original sense code */79847944 if ((scb->flags & SCB_SENSE) != 0) {···83678317 max_prog = 2048;8368831883698319 ahd_outb(ahd, SEQCTL0, PERRORDIS|FAILDIS|FASTMODE|LOADRAM);83708370- ahd_outb(ahd, PRGMCNT, 0);83718371- ahd_outb(ahd, PRGMCNT+1, 0);83208320+ ahd_outw(ahd, PRGMCNT, 0);83728321 for (i = 0; i < max_prog; i++) {83738322 uint8_t ins_bytes[4];83748323···83968347 u_int sg_prefetch_cnt_limit;83978348 u_int sg_prefetch_align;83988349 u_int sg_size;83508350+ u_int cacheline_mask;83998351 uint8_t download_consts[DOWNLOAD_CONST_COUNT];8400835284018353 if (bootverbose)84028354 printf("%s: Downloading Sequencer Program...",84038355 ahd_name(ahd));8404835684058405-#if DOWNLOAD_CONST_COUNT != 783578357+#if DOWNLOAD_CONST_COUNT != 884068358#error "Download Const Mismatch"84078359#endif84088360 /*···84398389 /* Round down to the nearest power of 2. */84408390 while (powerof2(sg_prefetch_align) == 0)84418391 sg_prefetch_align--;83928392+83938393+ cacheline_mask = sg_prefetch_align - 1;83948394+84428395 /*84438396 * If the cacheline boundary is greater than half our prefetch RAM84448397 * we risk not being able to fetch even a single complete S/G···84828429 download_consts[PKT_OVERRUN_BUFOFFSET] =84838430 (ahd->overrun_buf - (uint8_t *)ahd->qoutfifo) / 256;84848431 download_consts[SCB_TRANSFER_SIZE] = SCB_TRANSFER_SIZE_1BYTE_LUN;84328432+ download_consts[CACHELINE_MASK] = cacheline_mask;84858433 cur_patch = patches;84868434 downloaded = 0;84878435 skip_addr = 0;84888436 ahd_outb(ahd, SEQCTL0, PERRORDIS|FAILDIS|FASTMODE|LOADRAM);84898489- ahd_outb(ahd, PRGMCNT, 0);84908490- ahd_outb(ahd, PRGMCNT+1, 0);84378437+ ahd_outw(ahd, PRGMCNT, 0);8491843884928439 for (i = 0; i < sizeof(seqprog)/4; i++) {84938440 if (ahd_check_patch(ahd, &cur_patch, i, &skip_addr) == 0) {···87808727 printf(">>>>>>>>>>>>>>>>>> Dump Card State Begins <<<<<<<<<<<<<<<<<\n"87818728 "%s: Dumping Card State at program address 0x%x Mode 0x%x\n",87828729 ahd_name(ahd), 87838783- ahd_inb(ahd, CURADDR) | (ahd_inb(ahd, CURADDR+1) << 8),87308730+ ahd_inw(ahd, CURADDR),87848731 ahd_build_mode_state(ahd, ahd->saved_src_mode,87858732 ahd->saved_dst_mode));87868733 if (paused)···8889883688908837 printf("Sequencer DMA-Up and Complete list: ");88918838 scb_index = ahd_inw(ahd, COMPLETE_DMA_SCB_HEAD);88398839+ i = 0;88408840+ while (!SCBID_IS_NULL(scb_index) && i++ < AHD_SCB_MAX) {88418841+ ahd_set_scbptr(ahd, scb_index);88428842+ printf("%d ", scb_index);88438843+ scb_index = ahd_inw_scbram(ahd, SCB_NEXT_COMPLETE);88448844+ }88458845+ printf("\n");88468846+ printf("Sequencer On QFreeze and Complete list: ");88478847+ scb_index = ahd_inw(ahd, COMPLETE_ON_QFREEZE_HEAD);88928848 i = 0;88938849 while (!SCBID_IS_NULL(scb_index) && i++ < AHD_SCB_MAX) {88948850 ahd_set_scbptr(ahd, scb_index);···91399077{91409078 int cnt;9141907991429142- cnt = 20;90809080+ cnt = 5000;91439081 while ((ahd_inb(ahd, SEESTAT) & (SEEARBACK|SEEBUSY)) != 0 && --cnt)91449082 ahd_delay(5);91459083···94859423 if ((ahd->features & AHD_MULTI_TID) != 0) {94869424 u_int targid_mask;9487942594889488- targid_mask = ahd_inb(ahd, TARGID)94899489- | (ahd_inb(ahd, TARGID + 1) << 8);94909490-94269426+ targid_mask = ahd_inw(ahd, TARGID);94919427 targid_mask |= target_mask;94929492- ahd_outb(ahd, TARGID, targid_mask);94939493- ahd_outb(ahd, TARGID+1, (targid_mask >> 8));94949494-94289428+ ahd_outw(ahd, TARGID, targid_mask);94959429 ahd_update_scsiid(ahd, targid_mask);94969430 } else {94979431 u_int our_id;···96019543 if (ahd->features & AHD_MULTI_TID) {96029544 u_int targid_mask;9603954596049604- targid_mask = ahd_inb(ahd, TARGID)96059605- | (ahd_inb(ahd, TARGID + 1)96069606- << 8);96079607-95469546+ targid_mask = ahd_inw(ahd, TARGID);96089547 targid_mask &= ~target_mask;96099609- ahd_outb(ahd, TARGID, targid_mask);96109610- ahd_outb(ahd, TARGID+1,96119611- (targid_mask >> 8));95489548+ ahd_outw(ahd, TARGID, targid_mask);96129549 ahd_update_scsiid(ahd, targid_mask);96139550 }96149551 }···9704965197059652 cmd->cmd_valid = 0;97069653 ahd_dmamap_sync(ahd, ahd->shared_data_dmat,97079707- ahd->shared_data_dmamap,96549654+ ahd->shared_data_map.dmamap,97089655 ahd_targetcmd_offset(ahd, ahd->tqinfifonext),97099656 sizeof(struct target_cmd),97109657 BUS_DMASYNC_PREREAD);
+26-12
drivers/scsi/aic7xxx/aic79xx_inline.h
···3737 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE3838 * POSSIBILITY OF SUCH DAMAGES.3939 *4040- * $Id: //depot/aic7xxx/aic7xxx/aic79xx_inline.h#51 $4040+ * $Id: //depot/aic7xxx/aic7xxx/aic79xx_inline.h#58 $4141 *4242 * $FreeBSD$4343 */···522522static __inline uint16_t523523ahd_inw(struct ahd_softc *ahd, u_int port)524524{525525+ /*526526+ * Read high byte first as some registers increment527527+ * or have other side effects when the low byte is528528+ * read.529529+ */525530 return ((ahd_inb(ahd, port+1) << 8) | ahd_inb(ahd, port));526531}527532528533static __inline void529534ahd_outw(struct ahd_softc *ahd, u_int port, u_int value)530535{536536+ /*537537+ * Write low byte first to accomodate registers538538+ * such as PRGMCNT where the order maters.539539+ */531540 ahd_outb(ahd, port, value & 0xFF);532541 ahd_outb(ahd, port+1, (value >> 8) & 0xFF);533542}···693684 * Razor #528694685 */695686 value = ahd_inb(ahd, offset);696696- if ((ahd->flags & AHD_PCIX_SCBRAM_RD_BUG) != 0)687687+ if ((ahd->bugs & AHD_PCIX_SCBRAM_RD_BUG) != 0)697688 ahd_inb(ahd, MODE_PTR);698689 return (value);699690}···736727static __inline void737728ahd_swap_with_next_hscb(struct ahd_softc *ahd, struct scb *scb)738729{739739- struct hardware_scb *q_hscb;730730+ struct hardware_scb *q_hscb;731731+ struct map_node *q_hscb_map;740732 uint32_t saved_hscb_busaddr;741733742734 /*···753743 * locate the correct SCB by SCB_TAG.754744 */755745 q_hscb = ahd->next_queued_hscb;746746+ q_hscb_map = ahd->next_queued_hscb_map;756747 saved_hscb_busaddr = q_hscb->hscb_busaddr;757748 memcpy(q_hscb, scb->hscb, sizeof(*scb->hscb));758749 q_hscb->hscb_busaddr = saved_hscb_busaddr;···761750762751 /* Now swap HSCB pointers. */763752 ahd->next_queued_hscb = scb->hscb;753753+ ahd->next_queued_hscb_map = scb->hscb_map;764754 scb->hscb = q_hscb;755755+ scb->hscb_map = q_hscb_map;765756766757 /* Now define the mapping from tag to SCB in the scbindex */767758 ahd->scb_data.scbindex[SCB_GET_TAG(scb)] = scb;···837824static __inline void838825ahd_sync_qoutfifo(struct ahd_softc *ahd, int op)839826{840840- ahd_dmamap_sync(ahd, ahd->shared_data_dmat, ahd->shared_data_dmamap,841841- /*offset*/0, /*len*/AHC_SCB_MAX * sizeof(uint16_t), op);827827+ ahd_dmamap_sync(ahd, ahd->shared_data_dmat, ahd->shared_data_map.dmamap,828828+ /*offset*/0,829829+ /*len*/AHD_SCB_MAX * sizeof(struct ahd_completion), op);842830}843831844832static __inline void···848834#ifdef AHD_TARGET_MODE849835 if ((ahd->flags & AHD_TARGETROLE) != 0) {850836 ahd_dmamap_sync(ahd, ahd->shared_data_dmat,851851- ahd->shared_data_dmamap,837837+ ahd->shared_data_map.dmamap,852838 ahd_targetcmd_offset(ahd, 0),853839 sizeof(struct target_cmd) * AHD_TMODE_CMDS,854840 op);···868854 u_int retval;869855870856 retval = 0;871871- ahd_dmamap_sync(ahd, ahd->shared_data_dmat, ahd->shared_data_dmamap,872872- /*offset*/ahd->qoutfifonext, /*len*/2,873873- BUS_DMASYNC_POSTREAD);874874- if ((ahd->qoutfifo[ahd->qoutfifonext]875875- & QOUTFIFO_ENTRY_VALID_LE) == ahd->qoutfifonext_valid_tag)857857+ ahd_dmamap_sync(ahd, ahd->shared_data_dmat, ahd->shared_data_map.dmamap,858858+ /*offset*/ahd->qoutfifonext * sizeof(*ahd->qoutfifo),859859+ /*len*/sizeof(*ahd->qoutfifo), BUS_DMASYNC_POSTREAD);860860+ if (ahd->qoutfifo[ahd->qoutfifonext].valid_tag861861+ == ahd->qoutfifonext_valid_tag)876862 retval |= AHD_RUN_QOUTFIFO;877863#ifdef AHD_TARGET_MODE878864 if ((ahd->flags & AHD_TARGETROLE) != 0879865 && (ahd->flags & AHD_TQINFIFO_BLOCKED) == 0) {880866 ahd_dmamap_sync(ahd, ahd->shared_data_dmat,881881- ahd->shared_data_dmamap,867867+ ahd->shared_data_map.dmamap,882868 ahd_targetcmd_offset(ahd, ahd->tqinfifofnext),883869 /*len*/sizeof(struct target_cmd),884870 BUS_DMASYNC_POSTREAD);
+51-11
drivers/scsi/aic7xxx/aic79xx_osm.c
···14681468 if ((tstate->auto_negotiate & mask) != 0) {14691469 scb->flags |= SCB_AUTO_NEGOTIATE;14701470 scb->hscb->control |= MK_MESSAGE;14711471+ } else if (cmd->cmnd[0] == INQUIRY14721472+ && (tinfo->curr.offset != 014731473+ || tinfo->curr.width != MSG_EXT_WDTR_BUS_8_BIT14741474+ || tinfo->curr.ppr_options != 0)14751475+ && (tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ)==0) {14761476+ /*14771477+ * The SCSI spec requires inquiry14781478+ * commands to complete without14791479+ * reporting unit attention conditions.14801480+ * Because of this, an inquiry command14811481+ * that occurs just after a device is14821482+ * reset will result in a data phase14831483+ * with mismatched negotiated rates.14841484+ * The core already forces a renegotiation14851485+ * for reset events that are visible to14861486+ * our controller or that we initiate,14871487+ * but a third party device reset or a14881488+ * hot-plug insertion can still cause this14891489+ * issue. Therefore, we force a re-negotiation14901490+ * for every inquiry command unless we14911491+ * are async.14921492+ */14931493+ scb->flags |= SCB_NEGOTIATE;14941494+ scb->hscb->control |= MK_MESSAGE;14711495 }1472149614731497 if ((dev->flags & (AHD_DEV_Q_TAGGED|AHD_DEV_Q_BASIC)) != 0) {···20822058 int paused;20832059 int wait;20842060 int disconnected;20612061+ int found;20852062 ahd_mode_state saved_modes;20862063 unsigned long flags;20872064···22012176 last_phase = ahd_inb(ahd, LASTPHASE);22022177 saved_scbptr = ahd_get_scbptr(ahd);22032178 active_scbptr = saved_scbptr;22042204- if (disconnected && (ahd_inb(ahd, SEQ_FLAGS) & NOT_IDENTIFIED) == 0) {21792179+ if (disconnected && ((last_phase != P_BUSFREE) || 21802180+ (ahd_inb(ahd, SEQ_FLAGS) & NOT_IDENTIFIED) == 0)) {22052181 struct scb *bus_scb;2206218222072183 bus_scb = ahd_lookup_scb(ahd, active_scbptr);···22202194 * bus or is in the disconnected state.22212195 */22222196 saved_scsiid = ahd_inb(ahd, SAVED_SCSIID);22232223- if (last_phase != P_BUSFREE22242224- && (SCB_GET_TAG(pending_scb) == active_scbptr21972197+ if (SCB_GET_TAG(pending_scb) == active_scbptr22252198 || (flag == SCB_DEVICE_RESET22262226- && SCSIID_TARGET(ahd, saved_scsiid) == scmd_id(cmd)))) {21992199+ && SCSIID_TARGET(ahd, saved_scsiid) == scmd_id(cmd))) {2227220022282201 /*22292202 * We're active on the bus, so assert ATN22302203 * and hope that the target responds.22312204 */22322205 pending_scb = ahd_lookup_scb(ahd, active_scbptr);22332233- pending_scb->flags |= SCB_RECOVERY_SCB|flag;22062206+ pending_scb->flags |= SCB_RECOVERY_SCB|SCB_DEVICE_RESET;22342207 ahd_outb(ahd, MSG_OUT, HOST_MSG);22352208 ahd_outb(ahd, SCSISIGO, last_phase|ATNO);22362236- scmd_printk(KERN_INFO, cmd, "Device is active, asserting ATN\n");22092209+ scmd_printk(KERN_INFO, cmd, "BDR message in message buffer\n");22372210 wait = TRUE;22112211+ } else if (last_phase != P_BUSFREE22122212+ && ahd_inb(ahd, SCSIPHASE) == 0) {22132213+ /*22142214+ * SCB is not identified, there22152215+ * is no pending REQ, and the sequencer22162216+ * has not seen a busfree. Looks like22172217+ * a stuck connection waiting to22182218+ * go busfree. Reset the bus.22192219+ */22202220+ found = ahd_reset_channel(ahd, cmd->device->channel + 'A',22212221+ /*Initiate Reset*/TRUE);22222222+ printf("%s: Issued Channel %c Bus Reset. "22232223+ "%d SCBs aborted\n", ahd_name(ahd),22242224+ cmd->device->channel + 'A', found);22382225 } else if (disconnected) {2239222622402227 /*22412228 * Actually re-queue this SCB in an attempt22422229 * to select the device before it reconnects.22432230 */22442244- pending_scb->flags |= SCB_RECOVERY_SCB|SCB_ABORT;22312231+ pending_scb->flags |= SCB_RECOVERY_SCB|flag;22452232 ahd_set_scbptr(ahd, SCB_GET_TAG(pending_scb));22462233 pending_scb->hscb->cdb_len = 0;22472234 pending_scb->hscb->task_attribute = 0;···23352296 timer.expires = jiffies + (5 * HZ);23362297 timer.function = ahd_linux_sem_timeout;23372298 add_timer(&timer);23382338- printf("Recovery code sleeping\n");22992299+ printf("%s: Recovery code sleeping\n", ahd_name(ahd));23392300 down(&ahd->platform_data->eh_sem);23402340- printf("Recovery code awake\n");23012301+ printf("%s: Recovery code awake\n", ahd_name(ahd));23412302 ret = del_timer_sync(&timer);23422303 if (ret == 0) {23432343- printf("Timer Expired\n");23042304+ printf("%s: Timer Expired (active %d)\n",23052305+ ahd_name(ahd), dev->active);23442306 retval = FAILED;23452307 }23462308 }23472347- ahd_unlock(ahd, &flags);23092309+ ahd_unlock(ahd, &flags);23482310 return (retval);23492311}23502312
+1-1
drivers/scsi/aic7xxx/aic79xx_osm.h
···252252/***************************** SMP support ************************************/253253#include <linux/spinlock.h>254254255255-#define AIC79XX_DRIVER_VERSION "1.3.11"255255+#define AIC79XX_DRIVER_VERSION "3.0"256256257257/*************************** Device Data Structures ***************************/258258/*
+15-9
drivers/scsi/aic7xxx/aic79xx_pci.c
···3838 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE3939 * POSSIBILITY OF SUCH DAMAGES.4040 *4141- * $Id: //depot/aic7xxx/aic7xxx/aic79xx_pci.c#77 $4242- *4343- * $FreeBSD$4141+ * $Id: //depot/aic7xxx/aic7xxx/aic79xx_pci.c#89 $4442 */45434644#ifdef __linux__···112114 "Adaptec 29320ALP Ultra320 SCSI adapter",113115 ahd_aic7901_setup114116 },117117+ /* aic7901A based controllers */118118+ {119119+ ID_AHA_29320LP,120120+ ID_ALL_MASK,121121+ "Adaptec 29320LP Ultra320 SCSI adapter",122122+ ahd_aic7901A_setup123123+ },115124 /* aic7902 based controllers */ 116125 {117126 ID_AHA_29320,···133128 ahd_aic7902_setup134129 },135130 {136136- ID_AHA_29320LP,137137- ID_ALL_MASK,138138- "Adaptec 29320LP Ultra320 SCSI adapter",139139- ahd_aic7901A_setup140140- },141141- {142131 ID_AHA_39320,143132 ID_ALL_MASK,144133 "Adaptec 39320 Ultra320 SCSI adapter",···142143 ID_AHA_39320_B,143144 ID_ALL_MASK,144145 "Adaptec 39320 Ultra320 SCSI adapter",146146+ ahd_aic7902_setup147147+ },148148+ {149149+ ID_AHA_39320_B_DELL,150150+ ID_ALL_MASK,151151+ "Adaptec (Dell OEM) 39320 Ultra320 SCSI adapter",145152 ahd_aic7902_setup146153 },147154 {···673668 * Now set the termination based on what we found.674669 */675670 sxfrctl1 = ahd_inb(ahd, SXFRCTL1) & ~STPWEN;671671+ ahd->flags &= ~AHD_TERM_ENB_A;676672 if ((termctl & FLX_TERMCTL_ENPRILOW) != 0) {677673 ahd->flags |= AHD_TERM_ENB_A;678674 sxfrctl1 |= STPWEN;
···3939 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE4040 * POSSIBILITY OF SUCH DAMAGES.4141 *4242- * $Id: //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#69 $4343- *4444- * $FreeBSD$4242+ * $Id: //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#79 $4543 */46444745#ifdef __linux__···389391 ID_AIC7892_ARO,390392 ID_ALL_MASK,391393 "Adaptec aic7892 Ultra160 SCSI adapter (ARO)",394394+ ahc_aic7892_setup395395+ },396396+ {397397+ ID_AHA_2915_30LP,398398+ ID_ALL_MASK,399399+ "Adaptec 2915/30LP Ultra160 SCSI adapter",392400 ahc_aic7892_setup393401 },394402 /* aic7895 based controllers */ ···11971193 * use for this test.11981194 */11991195 hcntrl = ahc_inb(ahc, HCNTRL);11961196+12001197 if (hcntrl == 0xFF)12011198 goto fail;11991199+12001200+ if ((hcntrl & CHIPRST) != 0) {12011201+ /*12021202+ * The chip has not been initialized since12031203+ * PCI/EISA/VLB bus reset. Don't trust12041204+ * "left over BIOS data".12051205+ */12061206+ ahc->flags |= AHC_NO_BIOS_INIT;12071207+ }1202120812031209 /*12041210 * Next create a situation where write combining···13211307 sd.sd_chip = C56_66;13221308 }13231309 ahc_release_seeprom(&sd);13101310+13111311+ /* Remember the SEEPROM type for later */13121312+ if (sd.sd_chip == C56_66)13131313+ ahc->flags |= AHC_LARGE_SEEPROM;13241314 }1325131513261316 if (!have_seeprom) {
···44794479 * serialized. This is so because we want to reserve maximum number of44804480 * available command ids for the I/O commands.44814481 */44824482- down(&adapter->int_mtx);44824482+ mutex_lock(&adapter->int_mtx);4483448344844484 scb = &adapter->int_scb;44854485 memset(scb, 0, sizeof(scb_t));···45274527 mc->cmd, mc->opcode, mc->subopcode, scmd->result);45284528 }4529452945304530- up(&adapter->int_mtx);45304530+ mutex_unlock(&adapter->int_mtx);4531453145324532 return rval;45334533}···48664866 adapter->has_64bit_addr = 0;48674867 }4868486848694869- init_MUTEX(&adapter->int_mtx);48694869+ mutex_init(&adapter->int_mtx);48704870 init_completion(&adapter->int_waitq);4871487148724872 adapter->this_id = DEFAULT_INITIATOR_ID;
+2-2
drivers/scsi/megaraid.h
···22#define __MEGARAID_H__3344#include <linux/spinlock.h>55-55+#include <linux/mutex.h>6677#define MEGARAID_VERSION \88 "v2.00.3 (Release Date: Wed Feb 19 08:51:30 EST 2003)\n"···889889890890 scb_t int_scb;891891 Scsi_Cmnd int_scmd;892892- struct semaphore int_mtx; /* To synchronize the internal892892+ struct mutex int_mtx; /* To synchronize the internal893893 commands */894894 struct completion int_waitq; /* wait queue for internal895895 cmds */
+4-3
drivers/scsi/megaraid/megaraid_sas.c
···3535#include <asm/uaccess.h>3636#include <linux/fs.h>3737#include <linux/compat.h>3838+#include <linux/mutex.h>38393940#include <scsi/scsi.h>4041#include <scsi/scsi_cmnd.h>···7372static int megasas_mgmt_majorno;7473static struct megasas_mgmt_info megasas_mgmt_info;7574static struct fasync_struct *megasas_async_queue;7676-static DECLARE_MUTEX(megasas_async_queue_mutex);7575+static DEFINE_MUTEX(megasas_async_queue_mutex);77767877/**7978 * megasas_get_cmd - Get a command from the free pool···23632362{23642363 int rc;2365236423662366- down(&megasas_async_queue_mutex);23652365+ mutex_lock(&megasas_async_queue_mutex);2367236623682367 rc = fasync_helper(fd, filep, mode, &megasas_async_queue);2369236823702370- up(&megasas_async_queue_mutex);23692369+ mutex_unlock(&megasas_async_queue_mutex);2371237023722371 if (rc >= 0) {23732372 /* For sanity check when we get ioctl */
+16-8
drivers/scsi/qla2xxx/Kconfig
···11-config SCSI_QLA2XXX11+config SCSI_QLA_FC22 tristate "QLogic QLA2XXX Fibre Channel Support"33 depends on PCI && SCSI44 select SCSI_FC_ATTRS···2222 Upon request, the driver caches the firmware image until2323 the driver is unloaded.24242525+ Firmware images can be retrieved from:2626+2727+ ftp://ftp.qlogic.com/outgoing/linux/firmware/2828+2529 NOTE: The original method of building firmware-loader2630 modules has been deprecated as the firmware-images will2731 be removed from the kernel sources.28322933config SCSI_QLA2XXX_EMBEDDED_FIRMWARE3034 bool " Use firmware-loader modules (DEPRECATED)"3131- depends on SCSI_QLA2XXX3535+ depends on SCSI_QLA_FC3636+ help3737+ This option offers you the deprecated firmware-loader3838+ modules that have been obsoleted by the usage of the3939+ Firmware Loader interface in the qla2xxx driver.32403341config SCSI_QLA21XX3442 tristate " Build QLogic ISP2100 firmware-module"3535- depends on SCSI_QLA2XXX_EMBEDDED_FIRMWARE4343+ depends on SCSI_QLA_FC && SCSI_QLA2XXX_EMBEDDED_FIRMWARE3644 ---help---3745 This driver supports the QLogic 21xx (ISP2100) host adapter family.38463947config SCSI_QLA22XX4048 tristate " Build QLogic ISP2200 firmware-module"4141- depends on SCSI_QLA2XXX_EMBEDDED_FIRMWARE4949+ depends on SCSI_QLA_FC && SCSI_QLA2XXX_EMBEDDED_FIRMWARE4250 ---help---4351 This driver supports the QLogic 22xx (ISP2200) host adapter family.44524553config SCSI_QLA23004654 tristate " Build QLogic ISP2300 firmware-module"4747- depends on SCSI_QLA2XXX_EMBEDDED_FIRMWARE5555+ depends on SCSI_QLA_FC && SCSI_QLA2XXX_EMBEDDED_FIRMWARE4856 ---help---4957 This driver supports the QLogic 2300 (ISP2300 and ISP2312) host5058 adapter family.51595260config SCSI_QLA23225361 tristate " Build QLogic ISP2322 firmware-module"5454- depends on SCSI_QLA2XXX_EMBEDDED_FIRMWARE6262+ depends on SCSI_QLA_FC && SCSI_QLA2XXX_EMBEDDED_FIRMWARE5563 ---help---5664 This driver supports the QLogic 2322 (ISP2322) host adapter family.57655866config SCSI_QLA63125967 tristate " Build QLogic ISP63xx firmware-module"6060- depends on SCSI_QLA2XXX_EMBEDDED_FIRMWARE6868+ depends on SCSI_QLA_FC && SCSI_QLA2XXX_EMBEDDED_FIRMWARE6169 ---help---6270 This driver supports the QLogic 63xx (ISP6312 and ISP6322) host6371 adapter family.64726573config SCSI_QLA24XX6674 tristate " Build QLogic ISP24xx firmware-module"6767- depends on SCSI_QLA2XXX_EMBEDDED_FIRMWARE7575+ depends on SCSI_QLA_FC && SCSI_QLA2XXX_EMBEDDED_FIRMWARE6876 ---help---6977 This driver supports the QLogic 24xx (ISP2422 and ISP2432) host7078 adapter family.
···7171 "Enables FDMI registratons "7272 "Default is 0 - no FDMI. 1 - perfom FDMI.");73737474+int ql2xprocessrscn;7575+module_param(ql2xprocessrscn, int, S_IRUGO|S_IRUSR);7676+MODULE_PARM_DESC(ql2xprocessrscn,7777+ "Option to enable port RSCN handling via a series of less"7878+ "fabric intrusive ADISCs and PLOGIs.");7979+7480/*7581 * SCSI host template entry points7682 */
···2626#define SCSI_SENSE_VALID(scmd) \2727 (((scmd)->sense_buffer[0] & 0x70) == 0x70)28282929-/*3030- * Special value for scanning to specify scanning or rescanning of all3131- * possible channels, (target) ids, or luns on a given shost.3232- */3333-#define SCAN_WILD_CARD ~03434-3529/* hosts.c */3630extern int scsi_init_hosts(void);3731extern void scsi_exit_hosts(void);
+11-6
drivers/scsi/scsi_proc.c
···2525#include <linux/errno.h>2626#include <linux/blkdev.h>2727#include <linux/seq_file.h>2828+#include <linux/mutex.h>2829#include <asm/uaccess.h>29303031#include <scsi/scsi.h>3132#include <scsi/scsi_device.h>3233#include <scsi/scsi_host.h>3434+#include <scsi/scsi_transport.h>33353436#include "scsi_priv.h"3537#include "scsi_logging.h"···4341static struct proc_dir_entry *proc_scsi;44424543/* Protect sht->present and sht->proc_dir */4646-static DECLARE_MUTEX(global_host_template_sem);4444+static DEFINE_MUTEX(global_host_template_mutex);47454846static int proc_scsi_read(char *buffer, char **start, off_t offset,4947 int length, int *eof, void *data)···8583 if (!sht->proc_info)8684 return;87858888- down(&global_host_template_sem);8686+ mutex_lock(&global_host_template_mutex);8987 if (!sht->present++) {9088 sht->proc_dir = proc_mkdir(sht->proc_name, proc_scsi);9189 if (!sht->proc_dir)···9492 else9593 sht->proc_dir->owner = sht->module;9694 }9797- up(&global_host_template_sem);9595+ mutex_unlock(&global_host_template_mutex);9896}999710098void scsi_proc_hostdir_rm(struct scsi_host_template *sht)···102100 if (!sht->proc_info)103101 return;104102105105- down(&global_host_template_sem);103103+ mutex_lock(&global_host_template_mutex);106104 if (!--sht->present && sht->proc_dir) {107105 remove_proc_entry(sht->proc_name, proc_scsi);108106 sht->proc_dir = NULL;109107 }110110- up(&global_host_template_sem);108108+ mutex_unlock(&global_host_template_mutex);111109}112110113111void scsi_proc_host_add(struct Scsi_Host *shost)···201199 if (IS_ERR(shost))202200 return PTR_ERR(shost);203201204204- error = scsi_scan_host_selected(shost, channel, id, lun, 1);202202+ if (shost->transportt->user_scan)203203+ error = shost->transportt->user_scan(shost, channel, id, lun);204204+ else205205+ error = scsi_scan_host_selected(shost, channel, id, lun, 1);205206 scsi_host_put(shost);206207 return error;207208}
+10-22
drivers/scsi/scsi_scan.c
···334334 struct scsi_target *starget;335335 struct scsi_target *found_target;336336337337- /*338338- * Obtain the real parent from the transport. The transport339339- * is allowed to fail (no error) if there is nothing at that340340- * target id.341341- */342342- if (shost->transportt->target_parent) {343343- spin_lock_irqsave(shost->host_lock, flags);344344- parent = shost->transportt->target_parent(shost, channel, id);345345- spin_unlock_irqrestore(shost->host_lock, flags);346346- if (!parent)347347- return NULL;348348- }349349-350337 starget = kmalloc(size, GFP_KERNEL);351338 if (!starget) {352339 printk(KERN_ERR "%s: allocation failure\n", __FUNCTION__);···12701283 struct scsi_device *sdev;12711284 struct device *parent = &shost->shost_gendev;12721285 int res;12731273- struct scsi_target *starget = scsi_alloc_target(parent, channel, id);12861286+ struct scsi_target *starget;1274128712881288+ starget = scsi_alloc_target(parent, channel, id);12751289 if (!starget)12761290 return ERR_PTR(-ENOMEM);1277129112781292 get_device(&starget->dev);12791279- down(&shost->scan_mutex);12931293+ mutex_lock(&shost->scan_mutex);12801294 if (scsi_host_scan_allowed(shost)) {12811295 res = scsi_probe_and_add_lun(starget, lun, NULL, &sdev, 1,12821296 hostdata);12831297 if (res != SCSI_SCAN_LUN_PRESENT)12841298 sdev = ERR_PTR(-ENODEV);12851299 }12861286- up(&shost->scan_mutex);13001300+ mutex_unlock(&shost->scan_mutex);12871301 scsi_target_reap(starget);12881302 put_device(&starget->dev);12891303···13921404{13931405 struct Scsi_Host *shost = dev_to_shost(parent);1394140613951395- down(&shost->scan_mutex);14071407+ mutex_lock(&shost->scan_mutex);13961408 if (scsi_host_scan_allowed(shost))13971409 __scsi_scan_target(parent, channel, id, lun, rescan);13981398- up(&shost->scan_mutex);14101410+ mutex_unlock(&shost->scan_mutex);13991411}14001412EXPORT_SYMBOL(scsi_scan_target);14011413···14421454 ((lun != SCAN_WILD_CARD) && (lun > shost->max_lun)))14431455 return -EINVAL;1444145614451445- down(&shost->scan_mutex);14571457+ mutex_lock(&shost->scan_mutex);14461458 if (scsi_host_scan_allowed(shost)) {14471459 if (channel == SCAN_WILD_CARD)14481460 for (channel = 0; channel <= shost->max_channel;···14521464 else14531465 scsi_scan_channel(shost, channel, id, lun, rescan);14541466 }14551455- up(&shost->scan_mutex);14671467+ mutex_unlock(&shost->scan_mutex);1456146814571469 return 0;14581470}···15101522 struct scsi_device *sdev = NULL;15111523 struct scsi_target *starget;1512152415131513- down(&shost->scan_mutex);15251525+ mutex_lock(&shost->scan_mutex);15141526 if (!scsi_host_scan_allowed(shost))15151527 goto out;15161528 starget = scsi_alloc_target(&shost->shost_gendev, 0, shost->this_id);···15241536 }15251537 put_device(&starget->dev);15261538 out:15271527- up(&shost->scan_mutex);15391539+ mutex_unlock(&shost->scan_mutex);15281540 return sdev;15291541}15301542EXPORT_SYMBOL(scsi_get_host_dev);
+6-3
drivers/scsi/scsi_sysfs.c
···106106 return -EINVAL;107107 if (check_set(&lun, s3))108108 return -EINVAL;109109- res = scsi_scan_host_selected(shost, channel, id, lun, 1);109109+ if (shost->transportt->user_scan)110110+ res = shost->transportt->user_scan(shost, channel, id, lun);111111+ else112112+ res = scsi_scan_host_selected(shost, channel, id, lun, 1);110113 return res;111114}112115···748745{749746 struct Scsi_Host *shost = sdev->host;750747751751- down(&shost->scan_mutex);748748+ mutex_lock(&shost->scan_mutex);752749 __scsi_remove_device(sdev);753753- up(&shost->scan_mutex);750750+ mutex_unlock(&shost->scan_mutex);754751}755752EXPORT_SYMBOL(scsi_remove_device);756753
+18-8
drivers/scsi/scsi_transport_fc.c
···295295 */296296 fc_host_node_name(shost) = -1;297297 fc_host_port_name(shost) = -1;298298+ fc_host_permanent_port_name(shost) = -1;298299 fc_host_supported_classes(shost) = FC_COS_UNSPECIFIED;299300 memset(fc_host_supported_fc4s(shost), 0,300301 sizeof(fc_host_supported_fc4s(shost)));···796795797796fc_private_host_rd_attr_cast(node_name, "0x%llx\n", 20, unsigned long long);798797fc_private_host_rd_attr_cast(port_name, "0x%llx\n", 20, unsigned long long);798798+fc_private_host_rd_attr_cast(permanent_port_name, "0x%llx\n", 20,799799+ unsigned long long);799800fc_private_host_rd_attr(symbolic_name, "%s\n", (FC_SYMBOLIC_NAME_SIZE +1));800801fc_private_host_rd_attr(maxframe_size, "%u bytes\n", 20);801802fc_private_host_rd_attr(serial_number, "%s\n", (FC_SERIAL_NUMBER_SIZE +1));···10931090/*10941091 * Must be called with shost->host_lock held10951092 */10961096-static struct device *fc_target_parent(struct Scsi_Host *shost,10971097- int channel, uint id)10931093+static int fc_user_scan(struct Scsi_Host *shost, uint channel,10941094+ uint id, uint lun)10981095{10991096 struct fc_rport *rport;1100109711011101- list_for_each_entry(rport, &fc_host_rports(shost), peers)11021102- if ((rport->channel == channel) &&11031103- (rport->scsi_target_id == id))11041104- return &rport->dev;10981098+ list_for_each_entry(rport, &fc_host_rports(shost), peers) {10991099+ if (rport->scsi_target_id == -1)11001100+ continue;1105110111061106- return NULL;11021102+ if ((channel == SCAN_WILD_CARD || channel == rport->channel) &&11031103+ (id == SCAN_WILD_CARD || id == rport->scsi_target_id)) {11041104+ scsi_scan_target(&rport->dev, rport->channel,11051105+ rport->scsi_target_id, lun, 1);11061106+ }11071107+ }11081108+11091109+ return 0;11071110}1108111111091112struct scsi_transport_template *···11481139 /* Transport uses the shost workq for scsi scanning */11491140 i->t.create_work_queue = 1;1150114111511151- i->t.target_parent = fc_target_parent;11421142+ i->t.user_scan = fc_user_scan;1152114311531144 /*11541145 * Setup SCSI Target Attributes.···11691160 count=0;11701161 SETUP_HOST_ATTRIBUTE_RD(node_name);11711162 SETUP_HOST_ATTRIBUTE_RD(port_name);11631163+ SETUP_HOST_ATTRIBUTE_RD(permanent_port_name);11721164 SETUP_HOST_ATTRIBUTE_RD(supported_classes);11731165 SETUP_HOST_ATTRIBUTE_RD(supported_fc4s);11741166 SETUP_HOST_ATTRIBUTE_RD(symbolic_name);
+474-437
drivers/scsi/scsi_transport_iscsi.c
···2121 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.2222 */2323#include <linux/module.h>2424-#include <linux/string.h>2525-#include <linux/slab.h>2624#include <linux/mempool.h>2525+#include <linux/mutex.h>2726#include <net/tcp.h>2828-2927#include <scsi/scsi.h>3028#include <scsi/scsi_host.h>3129#include <scsi/scsi_device.h>···4244 * List of sessions for this transport4345 */4446 struct list_head sessions;4545- /*4646- * lock to serialize access to the sessions list which must4747- * be taken after the rx_queue_sema4848- */4949- spinlock_t session_lock;5047 /*5148 * based on transport capabilities, at register time we set these5249 * bits to tell the transport class it wants attributes displayed···6370/*6471 * list of registered transports and lock that must6572 * be held while accessing list. The iscsi_transport_lock must6666- * be acquired after the rx_queue_sema.7373+ * be acquired after the rx_queue_mutex.6774 */6875static LIST_HEAD(iscsi_transports);6976static DEFINE_SPINLOCK(iscsi_transport_lock);···138145139146static struct sock *nls;140147static int daemon_pid;141141-static DECLARE_MUTEX(rx_queue_sema);148148+static DEFINE_MUTEX(rx_queue_mutex);142149143150struct mempool_zone {144151 mempool_t *pool;···149156 spinlock_t freelock;150157};151158152152-static struct mempool_zone z_reply;159159+static struct mempool_zone *z_reply;153160154161/*155162 * Z_MAX_* - actual mempool size allocated at the mempool_zone_init() time···164171#define Z_MAX_ERROR 16165172#define Z_HIWAT_ERROR 12166173167167-struct iscsi_if_conn {168168- struct list_head conn_list; /* item in connlist */169169- struct list_head session_list; /* item in session->connections */170170- iscsi_connh_t connh;171171- int active; /* must be accessed with the connlock */172172- struct Scsi_Host *host; /* originated shost */173173- struct device dev; /* sysfs transport/container device */174174- struct iscsi_transport *transport;175175- struct mempool_zone z_error;176176- struct mempool_zone z_pdu;177177- struct list_head freequeue;178178-};179179-180180-#define iscsi_dev_to_if_conn(_dev) \181181- container_of(_dev, struct iscsi_if_conn, dev)182182-183183-#define iscsi_cdev_to_if_conn(_cdev) \184184- iscsi_dev_to_if_conn(_cdev->dev)185185-186174static LIST_HEAD(connlist);187175static DEFINE_SPINLOCK(connlock);188176189189-struct iscsi_if_session {190190- struct list_head list; /* item in session_list */191191- struct list_head connections;192192- iscsi_sessionh_t sessionh;193193- struct iscsi_transport *transport;194194- struct device dev; /* sysfs transport/container device */195195-};177177+/*178178+ * The following functions can be used by LLDs that allocate179179+ * their own scsi_hosts or by software iscsi LLDs180180+ */181181+static void iscsi_session_release(struct device *dev)182182+{183183+ struct iscsi_cls_session *session = iscsi_dev_to_session(dev);184184+ struct iscsi_transport *transport = session->transport;185185+ struct Scsi_Host *shost;196186197197-#define iscsi_dev_to_if_session(_dev) \198198- container_of(_dev, struct iscsi_if_session, dev)187187+ shost = iscsi_session_to_shost(session);188188+ scsi_host_put(shost);189189+ kfree(session);190190+ module_put(transport->owner);191191+}199192200200-#define iscsi_cdev_to_if_session(_cdev) \201201- iscsi_dev_to_if_session(_cdev->dev)193193+static int iscsi_is_session_dev(const struct device *dev)194194+{195195+ return dev->release == iscsi_session_release;196196+}202197203203-#define iscsi_if_session_to_shost(_session) \204204- dev_to_shost(_session->dev.parent)198198+/**199199+ * iscsi_create_session - create iscsi class session200200+ * @shost: scsi host201201+ * @transport: iscsi transport202202+ *203203+ * This can be called from a LLD or iscsi_transport204204+ **/205205+struct iscsi_cls_session *206206+iscsi_create_session(struct Scsi_Host *shost, struct iscsi_transport *transport)207207+{208208+ struct iscsi_cls_session *session;209209+ int err;205210206206-static struct iscsi_if_conn*211211+ if (!try_module_get(transport->owner))212212+ return NULL;213213+214214+ session = kzalloc(sizeof(*session), GFP_KERNEL);215215+ if (!session)216216+ goto module_put;217217+ session->transport = transport;218218+219219+ /* this is released in the dev's release function */220220+ scsi_host_get(shost);221221+ snprintf(session->dev.bus_id, BUS_ID_SIZE, "session%u", shost->host_no);222222+ session->dev.parent = &shost->shost_gendev;223223+ session->dev.release = iscsi_session_release;224224+ err = device_register(&session->dev);225225+ if (err) {226226+ dev_printk(KERN_ERR, &session->dev, "iscsi: could not "227227+ "register session's dev\n");228228+ goto free_session;229229+ }230230+ transport_register_device(&session->dev);231231+232232+ return session;233233+234234+free_session:235235+ kfree(session);236236+module_put:237237+ module_put(transport->owner);238238+ return NULL;239239+}240240+241241+EXPORT_SYMBOL_GPL(iscsi_create_session);242242+243243+/**244244+ * iscsi_destroy_session - destroy iscsi session245245+ * @session: iscsi_session246246+ *247247+ * Can be called by a LLD or iscsi_transport. There must not be248248+ * any running connections.249249+ **/250250+int iscsi_destroy_session(struct iscsi_cls_session *session)251251+{252252+ transport_unregister_device(&session->dev);253253+ device_unregister(&session->dev);254254+ return 0;255255+}256256+257257+EXPORT_SYMBOL_GPL(iscsi_destroy_session);258258+259259+static void iscsi_conn_release(struct device *dev)260260+{261261+ struct iscsi_cls_conn *conn = iscsi_dev_to_conn(dev);262262+ struct device *parent = conn->dev.parent;263263+264264+ kfree(conn);265265+ put_device(parent);266266+}267267+268268+static int iscsi_is_conn_dev(const struct device *dev)269269+{270270+ return dev->release == iscsi_conn_release;271271+}272272+273273+/**274274+ * iscsi_create_conn - create iscsi class connection275275+ * @session: iscsi cls session276276+ * @cid: connection id277277+ *278278+ * This can be called from a LLD or iscsi_transport. The connection279279+ * is child of the session so cid must be unique for all connections280280+ * on the session.281281+ **/282282+struct iscsi_cls_conn *283283+iscsi_create_conn(struct iscsi_cls_session *session, uint32_t cid)284284+{285285+ struct iscsi_transport *transport = session->transport;286286+ struct Scsi_Host *shost = iscsi_session_to_shost(session);287287+ struct iscsi_cls_conn *conn;288288+ int err;289289+290290+ conn = kzalloc(sizeof(*conn) + transport->conndata_size, GFP_KERNEL);291291+ if (!conn)292292+ return NULL;293293+294294+ if (transport->conndata_size)295295+ conn->dd_data = &conn[1];296296+297297+ INIT_LIST_HEAD(&conn->conn_list);298298+ conn->transport = transport;299299+300300+ /* this is released in the dev's release function */301301+ if (!get_device(&session->dev))302302+ goto free_conn;303303+ snprintf(conn->dev.bus_id, BUS_ID_SIZE, "connection%d:%u",304304+ shost->host_no, cid);305305+ conn->dev.parent = &session->dev;306306+ conn->dev.release = iscsi_conn_release;307307+ err = device_register(&conn->dev);308308+ if (err) {309309+ dev_printk(KERN_ERR, &conn->dev, "iscsi: could not register "310310+ "connection's dev\n");311311+ goto release_parent_ref;312312+ }313313+ transport_register_device(&conn->dev);314314+ return conn;315315+316316+release_parent_ref:317317+ put_device(&session->dev);318318+free_conn:319319+ kfree(conn);320320+ return NULL;321321+}322322+323323+EXPORT_SYMBOL_GPL(iscsi_create_conn);324324+325325+/**326326+ * iscsi_destroy_conn - destroy iscsi class connection327327+ * @session: iscsi cls session328328+ *329329+ * This can be called from a LLD or iscsi_transport.330330+ **/331331+int iscsi_destroy_conn(struct iscsi_cls_conn *conn)332332+{333333+ transport_unregister_device(&conn->dev);334334+ device_unregister(&conn->dev);335335+ return 0;336336+}337337+338338+EXPORT_SYMBOL_GPL(iscsi_destroy_conn);339339+340340+/*341341+ * These functions are used only by software iscsi_transports342342+ * which do not allocate and more their scsi_hosts since this343343+ * is initiated from userspace.344344+ */345345+346346+/*347347+ * iSCSI Session's hostdata organization:348348+ *349349+ * *------------------* <== hostdata_session(host->hostdata)350350+ * | ptr to class sess|351351+ * |------------------| <== iscsi_hostdata(host->hostdata)352352+ * | transport's data |353353+ * *------------------*354354+ */355355+356356+#define hostdata_privsize(_t) (sizeof(unsigned long) + _t->hostdata_size + \357357+ _t->hostdata_size % sizeof(unsigned long))358358+359359+#define hostdata_session(_hostdata) (iscsi_ptr(*(unsigned long *)_hostdata))360360+361361+/**362362+ * iscsi_transport_create_session - create iscsi cls session and host363363+ * scsit: scsi transport template364364+ * transport: iscsi transport template365365+ *366366+ * This can be used by software iscsi_transports that allocate367367+ * a session per scsi host.368368+ **/369369+struct Scsi_Host *370370+iscsi_transport_create_session(struct scsi_transport_template *scsit,371371+ struct iscsi_transport *transport)372372+{373373+ struct iscsi_cls_session *session;374374+ struct Scsi_Host *shost;375375+376376+ shost = scsi_host_alloc(transport->host_template,377377+ hostdata_privsize(transport));378378+ if (!shost) {379379+ printk(KERN_ERR "iscsi: can not allocate SCSI host for "380380+ "session\n");381381+ return NULL;382382+ }383383+384384+ shost->max_id = 1;385385+ shost->max_channel = 0;386386+ shost->max_lun = transport->max_lun;387387+ shost->max_cmd_len = transport->max_cmd_len;388388+ shost->transportt = scsit;389389+ shost->transportt->create_work_queue = 1;390390+391391+ if (scsi_add_host(shost, NULL))392392+ goto free_host;393393+394394+ session = iscsi_create_session(shost, transport);395395+ if (!session)396396+ goto remove_host;397397+398398+ *(unsigned long*)shost->hostdata = (unsigned long)session;399399+ return shost;400400+401401+remove_host:402402+ scsi_remove_host(shost);403403+free_host:404404+ scsi_host_put(shost);405405+ return NULL;406406+}407407+408408+EXPORT_SYMBOL_GPL(iscsi_transport_create_session);409409+410410+/**411411+ * iscsi_transport_destroy_session - destroy session and scsi host412412+ * shost: scsi host413413+ *414414+ * This can be used by software iscsi_transports that allocate415415+ * a session per scsi host.416416+ **/417417+int iscsi_transport_destroy_session(struct Scsi_Host *shost)418418+{419419+ struct iscsi_cls_session *session;420420+421421+ scsi_remove_host(shost);422422+ session = hostdata_session(shost->hostdata);423423+ iscsi_destroy_session(session);424424+ /* ref from host alloc */425425+ scsi_host_put(shost);426426+ return 0;427427+}428428+429429+EXPORT_SYMBOL_GPL(iscsi_transport_destroy_session);430430+431431+/*432432+ * iscsi interface functions433433+ */434434+static struct iscsi_cls_conn*207435iscsi_if_find_conn(uint64_t key)208436{209437 unsigned long flags;210210- struct iscsi_if_conn *conn;438438+ struct iscsi_cls_conn *conn;211439212440 spin_lock_irqsave(&connlock, flags);213441 list_for_each_entry(conn, &connlist, conn_list)···463249}464250465251static void*466466-mempool_zone_alloc_skb(gfp_t gfp_mask, void *pool_data)252252+mempool_zone_alloc_skb(unsigned int gfp_mask, void *pool_data)467253{468254 struct mempool_zone *zone = pool_data;469255···495281 spin_unlock_irqrestore(&zone->freelock, flags);496282}497283498498-static int499499-mempool_zone_init(struct mempool_zone *zp, unsigned max, unsigned size,500500- unsigned hiwat)284284+static struct mempool_zone *285285+mempool_zone_init(unsigned max, unsigned size, unsigned hiwat)501286{287287+ struct mempool_zone *zp;288288+289289+ zp = kzalloc(sizeof(*zp), GFP_KERNEL);290290+ if (!zp)291291+ return NULL;292292+502293 zp->pool = mempool_create(max, mempool_zone_alloc_skb,503294 mempool_zone_free_skb, zp);504504- if (!zp->pool)505505- return -ENOMEM;295295+ if (!zp->pool) {296296+ kfree(zp);297297+ return NULL;298298+ }506299507300 zp->size = size;508301 zp->hiwat = hiwat;···518297 spin_lock_init(&zp->freelock);519298 atomic_set(&zp->allocated, 0);520299521521- return 0;300300+ return zp;522301}523302303303+static void mempool_zone_destroy(struct mempool_zone *zp)304304+{305305+ mempool_destroy(zp->pool);306306+ kfree(zp);307307+}524308525309static struct sk_buff*526310mempool_zone_get_skb(struct mempool_zone *zone)···565339 struct nlmsghdr *nlh;566340 struct sk_buff *skb;567341 struct iscsi_uevent *ev;568568- struct iscsi_if_conn *conn;342342+ struct iscsi_cls_conn *conn;569343 char *pdu;570344 int len = NLMSG_SPACE(sizeof(*ev) + sizeof(struct iscsi_hdr) +571345 data_size);···573347 conn = iscsi_if_find_conn(connh);574348 BUG_ON(!conn);575349576576- mempool_zone_complete(&conn->z_pdu);350350+ mempool_zone_complete(conn->z_pdu);577351578578- skb = mempool_zone_get_skb(&conn->z_pdu);352352+ skb = mempool_zone_get_skb(conn->z_pdu);579353 if (!skb) {580354 iscsi_conn_error(connh, ISCSI_ERR_CONN_FAILED);581581- printk(KERN_ERR "iscsi%d: can not deliver control PDU: OOM\n",582582- conn->host->host_no);355355+ dev_printk(KERN_ERR, &conn->dev, "iscsi: can not deliver "356356+ "control PDU: OOM\n");583357 return -ENOMEM;584358 }585359···588362 memset(ev, 0, sizeof(*ev));589363 ev->transport_handle = iscsi_handle(conn->transport);590364 ev->type = ISCSI_KEVENT_RECV_PDU;591591- if (atomic_read(&conn->z_pdu.allocated) >= conn->z_pdu.hiwat)365365+ if (atomic_read(&conn->z_pdu->allocated) >= conn->z_pdu->hiwat)592366 ev->iferror = -ENOMEM;593367 ev->r.recv_req.conn_handle = connh;594368 pdu = (char*)ev + sizeof(*ev);595369 memcpy(pdu, hdr, sizeof(struct iscsi_hdr));596370 memcpy(pdu + sizeof(struct iscsi_hdr), data, data_size);597371598598- return iscsi_unicast_skb(&conn->z_pdu, skb);372372+ return iscsi_unicast_skb(conn->z_pdu, skb);599373}600374EXPORT_SYMBOL_GPL(iscsi_recv_pdu);601375···604378 struct nlmsghdr *nlh;605379 struct sk_buff *skb;606380 struct iscsi_uevent *ev;607607- struct iscsi_if_conn *conn;381381+ struct iscsi_cls_conn *conn;608382 int len = NLMSG_SPACE(sizeof(*ev));609383610384 conn = iscsi_if_find_conn(connh);611385 BUG_ON(!conn);612386613613- mempool_zone_complete(&conn->z_error);387387+ mempool_zone_complete(conn->z_error);614388615615- skb = mempool_zone_get_skb(&conn->z_error);389389+ skb = mempool_zone_get_skb(conn->z_error);616390 if (!skb) {617617- printk(KERN_ERR "iscsi%d: gracefully ignored conn error (%d)\n",618618- conn->host->host_no, error);391391+ dev_printk(KERN_ERR, &conn->dev, "iscsi: gracefully ignored "392392+ "conn error (%d)\n", error);619393 return;620394 }621395···623397 ev = NLMSG_DATA(nlh);624398 ev->transport_handle = iscsi_handle(conn->transport);625399 ev->type = ISCSI_KEVENT_CONN_ERROR;626626- if (atomic_read(&conn->z_error.allocated) >= conn->z_error.hiwat)400400+ if (atomic_read(&conn->z_error->allocated) >= conn->z_error->hiwat)627401 ev->iferror = -ENOMEM;628402 ev->r.connerror.error = error;629403 ev->r.connerror.conn_handle = connh;630404631631- iscsi_unicast_skb(&conn->z_error, skb);405405+ iscsi_unicast_skb(conn->z_error, skb);632406633633- printk(KERN_INFO "iscsi%d: detected conn error (%d)\n",634634- conn->host->host_no, error);407407+ dev_printk(KERN_INFO, &conn->dev, "iscsi: detected conn error (%d)\n",408408+ error);635409}636410EXPORT_SYMBOL_GPL(iscsi_conn_error);637411···645419 int flags = multi ? NLM_F_MULTI : 0;646420 int t = done ? NLMSG_DONE : type;647421648648- mempool_zone_complete(&z_reply);422422+ mempool_zone_complete(z_reply);649423650650- skb = mempool_zone_get_skb(&z_reply);424424+ skb = mempool_zone_get_skb(z_reply);651425 /*652426 * FIXME:653427 * user is supposed to react on iferror == -ENOMEM;···658432 nlh = __nlmsg_put(skb, pid, seq, t, (len - sizeof(*nlh)), 0);659433 nlh->nlmsg_flags = flags;660434 memcpy(NLMSG_DATA(nlh), payload, size);661661- return iscsi_unicast_skb(&z_reply, skb);662662-}663663-664664-/*665665- * iSCSI Session's hostdata organization:666666- *667667- * *------------------* <== host->hostdata668668- * | transport |669669- * |------------------| <== iscsi_hostdata(host->hostdata)670670- * | transport's data |671671- * |------------------| <== hostdata_session(host->hostdata)672672- * | interface's data |673673- * *------------------*674674- */675675-676676-#define hostdata_privsize(_t) (sizeof(unsigned long) + _t->hostdata_size + \677677- _t->hostdata_size % sizeof(unsigned long) + \678678- sizeof(struct iscsi_if_session))679679-680680-#define hostdata_session(_hostdata) ((void*)_hostdata + sizeof(unsigned long) + \681681- ((struct iscsi_transport *) \682682- iscsi_ptr(*(uint64_t *)_hostdata))->hostdata_size)683683-684684-static void iscsi_if_session_dev_release(struct device *dev)685685-{686686- struct iscsi_if_session *session = iscsi_dev_to_if_session(dev);687687- struct iscsi_transport *transport = session->transport;688688- struct Scsi_Host *shost = iscsi_if_session_to_shost(session);689689- struct iscsi_if_conn *conn, *tmp;690690- unsigned long flags;691691-692692- /* now free connections */693693- spin_lock_irqsave(&connlock, flags);694694- list_for_each_entry_safe(conn, tmp, &session->connections,695695- session_list) {696696- list_del(&conn->session_list);697697- mempool_destroy(conn->z_pdu.pool);698698- mempool_destroy(conn->z_error.pool);699699- kfree(conn);700700- }701701- spin_unlock_irqrestore(&connlock, flags);702702- scsi_host_put(shost);703703- module_put(transport->owner);704704-}705705-706706-static int707707-iscsi_if_create_session(struct iscsi_internal *priv, struct iscsi_uevent *ev)708708-{709709- struct iscsi_transport *transport = priv->iscsi_transport;710710- struct iscsi_if_session *session;711711- struct Scsi_Host *shost;712712- unsigned long flags;713713- int error;714714-715715- if (!try_module_get(transport->owner))716716- return -EPERM;717717-718718- shost = scsi_host_alloc(transport->host_template,719719- hostdata_privsize(transport));720720- if (!shost) {721721- ev->r.c_session_ret.session_handle = iscsi_handle(NULL);722722- printk(KERN_ERR "iscsi: can not allocate SCSI host for "723723- "session\n");724724- error = -ENOMEM;725725- goto out_module_put;726726- }727727- shost->max_id = 1;728728- shost->max_channel = 0;729729- shost->max_lun = transport->max_lun;730730- shost->max_cmd_len = transport->max_cmd_len;731731- shost->transportt = &priv->t;732732-733733- /* store struct iscsi_transport in hostdata */734734- *(uint64_t*)shost->hostdata = ev->transport_handle;735735-736736- ev->r.c_session_ret.session_handle = transport->create_session(737737- ev->u.c_session.initial_cmdsn, shost);738738- if (ev->r.c_session_ret.session_handle == iscsi_handle(NULL)) {739739- error = 0;740740- goto out_host_put;741741- }742742-743743- /* host_no becomes assigned SID */744744- ev->r.c_session_ret.sid = shost->host_no;745745- /* initialize session */746746- session = hostdata_session(shost->hostdata);747747- INIT_LIST_HEAD(&session->connections);748748- INIT_LIST_HEAD(&session->list);749749- session->sessionh = ev->r.c_session_ret.session_handle;750750- session->transport = transport;751751-752752- error = scsi_add_host(shost, NULL);753753- if (error)754754- goto out_destroy_session;755755-756756- /*757757- * this is released in the dev's release function)758758- */759759- scsi_host_get(shost);760760- snprintf(session->dev.bus_id, BUS_ID_SIZE, "session%u", shost->host_no);761761- session->dev.parent = &shost->shost_gendev;762762- session->dev.release = iscsi_if_session_dev_release;763763- error = device_register(&session->dev);764764- if (error) {765765- printk(KERN_ERR "iscsi: could not register session%d's dev\n",766766- shost->host_no);767767- goto out_remove_host;768768- }769769- transport_register_device(&session->dev);770770-771771- /* add this session to the list of active sessions */772772- spin_lock_irqsave(&priv->session_lock, flags);773773- list_add(&session->list, &priv->sessions);774774- spin_unlock_irqrestore(&priv->session_lock, flags);775775-776776- return 0;777777-778778-out_remove_host:779779- scsi_remove_host(shost);780780-out_destroy_session:781781- transport->destroy_session(ev->r.c_session_ret.session_handle);782782- ev->r.c_session_ret.session_handle = iscsi_handle(NULL);783783-out_host_put:784784- scsi_host_put(shost);785785-out_module_put:786786- module_put(transport->owner);787787- return error;788788-}789789-790790-static int791791-iscsi_if_destroy_session(struct iscsi_internal *priv, struct iscsi_uevent *ev)792792-{793793- struct iscsi_transport *transport = priv->iscsi_transport;794794- struct Scsi_Host *shost;795795- struct iscsi_if_session *session;796796- unsigned long flags;797797- struct iscsi_if_conn *conn;798798- int error = 0;799799-800800- shost = scsi_host_lookup(ev->u.d_session.sid);801801- if (shost == ERR_PTR(-ENXIO))802802- return -EEXIST;803803- session = hostdata_session(shost->hostdata);804804-805805- /* check if we have active connections */806806- spin_lock_irqsave(&connlock, flags);807807- list_for_each_entry(conn, &session->connections, session_list) {808808- if (conn->active) {809809- printk(KERN_ERR "iscsi%d: can not destroy session: "810810- "has active connection (%p)\n",811811- shost->host_no, iscsi_ptr(conn->connh));812812- spin_unlock_irqrestore(&connlock, flags);813813- error = EIO;814814- goto out_release_ref;815815- }816816- }817817- spin_unlock_irqrestore(&connlock, flags);818818-819819- scsi_remove_host(shost);820820- transport->destroy_session(ev->u.d_session.session_handle);821821- transport_unregister_device(&session->dev);822822- device_unregister(&session->dev);823823-824824- /* remove this session from the list of active sessions */825825- spin_lock_irqsave(&priv->session_lock, flags);826826- list_del(&session->list);827827- spin_unlock_irqrestore(&priv->session_lock, flags);828828-829829- /* ref from host alloc */830830- scsi_host_put(shost);831831-out_release_ref:832832- /* ref from host lookup */833833- scsi_host_put(shost);834834- return error;835835-}836836-837837-static void iscsi_if_conn_dev_release(struct device *dev)838838-{839839- struct iscsi_if_conn *conn = iscsi_dev_to_if_conn(dev);840840- struct Scsi_Host *shost = conn->host;841841-842842- scsi_host_put(shost);843843-}844844-845845-static int846846-iscsi_if_create_conn(struct iscsi_transport *transport, struct iscsi_uevent *ev)847847-{848848- struct iscsi_if_session *session;849849- struct Scsi_Host *shost;850850- struct iscsi_if_conn *conn;851851- unsigned long flags;852852- int error;853853-854854- shost = scsi_host_lookup(ev->u.c_conn.sid);855855- if (shost == ERR_PTR(-ENXIO))856856- return -EEXIST;857857- session = hostdata_session(shost->hostdata);858858-859859- conn = kmalloc(sizeof(struct iscsi_if_conn), GFP_KERNEL);860860- if (!conn) {861861- error = -ENOMEM;862862- goto out_release_ref;863863- }864864- memset(conn, 0, sizeof(struct iscsi_if_conn));865865- INIT_LIST_HEAD(&conn->session_list);866866- INIT_LIST_HEAD(&conn->conn_list);867867- conn->host = shost;868868- conn->transport = transport;869869-870870- error = mempool_zone_init(&conn->z_pdu, Z_MAX_PDU,871871- NLMSG_SPACE(sizeof(struct iscsi_uevent) +872872- sizeof(struct iscsi_hdr) +873873- DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH),874874- Z_HIWAT_PDU);875875- if (error) {876876- printk(KERN_ERR "iscsi%d: can not allocate pdu zone for new "877877- "conn\n", shost->host_no);878878- goto out_free_conn;879879- }880880- error = mempool_zone_init(&conn->z_error, Z_MAX_ERROR,881881- NLMSG_SPACE(sizeof(struct iscsi_uevent)),882882- Z_HIWAT_ERROR);883883- if (error) {884884- printk(KERN_ERR "iscsi%d: can not allocate error zone for "885885- "new conn\n", shost->host_no);886886- goto out_free_pdu_pool;887887- }888888-889889- ev->r.handle = transport->create_conn(ev->u.c_conn.session_handle,890890- ev->u.c_conn.cid);891891- if (!ev->r.handle) {892892- error = -ENODEV;893893- goto out_free_error_pool;894894- }895895-896896- conn->connh = ev->r.handle;897897-898898- /*899899- * this is released in the dev's release function900900- */901901- if (!scsi_host_get(shost))902902- goto out_destroy_conn;903903- snprintf(conn->dev.bus_id, BUS_ID_SIZE, "connection%d:%u",904904- shost->host_no, ev->u.c_conn.cid);905905- conn->dev.parent = &session->dev;906906- conn->dev.release = iscsi_if_conn_dev_release;907907- error = device_register(&conn->dev);908908- if (error) {909909- printk(KERN_ERR "iscsi%d: could not register connections%u "910910- "dev\n", shost->host_no, ev->u.c_conn.cid);911911- goto out_release_parent_ref;912912- }913913- transport_register_device(&conn->dev);914914-915915- spin_lock_irqsave(&connlock, flags);916916- list_add(&conn->conn_list, &connlist);917917- list_add(&conn->session_list, &session->connections);918918- conn->active = 1;919919- spin_unlock_irqrestore(&connlock, flags);920920-921921- scsi_host_put(shost);922922- return 0;923923-924924-out_release_parent_ref:925925- scsi_host_put(shost);926926-out_destroy_conn:927927- transport->destroy_conn(ev->r.handle);928928-out_free_error_pool:929929- mempool_destroy(conn->z_error.pool);930930-out_free_pdu_pool:931931- mempool_destroy(conn->z_pdu.pool);932932-out_free_conn:933933- kfree(conn);934934-out_release_ref:935935- scsi_host_put(shost);936936- return error;937937-}938938-939939-static int940940-iscsi_if_destroy_conn(struct iscsi_transport *transport, struct iscsi_uevent *ev)941941-{942942- unsigned long flags;943943- struct iscsi_if_conn *conn;944944-945945- conn = iscsi_if_find_conn(ev->u.d_conn.conn_handle);946946- if (!conn)947947- return -EEXIST;948948-949949- transport->destroy_conn(ev->u.d_conn.conn_handle);950950-951951- spin_lock_irqsave(&connlock, flags);952952- conn->active = 0;953953- list_del(&conn->conn_list);954954- spin_unlock_irqrestore(&connlock, flags);955955-956956- transport_unregister_device(&conn->dev);957957- device_unregister(&conn->dev);958958- return 0;435435+ return iscsi_unicast_skb(z_reply, skb);959436}960437961438static int···668739 struct iscsi_uevent *ev = NLMSG_DATA(nlh);669740 struct iscsi_stats *stats;670741 struct sk_buff *skbstat;671671- struct iscsi_if_conn *conn;742742+ struct iscsi_cls_conn *conn;672743 struct nlmsghdr *nlhstat;673744 struct iscsi_uevent *evstat;674745 int len = NLMSG_SPACE(sizeof(*ev) +···684755 do {685756 int actual_size;686757687687- mempool_zone_complete(&conn->z_pdu);758758+ mempool_zone_complete(conn->z_pdu);688759689689- skbstat = mempool_zone_get_skb(&conn->z_pdu);760760+ skbstat = mempool_zone_get_skb(conn->z_pdu);690761 if (!skbstat) {691691- printk(KERN_ERR "iscsi%d: can not deliver stats: OOM\n",692692- conn->host->host_no);762762+ dev_printk(KERN_ERR, &conn->dev, "iscsi: can not "763763+ "deliver stats: OOM\n");693764 return -ENOMEM;694765 }695766···699770 memset(evstat, 0, sizeof(*evstat));700771 evstat->transport_handle = iscsi_handle(conn->transport);701772 evstat->type = nlh->nlmsg_type;702702- if (atomic_read(&conn->z_pdu.allocated) >= conn->z_pdu.hiwat)773773+ if (atomic_read(&conn->z_pdu->allocated) >= conn->z_pdu->hiwat)703774 evstat->iferror = -ENOMEM;704775 evstat->u.get_stats.conn_handle =705776 ev->u.get_stats.conn_handle;···717788 skb_trim(skb, NLMSG_ALIGN(actual_size));718789 nlhstat->nlmsg_len = actual_size;719790720720- err = iscsi_unicast_skb(&conn->z_pdu, skbstat);791791+ err = iscsi_unicast_skb(conn->z_pdu, skbstat);721792 } while (err < 0 && err != -ECONNREFUSED);722793723794 return err;795795+}796796+797797+static int798798+iscsi_if_create_session(struct iscsi_internal *priv, struct iscsi_uevent *ev)799799+{800800+ struct iscsi_transport *transport = priv->iscsi_transport;801801+ struct Scsi_Host *shost;802802+803803+ if (!transport->create_session)804804+ return -EINVAL;805805+806806+ shost = transport->create_session(&priv->t,807807+ ev->u.c_session.initial_cmdsn);808808+ if (!shost)809809+ return -ENOMEM;810810+811811+ ev->r.c_session_ret.session_handle = iscsi_handle(iscsi_hostdata(shost->hostdata));812812+ ev->r.c_session_ret.sid = shost->host_no;813813+ return 0;814814+}815815+816816+static int817817+iscsi_if_destroy_session(struct iscsi_internal *priv, struct iscsi_uevent *ev)818818+{819819+ struct iscsi_transport *transport = priv->iscsi_transport;820820+821821+ struct Scsi_Host *shost;822822+823823+ if (!transport->destroy_session)824824+ return -EINVAL;825825+826826+ shost = scsi_host_lookup(ev->u.d_session.sid);827827+ if (shost == ERR_PTR(-ENXIO))828828+ return -EEXIST;829829+830830+ if (transport->destroy_session)831831+ transport->destroy_session(shost);832832+ /* ref from host lookup */833833+ scsi_host_put(shost);834834+ return 0;835835+}836836+837837+static int838838+iscsi_if_create_conn(struct iscsi_transport *transport, struct iscsi_uevent *ev){839839+ struct Scsi_Host *shost;840840+ struct iscsi_cls_conn *conn;841841+ unsigned long flags;842842+843843+ if (!transport->create_conn)844844+ return -EINVAL;845845+846846+ shost = scsi_host_lookup(ev->u.c_conn.sid);847847+ if (shost == ERR_PTR(-ENXIO))848848+ return -EEXIST;849849+850850+ conn = transport->create_conn(shost, ev->u.c_conn.cid);851851+ if (!conn)852852+ goto release_ref;853853+854854+ conn->z_pdu = mempool_zone_init(Z_MAX_PDU,855855+ NLMSG_SPACE(sizeof(struct iscsi_uevent) +856856+ sizeof(struct iscsi_hdr) +857857+ DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH),858858+ Z_HIWAT_PDU);859859+ if (!conn->z_pdu) {860860+ dev_printk(KERN_ERR, &conn->dev, "iscsi: can not allocate "861861+ "pdu zone for new conn\n");862862+ goto destroy_conn;863863+ }864864+865865+ conn->z_error = mempool_zone_init(Z_MAX_ERROR,866866+ NLMSG_SPACE(sizeof(struct iscsi_uevent)),867867+ Z_HIWAT_ERROR);868868+ if (!conn->z_error) {869869+ dev_printk(KERN_ERR, &conn->dev, "iscsi: can not allocate "870870+ "error zone for new conn\n");871871+ goto free_pdu_pool;872872+ }873873+874874+ ev->r.handle = conn->connh = iscsi_handle(conn->dd_data);875875+876876+ spin_lock_irqsave(&connlock, flags);877877+ list_add(&conn->conn_list, &connlist);878878+ conn->active = 1;879879+ spin_unlock_irqrestore(&connlock, flags);880880+881881+ scsi_host_put(shost);882882+ return 0;883883+884884+free_pdu_pool:885885+ mempool_zone_destroy(conn->z_pdu);886886+destroy_conn:887887+ if (transport->destroy_conn)888888+ transport->destroy_conn(conn->dd_data);889889+release_ref:890890+ scsi_host_put(shost);891891+ return -ENOMEM;892892+}893893+894894+static int895895+iscsi_if_destroy_conn(struct iscsi_transport *transport, struct iscsi_uevent *ev)896896+{897897+ unsigned long flags;898898+ struct iscsi_cls_conn *conn;899899+ struct mempool_zone *z_error, *z_pdu;900900+901901+ conn = iscsi_if_find_conn(ev->u.d_conn.conn_handle);902902+ if (!conn)903903+ return -EEXIST;904904+905905+ if (!transport->destroy_conn)906906+ return -EINVAL;907907+908908+ spin_lock_irqsave(&connlock, flags);909909+ conn->active = 0;910910+ list_del(&conn->conn_list);911911+ spin_unlock_irqrestore(&connlock, flags);912912+913913+ z_pdu = conn->z_pdu;914914+ z_error = conn->z_error;915915+916916+ if (transport->destroy_conn)917917+ transport->destroy_conn(conn);918918+919919+ mempool_zone_destroy(z_pdu);920920+ mempool_zone_destroy(z_error);921921+922922+ return 0;724923}725924726925static int···938881{939882 struct sk_buff *skb;940883941941- down(&rx_queue_sema);884884+ mutex_lock(&rx_queue_mutex);942885 while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) {943886 while (skb->len >= NLMSG_SPACE(0)) {944887 int err;···972915 err = iscsi_if_send_reply(973916 NETLINK_CREDS(skb)->pid, nlh->nlmsg_seq,974917 nlh->nlmsg_type, 0, 0, ev, sizeof(*ev));975975- if (atomic_read(&z_reply.allocated) >=976976- z_reply.hiwat)918918+ if (atomic_read(&z_reply->allocated) >=919919+ z_reply->hiwat)977920 ev->iferror = -ENOMEM;978921 } while (err < 0 && err != -ECONNREFUSED);979922 skb_pull(skb, rlen);980923 }981924 kfree_skb(skb);982925 }983983- up(&rx_queue_sema);926926+ mutex_unlock(&rx_queue_mutex);984927}928928+929929+#define iscsi_cdev_to_conn(_cdev) \930930+ iscsi_dev_to_conn(_cdev->dev)985931986932/*987933 * iSCSI connection attrs···994934show_conn_int_param_##param(struct class_device *cdev, char *buf) \995935{ \996936 uint32_t value = 0; \997997- struct iscsi_if_conn *conn = iscsi_cdev_to_if_conn(cdev); \998998- struct iscsi_internal *priv; \937937+ struct iscsi_cls_conn *conn = iscsi_cdev_to_conn(cdev); \938938+ struct iscsi_transport *t = conn->transport; \999939 \10001000- priv = to_iscsi_internal(conn->host->transportt); \10011001- if (priv->param_mask & (1 << param)) \10021002- priv->iscsi_transport->get_param(conn->connh, param, &value); \940940+ t->get_conn_param(conn->dd_data, param, &value); \1003941 return snprintf(buf, 20, format"\n", value); \1004942}1005943···1012954iscsi_conn_int_attr(ifmarker, ISCSI_PARAM_IFMARKER_EN, "%d");1013955iscsi_conn_int_attr(ofmarker, ISCSI_PARAM_OFMARKER_EN, "%d");1014956957957+#define iscsi_cdev_to_session(_cdev) \958958+ iscsi_dev_to_session(_cdev->dev)959959+1015960/*1016961 * iSCSI session attrs1017962 */···1023962show_session_int_param_##param(struct class_device *cdev, char *buf) \1024963{ \1025964 uint32_t value = 0; \10261026- struct iscsi_if_session *session = iscsi_cdev_to_if_session(cdev); \10271027- struct Scsi_Host *shost = iscsi_if_session_to_shost(session); \10281028- struct iscsi_internal *priv = to_iscsi_internal(shost->transportt); \10291029- struct iscsi_if_conn *conn = NULL; \10301030- unsigned long flags; \965965+ struct iscsi_cls_session *session = iscsi_cdev_to_session(cdev); \966966+ struct Scsi_Host *shost = iscsi_session_to_shost(session); \967967+ struct iscsi_transport *t = session->transport; \1031968 \10321032- spin_lock_irqsave(&connlock, flags); \10331033- if (!list_empty(&session->connections)) \10341034- conn = list_entry(session->connections.next, \10351035- struct iscsi_if_conn, session_list); \10361036- spin_unlock_irqrestore(&connlock, flags); \10371037- \10381038- if (conn && (priv->param_mask & (1 << param))) \10391039- priv->iscsi_transport->get_param(conn->connh, param, &value);\969969+ t->get_session_param(shost, param, &value); \1040970 return snprintf(buf, 20, format"\n", value); \1041971}1042972···10561004 count++; \10571005 }1058100610591059-static int iscsi_is_session_dev(const struct device *dev)10601060-{10611061- return dev->release == iscsi_if_session_dev_release;10621062-}10631063-10641007static int iscsi_session_match(struct attribute_container *cont,10651008 struct device *dev)10661009{10671067- struct iscsi_if_session *session;10101010+ struct iscsi_cls_session *session;10681011 struct Scsi_Host *shost;10691012 struct iscsi_internal *priv;1070101310711014 if (!iscsi_is_session_dev(dev))10721015 return 0;1073101610741074- session = iscsi_dev_to_if_session(dev);10751075- shost = iscsi_if_session_to_shost(session);10171017+ session = iscsi_dev_to_session(dev);10181018+ shost = iscsi_session_to_shost(session);10761019 if (!shost->transportt)10771020 return 0;10781021···10781031 return &priv->session_cont.ac == cont;10791032}1080103310811081-static int iscsi_is_conn_dev(const struct device *dev)10821082-{10831083- return dev->release == iscsi_if_conn_dev_release;10841084-}10851085-10861034static int iscsi_conn_match(struct attribute_container *cont,10871035 struct device *dev)10881036{10891089- struct iscsi_if_conn *conn;10371037+ struct iscsi_cls_session *session;10381038+ struct iscsi_cls_conn *conn;10901039 struct Scsi_Host *shost;10911040 struct iscsi_internal *priv;1092104110931042 if (!iscsi_is_conn_dev(dev))10941043 return 0;1095104410961096- conn = iscsi_dev_to_if_conn(dev);10971097- shost = conn->host;10451045+ conn = iscsi_dev_to_conn(dev);10461046+ session = iscsi_dev_to_session(conn->dev.parent);10471047+ shost = iscsi_session_to_shost(session);10481048+10981049 if (!shost->transportt)10991050 return 0;11001051···11031058 return &priv->conn_cont.ac == cont;11041059}1105106011061106-int iscsi_register_transport(struct iscsi_transport *tt)10611061+struct scsi_transport_template *10621062+iscsi_register_transport(struct iscsi_transport *tt)11071063{11081064 struct iscsi_internal *priv;11091065 unsigned long flags;···1114106811151069 priv = iscsi_if_transport_lookup(tt);11161070 if (priv)11171117- return -EEXIST;10711071+ return NULL;1118107211191073 priv = kmalloc(sizeof(*priv), GFP_KERNEL);11201074 if (!priv)11211121- return -ENOMEM;10751075+ return NULL;11221076 memset(priv, 0, sizeof(*priv));11231077 INIT_LIST_HEAD(&priv->list);11241078 INIT_LIST_HEAD(&priv->sessions);11251125- spin_lock_init(&priv->session_lock);11261079 priv->iscsi_transport = tt;1127108011281081 priv->cdev.class = &iscsi_transport_class;···11871142 spin_unlock_irqrestore(&iscsi_transport_lock, flags);1188114311891144 printk(KERN_NOTICE "iscsi: registered transport (%s)\n", tt->name);11901190- return 0;11451145+ return &priv->t;1191114611921147unregister_cdev:11931148 class_device_unregister(&priv->cdev);11941149free_priv:11951150 kfree(priv);11961196- return err;11511151+ return NULL;11971152}11981153EXPORT_SYMBOL_GPL(iscsi_register_transport);11991154···1204115912051160 BUG_ON(!tt);1206116112071207- down(&rx_queue_sema);11621162+ mutex_lock(&rx_queue_mutex);1208116312091164 priv = iscsi_if_transport_lookup(tt);12101165 BUG_ON (!priv);12111211-12121212- spin_lock_irqsave(&priv->session_lock, flags);12131213- if (!list_empty(&priv->sessions)) {12141214- spin_unlock_irqrestore(&priv->session_lock, flags);12151215- up(&rx_queue_sema);12161216- return -EPERM;12171217- }12181218- spin_unlock_irqrestore(&priv->session_lock, flags);1219116612201167 spin_lock_irqsave(&iscsi_transport_lock, flags);12211168 list_del(&priv->list);···1218118112191182 sysfs_remove_group(&priv->cdev.kobj, &iscsi_transport_group);12201183 class_device_unregister(&priv->cdev);12211221- up(&rx_queue_sema);11841184+ mutex_unlock(&rx_queue_mutex);1222118512231186 return 0;12241187}···1231119412321195 if (event == NETLINK_URELEASE &&12331196 n->protocol == NETLINK_ISCSI && n->pid) {12341234- struct iscsi_if_conn *conn;11971197+ struct iscsi_cls_conn *conn;12351198 unsigned long flags;1236119912371237- mempool_zone_complete(&z_reply);12001200+ mempool_zone_complete(z_reply);12381201 spin_lock_irqsave(&connlock, flags);12391202 list_for_each_entry(conn, &connlist, conn_list) {12401240- mempool_zone_complete(&conn->z_error);12411241- mempool_zone_complete(&conn->z_pdu);12031203+ mempool_zone_complete(conn->z_error);12041204+ mempool_zone_complete(conn->z_pdu);12421205 }12431206 spin_unlock_irqrestore(&connlock, flags);12441207 }···12711234 goto unregister_session_class;1272123512731236 nls = netlink_kernel_create(NETLINK_ISCSI, 1, iscsi_if_rx,12741274- THIS_MODULE);12371237+ THIS_MODULE);12751238 if (!nls) {12761239 err = -ENOBUFS;12771240 goto unregister_notifier;12781241 }1279124212801280- err = mempool_zone_init(&z_reply, Z_MAX_REPLY,12431243+ z_reply = mempool_zone_init(Z_MAX_REPLY,12811244 NLMSG_SPACE(sizeof(struct iscsi_uevent)), Z_HIWAT_REPLY);12821282- if (!err)12451245+ if (z_reply)12831246 return 0;1284124712851248 sock_release(nls->sk_socket);···1296125912971260static void __exit iscsi_transport_exit(void)12981261{12991299- mempool_destroy(z_reply.pool);12621262+ mempool_zone_destroy(z_reply);13001263 sock_release(nls->sk_socket);13011264 netlink_unregister_notifier(&iscsi_nl_notifier);13021265 transport_class_unregister(&iscsi_connection_class);
···2424#include <linux/module.h>2525#include <linux/workqueue.h>2626#include <linux/blkdev.h>2727-#include <asm/semaphore.h>2727+#include <linux/mutex.h>2828#include <scsi/scsi.h>2929#include "scsi_priv.h"3030#include <scsi/scsi_device.h>···48484949/* Private data accessors (keep these out of the header file) */5050#define spi_dv_pending(x) (((struct spi_transport_attrs *)&(x)->starget_data)->dv_pending)5151-#define spi_dv_sem(x) (((struct spi_transport_attrs *)&(x)->starget_data)->dv_sem)5151+#define spi_dv_mutex(x) (((struct spi_transport_attrs *)&(x)->starget_data)->dv_mutex)52525353struct spi_internal {5454 struct scsi_transport_template t;···242242 spi_hold_mcs(starget) = 0;243243 spi_dv_pending(starget) = 0;244244 spi_initial_dv(starget) = 0;245245- init_MUTEX(&spi_dv_sem(starget));245245+ mutex_init(&spi_dv_mutex(starget));246246247247 return 0;248248}···915915 scsi_target_quiesce(starget);916916917917 spi_dv_pending(starget) = 1;918918- down(&spi_dv_sem(starget));918918+ mutex_lock(&spi_dv_mutex(starget));919919920920 starget_printk(KERN_INFO, starget, "Beginning Domain Validation\n");921921···923923924924 starget_printk(KERN_INFO, starget, "Ending Domain Validation\n");925925926926- up(&spi_dv_sem(starget));926926+ mutex_unlock(&spi_dv_mutex(starget));927927 spi_dv_pending(starget) = 0;928928929929 scsi_target_resume(starget);···10751075/* 0x04 */ "Parallel Protocol Request"10761076};1077107710781078-void print_nego(const unsigned char *msg, int per, int off, int width)10781078+static void print_nego(const unsigned char *msg, int per, int off, int width)10791079{10801080 if (per) {10811081 char buf[20];
+16-47
drivers/scsi/sd.c
···4949#include <linux/blkpg.h>5050#include <linux/kref.h>5151#include <linux/delay.h>5252+#include <linux/mutex.h>5253#include <asm/uaccess.h>53545455#include <scsi/scsi.h>···112111/* This semaphore is used to mediate the 0->1 reference get in the113112 * face of object destruction (i.e. we can't allow a get on an114113 * object after last put) */115115-static DECLARE_MUTEX(sd_ref_sem);114114+static DEFINE_MUTEX(sd_ref_mutex);116115117116static int sd_revalidate_disk(struct gendisk *disk);118117static void sd_rw_intr(struct scsi_cmnd * SCpnt);···194193{195194 struct scsi_disk *sdkp;196195197197- down(&sd_ref_sem);196196+ mutex_lock(&sd_ref_mutex);198197 sdkp = __scsi_disk_get(disk);199199- up(&sd_ref_sem);198198+ mutex_unlock(&sd_ref_mutex);200199 return sdkp;201200}202201···204203{205204 struct scsi_disk *sdkp;206205207207- down(&sd_ref_sem);206206+ mutex_lock(&sd_ref_mutex);208207 sdkp = dev_get_drvdata(dev);209208 if (sdkp)210209 sdkp = __scsi_disk_get(sdkp->disk);211211- up(&sd_ref_sem);210210+ mutex_unlock(&sd_ref_mutex);212211 return sdkp;213212}214213···216215{217216 struct scsi_device *sdev = sdkp->device;218217219219- down(&sd_ref_sem);218218+ mutex_lock(&sd_ref_mutex);220219 kref_put(&sdkp->kref, scsi_disk_release);221220 scsi_device_put(sdev);222222- up(&sd_ref_sem);221221+ mutex_unlock(&sd_ref_mutex);223222}224223225224/**···232231 **/233232static int sd_init_command(struct scsi_cmnd * SCpnt)234233{235235- unsigned int this_count, timeout;236236- struct gendisk *disk;237237- sector_t block;238234 struct scsi_device *sdp = SCpnt->device;239235 struct request *rq = SCpnt->request;240240-241241- timeout = sdp->timeout;242242-243243- /*244244- * SG_IO from block layer already setup, just copy cdb basically245245- */246246- if (blk_pc_request(rq)) {247247- scsi_setup_blk_pc_cmnd(SCpnt);248248- if (rq->timeout)249249- timeout = rq->timeout;250250-251251- goto queue;252252- }253253-254254- /*255255- * we only do REQ_CMD and REQ_BLOCK_PC256256- */257257- if (!blk_fs_request(rq))258258- return 0;259259-260260- disk = rq->rq_disk;261261- block = rq->sector;262262- this_count = SCpnt->request_bufflen >> 9;236236+ struct gendisk *disk = rq->rq_disk;237237+ sector_t block = rq->sector;238238+ unsigned int this_count = SCpnt->request_bufflen >> 9;239239+ unsigned int timeout = sdp->timeout;263240264241 SCSI_LOG_HLQUEUE(1, printk("sd_init_command: disk=%s, block=%llu, "265242 "count=%d\n", disk->disk_name,···380401 SCpnt->transfersize = sdp->sector_size;381402 SCpnt->underflow = this_count << 9;382403 SCpnt->allowed = SD_MAX_RETRIES;383383-384384-queue:385404 SCpnt->timeout_per_command = timeout;386405387406 /*···813836 relatively rare error condition, no care is taken to avoid814837 unnecessary additional work such as memcpy's that could be avoided.815838 */816816-817817- /* 818818- * If SG_IO from block layer then set good_bytes to stop retries;819819- * else if errors, check them, and if necessary prepare for820820- * (partial) retries.821821- */822822- if (blk_pc_request(SCpnt->request))823823- good_bytes = this_count;824824- else if (driver_byte(result) != 0 &&839839+ if (driver_byte(result) != 0 &&825840 sense_valid && !sense_deferred) {826841 switch (sshdr.sense_key) {827842 case MEDIUM_ERROR:···16041635 del_gendisk(sdkp->disk);16051636 sd_shutdown(dev);1606163716071607- down(&sd_ref_sem);16381638+ mutex_lock(&sd_ref_mutex);16081639 dev_set_drvdata(dev, NULL);16091640 kref_put(&sdkp->kref, scsi_disk_release);16101610- up(&sd_ref_sem);16411641+ mutex_unlock(&sd_ref_mutex);1611164216121643 return 0;16131644}···16161647 * scsi_disk_release - Called to free the scsi_disk structure16171648 * @kref: pointer to embedded kref16181649 *16191619- * sd_ref_sem must be held entering this routine. Because it is16501650+ * sd_ref_mutex must be held entering this routine. Because it is16201651 * called on last put, you should always use the scsi_disk_get()16211652 * scsi_disk_put() helpers which manipulate the semaphore directly16221653 * and never do a direct kref_put().
+12-31
drivers/scsi/sr.c
···4444#include <linux/interrupt.h>4545#include <linux/init.h>4646#include <linux/blkdev.h>4747+#include <linux/mutex.h>4748#include <asm/uaccess.h>48494950#include <scsi/scsi.h>···9190/* This semaphore is used to mediate the 0->1 reference get in the9291 * face of object destruction (i.e. we can't allow a get on an9392 * object after last put) */9494-static DECLARE_MUTEX(sr_ref_sem);9393+static DEFINE_MUTEX(sr_ref_mutex);95949695static int sr_open(struct cdrom_device_info *, int);9796static void sr_release(struct cdrom_device_info *);···134133{135134 struct scsi_cd *cd = NULL;136135137137- down(&sr_ref_sem);136136+ mutex_lock(&sr_ref_mutex);138137 if (disk->private_data == NULL)139138 goto out;140139 cd = scsi_cd(disk);···147146 kref_put(&cd->kref, sr_kref_release);148147 cd = NULL;149148 out:150150- up(&sr_ref_sem);149149+ mutex_unlock(&sr_ref_mutex);151150 return cd;152151}153152···155154{156155 struct scsi_device *sdev = cd->device;157156158158- down(&sr_ref_sem);157157+ mutex_lock(&sr_ref_mutex);159158 kref_put(&cd->kref, sr_kref_release);160159 scsi_device_put(sdev);161161- up(&sr_ref_sem);160160+ mutex_unlock(&sr_ref_mutex);162161}163162164163/*···238237 case ILLEGAL_REQUEST:239238 if (!(SCpnt->sense_buffer[0] & 0x90))240239 break;241241- if (!blk_fs_request(SCpnt->request))242242- break;243240 error_sector = (SCpnt->sense_buffer[3] << 24) |244241 (SCpnt->sense_buffer[4] << 16) |245242 (SCpnt->sense_buffer[5] << 8) |···312313 * quietly refuse to do anything to a changed disc until the313314 * changed bit has been reset314315 */315315- return 0;316316- }317317-318318- /*319319- * these are already setup, just copy cdb basically320320- */321321- if (SCpnt->request->flags & REQ_BLOCK_PC) {322322- scsi_setup_blk_pc_cmnd(SCpnt);323323-324324- if (SCpnt->timeout_per_command)325325- timeout = SCpnt->timeout_per_command;326326-327327- goto queue;328328- }329329-330330- if (!(SCpnt->request->flags & REQ_CMD)) {331331- blk_dump_rq_flags(SCpnt->request, "sr unsup command");332316 return 0;333317 }334318···403421 */404422 SCpnt->transfersize = cd->device->sector_size;405423 SCpnt->underflow = this_count << 9;406406-407407-queue:408424 SCpnt->allowed = MAX_RETRIES;409425 SCpnt->timeout_per_command = timeout;410426···742762 /* failed, drive doesn't have capabilities mode page */743763 cd->cdi.speed = 1;744764 cd->cdi.mask |= (CDC_CD_R | CDC_CD_RW | CDC_DVD_R |745745- CDC_DVD | CDC_DVD_RAM |746746- CDC_SELECT_DISC | CDC_SELECT_SPEED);765765+ CDC_DVD | CDC_DVD_RAM |766766+ CDC_SELECT_DISC | CDC_SELECT_SPEED |767767+ CDC_MRW | CDC_MRW_W | CDC_RAM);747768 kfree(buffer);748769 printk("%s: scsi-1 drive\n", cd->cdi.name);749770 return;···826845 * sr_kref_release - Called to free the scsi_cd structure827846 * @kref: pointer to embedded kref828847 *829829- * sr_ref_sem must be held entering this routine. Because it is848848+ * sr_ref_mutex must be held entering this routine. Because it is830849 * called on last put, you should always use the scsi_cd_get()831850 * scsi_cd_put() helpers which manipulate the semaphore directly832851 * and never do a direct kref_put().···855874856875 del_gendisk(cd->disk);857876858858- down(&sr_ref_sem);877877+ mutex_lock(&sr_ref_mutex);859878 kref_put(&cd->kref, sr_kref_release);860860- up(&sr_ref_sem);879879+ mutex_unlock(&sr_ref_mutex);861880862881 return 0;863882}
+111-91
drivers/scsi/sr_ioctl.c
···31313232module_param(xa_test, int, S_IRUGO | S_IWUSR);33333434+/* primitive to determine whether we need to have GFP_DMA set based on3535+ * the status of the unchecked_isa_dma flag in the host structure */3636+#define SR_GFP_DMA(cd) (((cd)->device->host->unchecked_isa_dma) ? GFP_DMA : 0)3737+3838+3939+static int sr_read_tochdr(struct cdrom_device_info *cdi,4040+ struct cdrom_tochdr *tochdr)4141+{4242+ struct scsi_cd *cd = cdi->handle;4343+ struct packet_command cgc;4444+ int result;4545+ unsigned char *buffer;4646+4747+ buffer = kmalloc(32, GFP_KERNEL | SR_GFP_DMA(cd));4848+ if (!buffer)4949+ return -ENOMEM;5050+5151+ memset(&cgc, 0, sizeof(struct packet_command));5252+ cgc.timeout = IOCTL_TIMEOUT;5353+ cgc.cmd[0] = GPCMD_READ_TOC_PMA_ATIP;5454+ cgc.cmd[8] = 12; /* LSB of length */5555+ cgc.buffer = buffer;5656+ cgc.buflen = 12;5757+ cgc.quiet = 1;5858+ cgc.data_direction = DMA_FROM_DEVICE;5959+6060+ result = sr_do_ioctl(cd, &cgc);6161+6262+ tochdr->cdth_trk0 = buffer[2];6363+ tochdr->cdth_trk1 = buffer[3];6464+6565+ kfree(buffer);6666+ return result;6767+}6868+6969+static int sr_read_tocentry(struct cdrom_device_info *cdi,7070+ struct cdrom_tocentry *tocentry)7171+{7272+ struct scsi_cd *cd = cdi->handle;7373+ struct packet_command cgc;7474+ int result;7575+ unsigned char *buffer;7676+7777+ buffer = kmalloc(32, GFP_KERNEL | SR_GFP_DMA(cd));7878+ if (!buffer)7979+ return -ENOMEM;8080+8181+ memset(&cgc, 0, sizeof(struct packet_command));8282+ cgc.timeout = IOCTL_TIMEOUT;8383+ cgc.cmd[0] = GPCMD_READ_TOC_PMA_ATIP;8484+ cgc.cmd[1] |= (tocentry->cdte_format == CDROM_MSF) ? 0x02 : 0;8585+ cgc.cmd[6] = tocentry->cdte_track;8686+ cgc.cmd[8] = 12; /* LSB of length */8787+ cgc.buffer = buffer;8888+ cgc.buflen = 12;8989+ cgc.data_direction = DMA_FROM_DEVICE;9090+9191+ result = sr_do_ioctl(cd, &cgc);9292+9393+ tocentry->cdte_ctrl = buffer[5] & 0xf;9494+ tocentry->cdte_adr = buffer[5] >> 4;9595+ tocentry->cdte_datamode = (tocentry->cdte_ctrl & 0x04) ? 1 : 0;9696+ if (tocentry->cdte_format == CDROM_MSF) {9797+ tocentry->cdte_addr.msf.minute = buffer[9];9898+ tocentry->cdte_addr.msf.second = buffer[10];9999+ tocentry->cdte_addr.msf.frame = buffer[11];100100+ } else101101+ tocentry->cdte_addr.lba = (((((buffer[8] << 8) + buffer[9]) << 8)102102+ + buffer[10]) << 8) + buffer[11];103103+104104+ kfree(buffer);105105+ return result;106106+}3410735108#define IOCTL_RETRIES 336109···11845 struct packet_command cgc;11946 int ntracks, ret;12047121121- if ((ret = sr_audio_ioctl(cdi, CDROMREADTOCHDR, &tochdr)))4848+ ret = sr_read_tochdr(cdi, &tochdr);4949+ if (ret)12250 return ret;1235112452 ntracks = tochdr.cdth_trk1 - tochdr.cdth_trk0 + 1;···13460 trk1_te.cdte_track = ti->cdti_trk1;13561 trk1_te.cdte_format = CDROM_MSF;13662137137- if ((ret = sr_audio_ioctl(cdi, CDROMREADTOCENTRY, &trk0_te)))6363+ ret = sr_read_tocentry(cdi, &trk0_te);6464+ if (ret)13865 return ret;139139- if ((ret = sr_audio_ioctl(cdi, CDROMREADTOCENTRY, &trk1_te)))6666+ ret = sr_read_tocentry(cdi, &trk1_te);6767+ if (ret)14068 return ret;1416914270 memset(&cgc, 0, sizeof(struct packet_command));···15276 cgc.data_direction = DMA_NONE;15377 cgc.timeout = IOCTL_TIMEOUT;15478 return sr_do_ioctl(cdi->handle, &cgc);7979+}8080+8181+static int sr_play_trkind(struct cdrom_device_info *cdi,8282+ struct cdrom_ti *ti)8383+8484+{8585+ struct scsi_cd *cd = cdi->handle;8686+ struct packet_command cgc;8787+ int result;8888+8989+ memset(&cgc, 0, sizeof(struct packet_command));9090+ cgc.timeout = IOCTL_TIMEOUT;9191+ cgc.cmd[0] = GPCMD_PLAYAUDIO_TI;9292+ cgc.cmd[4] = ti->cdti_trk0;9393+ cgc.cmd[5] = ti->cdti_ind0;9494+ cgc.cmd[7] = ti->cdti_trk1;9595+ cgc.cmd[8] = ti->cdti_ind1;9696+ cgc.data_direction = DMA_NONE;9797+9898+ result = sr_do_ioctl(cd, &cgc);9999+ if (result == -EDRIVE_CANT_DO_THIS)100100+ result = sr_fake_playtrkind(cdi, ti);101101+102102+ return result;155103}156104157105/* We do our own retries because we want to know what the specific···329229 int i, rc, have_datatracks = 0;330230331231 /* look for data tracks */332332- if (0 != (rc = sr_audio_ioctl(cdi, CDROMREADTOCHDR, &toc_h)))232232+ rc = sr_read_tochdr(cdi, &toc_h);233233+ if (rc)333234 return (rc == -ENOMEDIUM) ? CDS_NO_DISC : CDS_NO_INFO;334235335236 for (i = toc_h.cdth_trk0; i <= toc_h.cdth_trk1; i++) {336237 toc_e.cdte_track = i;337238 toc_e.cdte_format = CDROM_LBA;338338- if (sr_audio_ioctl(cdi, CDROMREADTOCENTRY, &toc_e))239239+ if (sr_read_tocentry(cdi, &toc_e))339240 return CDS_NO_INFO;340241 if (toc_e.cdte_ctrl & CDROM_DATA_TRACK) {341242 have_datatracks = 1;···362261363262 return 0;364263}365365-366366-/* primitive to determine whether we need to have GFP_DMA set based on367367- * the status of the unchecked_isa_dma flag in the host structure */368368-#define SR_GFP_DMA(cd) (((cd)->device->host->unchecked_isa_dma) ? GFP_DMA : 0)369264370265int sr_get_mcn(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn)371266{···426329427330int sr_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd, void *arg)428331{429429- Scsi_CD *cd = cdi->handle;430430- struct packet_command cgc;431431- int result;432432- unsigned char *buffer = kmalloc(32, GFP_KERNEL | SR_GFP_DMA(cd));433433-434434- if (!buffer)435435- return -ENOMEM;436436-437437- memset(&cgc, 0, sizeof(struct packet_command));438438- cgc.timeout = IOCTL_TIMEOUT;439439-440332 switch (cmd) {441333 case CDROMREADTOCHDR:442442- {443443- struct cdrom_tochdr *tochdr = (struct cdrom_tochdr *) arg;444444-445445- cgc.cmd[0] = GPCMD_READ_TOC_PMA_ATIP;446446- cgc.cmd[8] = 12; /* LSB of length */447447- cgc.buffer = buffer;448448- cgc.buflen = 12;449449- cgc.quiet = 1;450450- cgc.data_direction = DMA_FROM_DEVICE;451451-452452- result = sr_do_ioctl(cd, &cgc);453453-454454- tochdr->cdth_trk0 = buffer[2];455455- tochdr->cdth_trk1 = buffer[3];456456-457457- break;458458- }459459-334334+ return sr_read_tochdr(cdi, arg);460335 case CDROMREADTOCENTRY:461461- {462462- struct cdrom_tocentry *tocentry = (struct cdrom_tocentry *) arg;463463-464464- cgc.cmd[0] = GPCMD_READ_TOC_PMA_ATIP;465465- cgc.cmd[1] |= (tocentry->cdte_format == CDROM_MSF) ? 0x02 : 0;466466- cgc.cmd[6] = tocentry->cdte_track;467467- cgc.cmd[8] = 12; /* LSB of length */468468- cgc.buffer = buffer;469469- cgc.buflen = 12;470470- cgc.data_direction = DMA_FROM_DEVICE;471471-472472- result = sr_do_ioctl(cd, &cgc);473473-474474- tocentry->cdte_ctrl = buffer[5] & 0xf;475475- tocentry->cdte_adr = buffer[5] >> 4;476476- tocentry->cdte_datamode = (tocentry->cdte_ctrl & 0x04) ? 1 : 0;477477- if (tocentry->cdte_format == CDROM_MSF) {478478- tocentry->cdte_addr.msf.minute = buffer[9];479479- tocentry->cdte_addr.msf.second = buffer[10];480480- tocentry->cdte_addr.msf.frame = buffer[11];481481- } else482482- tocentry->cdte_addr.lba = (((((buffer[8] << 8) + buffer[9]) << 8)483483- + buffer[10]) << 8) + buffer[11];484484-485485- break;486486- }487487-488488- case CDROMPLAYTRKIND: {489489- struct cdrom_ti* ti = (struct cdrom_ti*)arg;490490-491491- cgc.cmd[0] = GPCMD_PLAYAUDIO_TI;492492- cgc.cmd[4] = ti->cdti_trk0;493493- cgc.cmd[5] = ti->cdti_ind0;494494- cgc.cmd[7] = ti->cdti_trk1;495495- cgc.cmd[8] = ti->cdti_ind1;496496- cgc.data_direction = DMA_NONE;497497-498498- result = sr_do_ioctl(cd, &cgc);499499- if (result == -EDRIVE_CANT_DO_THIS)500500- result = sr_fake_playtrkind(cdi, ti);501501-502502- break;503503- }504504-336336+ return sr_read_tocentry(cdi, arg);337337+ case CDROMPLAYTRKIND:338338+ return sr_play_trkind(cdi, arg);505339 default:506506- result = -EINVAL;340340+ return -EINVAL;507341 }508508-509509-#if 0510510- if (result)511511- printk("DEBUG: sr_audio: result for ioctl %x: %x\n", cmd, result);512512-#endif513513-514514- kfree(buffer);515515- return result;516342}517343518344/* -----------------------------------------------------------------------
+9-33
drivers/scsi/st.c
···3838#include <linux/devfs_fs_kernel.h>3939#include <linux/cdev.h>4040#include <linux/delay.h>4141+#include <linux/mutex.h>41424243#include <asm/uaccess.h>4344#include <asm/dma.h>···194193195194static int st_probe(struct device *);196195static int st_remove(struct device *);197197-static int st_init_command(struct scsi_cmnd *);198196199197static void do_create_driverfs_files(void);200198static void do_remove_driverfs_files(void);···206206 .probe = st_probe,207207 .remove = st_remove,208208 },209209- .init_command = st_init_command,210209};211210212211static int st_compression(struct scsi_tape *, int);···219220220221#define to_scsi_tape(obj) container_of(obj, struct scsi_tape, kref)221222222222-static DECLARE_MUTEX(st_ref_sem);223223+static DEFINE_MUTEX(st_ref_mutex);223224224225225226#include "osst_detect.h"···236237{237238 struct scsi_tape *STp = NULL;238239239239- down(&st_ref_sem);240240+ mutex_lock(&st_ref_mutex);240241 write_lock(&st_dev_arr_lock);241242242243 if (dev < st_dev_max && scsi_tapes != NULL)···258259 STp = NULL;259260out:260261 write_unlock(&st_dev_arr_lock);261261- up(&st_ref_sem);262262+ mutex_unlock(&st_ref_mutex);262263 return STp;263264}264265···266267{267268 struct scsi_device *sdev = STp->device;268269269269- down(&st_ref_sem);270270+ mutex_lock(&st_ref_mutex);270271 kref_put(&STp->kref, scsi_tape_release);271272 scsi_device_put(sdev);272272- up(&st_ref_sem);273273+ mutex_unlock(&st_ref_mutex);273274}274275275276struct st_reject_data {···41404141 }41414142 }4142414341434143- down(&st_ref_sem);41444144+ mutex_lock(&st_ref_mutex);41444145 kref_put(&tpnt->kref, scsi_tape_release);41454145- up(&st_ref_sem);41464146+ mutex_unlock(&st_ref_mutex);41464147 return 0;41474148 }41484149 }···41554156 * scsi_tape_release - Called to free the Scsi_Tape structure41564157 * @kref: pointer to embedded kref41574158 *41584158- * st_ref_sem must be held entering this routine. Because it is41594159+ * st_ref_mutex must be held entering this routine. Because it is41594160 * called on last put, you should always use the scsi_tape_get()41604161 * scsi_tape_put() helpers which manipulate the semaphore directly41614162 * and never do a direct kref_put().···41774178 put_disk(disk);41784179 kfree(tpnt);41794180 return;41804180-}41814181-41824182-static void st_intr(struct scsi_cmnd *SCpnt)41834183-{41844184- /*41854185- * The caller should be checking the request's errors41864186- * value.41874187- */41884188- scsi_io_completion(SCpnt, SCpnt->bufflen, 0);41894189-}41904190-41914191-/*41924192- * st_init_command: only called via the scsi_cmd_ioctl (block SG_IO)41934193- * interface for REQ_BLOCK_PC commands.41944194- */41954195-static int st_init_command(struct scsi_cmnd *SCpnt)41964196-{41974197- if (!(SCpnt->request->flags & REQ_BLOCK_PC))41984198- return 0;41994199-42004200- scsi_setup_blk_pc_cmnd(SCpnt);42014201- SCpnt->done = st_intr;42024202- return 1;42034181}4204418242054183static int __init init_st(void)
···168168169169#define iscsi_ptr(_handle) ((void*)(unsigned long)_handle)170170#define iscsi_handle(_ptr) ((uint64_t)(unsigned long)_ptr)171171+#define hostdata_session(_hostdata) (iscsi_ptr(*(unsigned long *)_hostdata))172172+173173+/**174174+ * iscsi_hostdata - get LLD hostdata from scsi_host175175+ * @_hostdata: pointer to scsi host's hostdata176176+ **/171177#define iscsi_hostdata(_hostdata) ((void*)_hostdata + sizeof(unsigned long))172178173179/*
+6
include/scsi/scsi.h
···3232extern const char *const scsi_device_types[MAX_SCSI_DEVICE_CODE];33333434/*3535+ * Special value for scanning to specify scanning or rescanning of all3636+ * possible channels, (target) ids, or luns on a given shost.3737+ */3838+#define SCAN_WILD_CARD ~03939+4040+/*3541 * SCSI opcodes3642 */3743
···3030 struct transport_container device_attrs;31313232 /*3333- * If set, call target_parent prior to allocating a scsi_target,3434- * so we get the appropriate parent for the target. This function3535- * is required for transports like FC and iSCSI that do not put the3636- * scsi_target under scsi_host.3333+ * If set, called from sysfs and legacy procfs rescanning code.3734 */3838- struct device *(*target_parent)(struct Scsi_Host *, int, uint);3535+ int (*user_scan)(struct Scsi_Host *, uint, uint, uint);39364037 /* The size of the specific transport attribute structure (a4138 * space of this size will be left at the end of the
+4
include/scsi/scsi_transport_fc.h
···303303 /* Fixed Attributes */304304 u64 node_name;305305 u64 port_name;306306+ u64 permanent_port_name;306307 u32 supported_classes;307308 u8 supported_fc4s[FC_FC4_LIST_SIZE];308309 char symbolic_name[FC_SYMBOLIC_NAME_SIZE];···339338 (((struct fc_host_attrs *)(x)->shost_data)->node_name)340339#define fc_host_port_name(x) \341340 (((struct fc_host_attrs *)(x)->shost_data)->port_name)341341+#define fc_host_permanent_port_name(x) \342342+ (((struct fc_host_attrs *)(x)->shost_data)->permanent_port_name)342343#define fc_host_supported_classes(x) \343344 (((struct fc_host_attrs *)(x)->shost_data)->supported_classes)344345#define fc_host_supported_fc4s(x) \···429426 /* host fixed attributes */430427 unsigned long show_host_node_name:1;431428 unsigned long show_host_port_name:1;429429+ unsigned long show_host_permanent_port_name:1;432430 unsigned long show_host_supported_classes:1;433431 unsigned long show_host_supported_fc4s:1;434432 unsigned long show_host_symbolic_name:1;
+67-8
include/scsi/scsi_transport_iscsi.h
···2323#ifndef SCSI_TRANSPORT_ISCSI_H2424#define SCSI_TRANSPORT_ISCSI_H25252626+#include <linux/device.h>2627#include <scsi/iscsi_if.h>2828+2929+struct scsi_transport_template;3030+struct Scsi_Host;3131+struct mempool_zone;3232+struct iscsi_cls_conn;27332834/**2935 * struct iscsi_transport - iSCSI Transport template···5448 char *name;5549 unsigned int caps;5650 struct scsi_host_template *host_template;5151+ /* LLD session/scsi_host data size */5752 int hostdata_size;5353+ /* LLD iscsi_host data size */5454+ int ihostdata_size;5555+ /* LLD connection data size */5656+ int conndata_size;5857 int max_lun;5958 unsigned int max_conn;6059 unsigned int max_cmd_len;6161- iscsi_sessionh_t (*create_session) (uint32_t initial_cmdsn,6262- struct Scsi_Host *shost);6363- void (*destroy_session) (iscsi_sessionh_t session);6464- iscsi_connh_t (*create_conn) (iscsi_sessionh_t session, uint32_t cid);6060+ struct Scsi_Host *(*create_session) (struct scsi_transport_template *t,6161+ uint32_t initial_cmdsn);6262+ void (*destroy_session) (struct Scsi_Host *shost);6363+ struct iscsi_cls_conn *(*create_conn) (struct Scsi_Host *shost,6464+ uint32_t cid);6565 int (*bind_conn) (iscsi_sessionh_t session, iscsi_connh_t conn,6666 uint32_t transport_fd, int is_leading);6767 int (*start_conn) (iscsi_connh_t conn);6868 void (*stop_conn) (iscsi_connh_t conn, int flag);6969- void (*destroy_conn) (iscsi_connh_t conn);6969+ void (*destroy_conn) (struct iscsi_cls_conn *conn);7070 int (*set_param) (iscsi_connh_t conn, enum iscsi_param param,7171 uint32_t value);7272- int (*get_param) (iscsi_connh_t conn, enum iscsi_param param,7373- uint32_t *value);7272+ int (*get_conn_param) (void *conndata, enum iscsi_param param,7373+ uint32_t *value);7474+ int (*get_session_param) (struct Scsi_Host *shost,7575+ enum iscsi_param param, uint32_t *value);7476 int (*send_pdu) (iscsi_connh_t conn, struct iscsi_hdr *hdr,7577 char *data, uint32_t data_size);7678 void (*get_stats) (iscsi_connh_t conn, struct iscsi_stats *stats);···8773/*8874 * transport registration upcalls8975 */9090-extern int iscsi_register_transport(struct iscsi_transport *tt);7676+extern struct scsi_transport_template *iscsi_register_transport(struct iscsi_transport *tt);9177extern int iscsi_unregister_transport(struct iscsi_transport *tt);92789379/*···9682extern void iscsi_conn_error(iscsi_connh_t conn, enum iscsi_err error);9783extern int iscsi_recv_pdu(iscsi_connh_t conn, struct iscsi_hdr *hdr,9884 char *data, uint32_t data_size);8585+8686+struct iscsi_cls_conn {8787+ struct list_head conn_list; /* item in connlist */8888+ void *dd_data; /* LLD private data */8989+ struct iscsi_transport *transport;9090+ iscsi_connh_t connh;9191+ int active; /* must be accessed with the connlock */9292+ struct device dev; /* sysfs transport/container device */9393+ struct mempool_zone *z_error;9494+ struct mempool_zone *z_pdu;9595+ struct list_head freequeue;9696+};9797+9898+#define iscsi_dev_to_conn(_dev) \9999+ container_of(_dev, struct iscsi_cls_conn, dev)100100+101101+struct iscsi_cls_session {102102+ struct list_head list; /* item in session_list */103103+ struct iscsi_transport *transport;104104+ struct device dev; /* sysfs transport/container device */105105+};106106+107107+#define iscsi_dev_to_session(_dev) \108108+ container_of(_dev, struct iscsi_cls_session, dev)109109+110110+#define iscsi_session_to_shost(_session) \111111+ dev_to_shost(_session->dev.parent)112112+113113+/*114114+ * session and connection functions that can be used by HW iSCSI LLDs115115+ */116116+extern struct iscsi_cls_session *iscsi_create_session(struct Scsi_Host *shost,117117+ struct iscsi_transport *t);118118+extern int iscsi_destroy_session(struct iscsi_cls_session *session);119119+extern struct iscsi_cls_conn *iscsi_create_conn(struct iscsi_cls_session *sess,120120+ uint32_t cid);121121+extern int iscsi_destroy_conn(struct iscsi_cls_conn *conn);122122+123123+/*124124+ * session functions used by software iscsi125125+ */126126+extern struct Scsi_Host *127127+iscsi_transport_create_session(struct scsi_transport_template *scsit,128128+ struct iscsi_transport *transport);129129+extern int iscsi_transport_destroy_session(struct Scsi_Host *shost);99130100131#endif
+1-1
include/scsi/scsi_transport_spi.h
···5454 unsigned int support_qas; /* supports quick arbitration and selection */5555 /* Private Fields */5656 unsigned int dv_pending:1; /* Internal flag */5757- struct semaphore dv_sem; /* semaphore to serialise dv */5757+ struct mutex dv_mutex; /* semaphore to serialise dv */5858};59596060enum spi_signal_type {