#define ORB_SET_DIRECTION(value) ((value & 0x1) << 27)
struct sbp2_command_orb {
- volatile u32 next_ORB_hi;
- volatile u32 next_ORB_lo;
+ u32 next_ORB_hi;
+ u32 next_ORB_lo;
u32 data_descriptor_hi;
u32 data_descriptor_lo;
u32 misc;
u8 cdb[12];
-};
+} __attribute__((packed));
#define SBP2_LOGIN_REQUEST 0x0
#define SBP2_QUERY_LOGINS_REQUEST 0x1
u32 passwd_resp_lengths;
u32 status_fifo_hi;
u32 status_fifo_lo;
-};
+} __attribute__((packed));
#define RESPONSE_GET_LOGIN_ID(value) (value & 0xffff)
#define RESPONSE_GET_LENGTH(value) ((value >> 16) & 0xffff)
u32 command_block_agent_hi;
u32 command_block_agent_lo;
u32 reconnect_hold;
-};
+} __attribute__((packed));
#define ORB_SET_LOGIN_ID(value) (value & 0xffff)
u32 reserved_resp_length;
u32 status_fifo_hi;
u32 status_fifo_lo;
-};
+} __attribute__((packed));
#define RESPONSE_GET_MAX_LOGINS(value) (value & 0xffff)
#define RESPONSE_GET_ACTIVE_LOGINS(value) ((RESPONSE_GET_LENGTH(value) - 4) / 12)
u32 misc_IDs;
u32 initiator_misc_hi;
u32 initiator_misc_lo;
-};
+} __attribute__((packed));
struct sbp2_reconnect_orb {
u32 reserved1;
u32 reserved5;
u32 status_fifo_hi;
u32 status_fifo_lo;
-};
+} __attribute__((packed));
struct sbp2_logout_orb {
u32 reserved1;
u32 reserved5;
u32 status_fifo_hi;
u32 status_fifo_lo;
-};
+} __attribute__((packed));
#define PAGE_TABLE_SET_SEGMENT_BASE_HI(value) (value & 0xffff)
#define PAGE_TABLE_SET_SEGMENT_LENGTH(value) ((value & 0xffff) << 16)
struct sbp2_unrestricted_page_table {
u32 length_segment_base_hi;
u32 segment_base_lo;
-};
+} __attribute__((packed));
#define RESP_STATUS_REQUEST_COMPLETE 0x0
#define RESP_STATUS_TRANSPORT_FAILURE 0x1
#define SBP2_SCSI_STATUS_SELECTION_TIMEOUT 0xff
-#define STATUS_GET_ORB_OFFSET_HI(value) (value & 0xffff)
-#define STATUS_GET_SBP_STATUS(value) ((value >> 16) & 0xff)
-#define STATUS_GET_LENGTH(value) ((value >> 24) & 0x7)
-#define STATUS_GET_DEAD_BIT(value) ((value >> 27) & 0x1)
-#define STATUS_GET_RESP(value) ((value >> 28) & 0x3)
-#define STATUS_GET_SRC(value) ((value >> 30) & 0x3)
+#define STATUS_GET_SRC(value) (((value) >> 30) & 0x3)
+#define STATUS_GET_RESP(value) (((value) >> 28) & 0x3)
+#define STATUS_GET_LEN(value) (((value) >> 24) & 0x7)
+#define STATUS_GET_SBP_STATUS(value) (((value) >> 16) & 0xff)
+#define STATUS_GET_ORB_OFFSET_HI(value) ((value) & 0x0000ffff)
+#define STATUS_TEST_DEAD(value) ((value) & 0x08000000)
+/* test 'resp' | 'dead' | 'sbp2_status' */
+#define STATUS_TEST_RDS(value) ((value) & 0x38ff0000)
struct sbp2_status_block {
u32 ORB_offset_hi_misc;
u32 ORB_offset_lo;
u8 command_set_dependent[24];
-};
+} __attribute__((packed));
/*
* Miscellaneous SBP2 related config rom defines
u64 status_fifo_addr;
/*
- * Variable used for logins, reconnects, logouts, query logins
+ * Waitqueue flag for logins, reconnects, logouts, query logins
*/
- atomic_t sbp2_login_complete;
+ int access_complete:1;
/*
* Pool of command orbs, so we can have more than overlapped command per id
/* Device specific workarounds/brokeness */
unsigned workarounds;
+
+ atomic_t state;
+ struct delayed_work protocol_work;
+};
+
+/* For use in scsi_id_instance_data.state */
+enum sbp2lu_state_types {
+ SBP2LU_STATE_RUNNING, /* all normal */
+ SBP2LU_STATE_IN_RESET, /* between bus reset and reconnect */
+ SBP2LU_STATE_IN_SHUTDOWN /* when sbp2_remove was called */
};
/* Sbp2 host data structure (one per IEEE1394 host) */
static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, int destid,
quadlet_t *data, u64 addr, size_t length, u16 flags);
static int sbp2_agent_reset(struct scsi_id_instance_data *scsi_id, int wait);
-static int sbp2_link_orb_command(struct scsi_id_instance_data *scsi_id,
- struct sbp2_command_info *command);
-static int sbp2_send_command(struct scsi_id_instance_data *scsi_id,
- struct scsi_cmnd *SCpnt,
- void (*done)(struct scsi_cmnd *));
-static unsigned int sbp2_status_to_sense_data(unchar *sbp2_status, unchar *sense_data);
-static void sbp2_check_sbp2_response(struct scsi_id_instance_data *scsi_id,
- struct scsi_cmnd *SCpnt);
+static unsigned int sbp2_status_to_sense_data(unchar *sbp2_status,
+ unchar *sense_data);
static void sbp2_parse_unit_directory(struct scsi_id_instance_data *scsi_id,
struct unit_directory *ud);
static int sbp2_set_busy_timeout(struct scsi_id_instance_data *scsi_id);