2005-04-17 02:20:36 +04:00
/*
* sbp2 . h - Defines and prototypes for sbp2 . c
*
* Copyright ( C ) 2000 James Goodwin , Filanet Corporation ( www . filanet . com )
* jamesg @ filanet . com
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 2 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software Foundation ,
* Inc . , 59 Temple Place - Suite 330 , Boston , MA 02111 - 1307 , USA .
*/
# ifndef SBP2_H
# define SBP2_H
# define SBP2_DEVICE_NAME "sbp2"
2009-06-30 22:28:31 +04:00
/*
* There is no transport protocol limit to the CDB length , but we implement
* a fixed length only . 16 bytes is enough for disks larger than 2 TB .
*/
# define SBP2_MAX_CDB_SIZE 16
2005-04-17 02:20:36 +04:00
/*
2006-11-02 23:16:08 +03:00
* SBP - 2 specific definitions
2005-04-17 02:20:36 +04:00
*/
2006-11-02 23:16:08 +03:00
# define ORB_DIRECTION_WRITE_TO_MEDIA 0x0
# define ORB_DIRECTION_READ_FROM_MEDIA 0x1
# define ORB_DIRECTION_NO_DATA_TRANSFER 0x2
# define ORB_SET_NULL_PTR(v) (((v) & 0x1) << 31)
# define ORB_SET_NOTIFY(v) (((v) & 0x1) << 31)
# define ORB_SET_RQ_FMT(v) (((v) & 0x3) << 29)
# define ORB_SET_NODE_ID(v) (((v) & 0xffff) << 16)
# define ORB_SET_STATUS_FIFO_HI(v, id) ((v) >> 32 | ORB_SET_NODE_ID(id))
# define ORB_SET_STATUS_FIFO_LO(v) ((v) & 0xffffffff)
# define ORB_SET_DATA_SIZE(v) ((v) & 0xffff)
# define ORB_SET_PAGE_SIZE(v) (((v) & 0x7) << 16)
# define ORB_SET_PAGE_TABLE_PRESENT(v) (((v) & 0x1) << 19)
# define ORB_SET_MAX_PAYLOAD(v) (((v) & 0xf) << 20)
# define ORB_SET_SPEED(v) (((v) & 0x7) << 24)
# define ORB_SET_DIRECTION(v) (((v) & 0x1) << 27)
2005-04-17 02:20:36 +04:00
struct sbp2_command_orb {
2006-07-24 00:12:00 +04:00
u32 next_ORB_hi ;
u32 next_ORB_lo ;
2005-04-17 02:20:36 +04:00
u32 data_descriptor_hi ;
u32 data_descriptor_lo ;
u32 misc ;
2009-06-30 22:28:31 +04:00
u8 cdb [ SBP2_MAX_CDB_SIZE ] ;
2006-06-13 02:14:47 +04:00
} __attribute__ ( ( packed ) ) ;
2005-04-17 02:20:36 +04:00
# define SBP2_LOGIN_REQUEST 0x0
# define SBP2_QUERY_LOGINS_REQUEST 0x1
# define SBP2_RECONNECT_REQUEST 0x3
# define SBP2_SET_PASSWORD_REQUEST 0x4
# define SBP2_LOGOUT_REQUEST 0x7
# define SBP2_ABORT_TASK_REQUEST 0xb
# define SBP2_ABORT_TASK_SET 0xc
# define SBP2_LOGICAL_UNIT_RESET 0xe
# define SBP2_TARGET_RESET_REQUEST 0xf
2006-11-02 23:16:08 +03:00
# define ORB_SET_LUN(v) ((v) & 0xffff)
# define ORB_SET_FUNCTION(v) (((v) & 0xf) << 16)
# define ORB_SET_RECONNECT(v) (((v) & 0xf) << 20)
2007-06-18 01:54:52 +04:00
# define ORB_SET_EXCLUSIVE(v) ((v) ? 1 << 28 : 0)
2006-11-02 23:16:08 +03:00
# define ORB_SET_LOGIN_RESP_LENGTH(v) ((v) & 0xffff)
# define ORB_SET_PASSWD_LENGTH(v) (((v) & 0xffff) << 16)
2005-04-17 02:20:36 +04:00
struct sbp2_login_orb {
u32 password_hi ;
u32 password_lo ;
u32 login_response_hi ;
u32 login_response_lo ;
u32 lun_misc ;
u32 passwd_resp_lengths ;
2006-01-31 08:13:33 +03:00
u32 status_fifo_hi ;
u32 status_fifo_lo ;
2006-06-13 02:14:47 +04:00
} __attribute__ ( ( packed ) ) ;
2005-04-17 02:20:36 +04:00
2006-11-02 23:16:08 +03:00
# define RESPONSE_GET_LOGIN_ID(v) ((v) & 0xffff)
# define RESPONSE_GET_LENGTH(v) (((v) >> 16) & 0xffff)
# define RESPONSE_GET_RECONNECT_HOLD(v) ((v) & 0xffff)
2005-04-17 02:20:36 +04:00
struct sbp2_login_response {
u32 length_login_ID ;
u32 command_block_agent_hi ;
u32 command_block_agent_lo ;
u32 reconnect_hold ;
2006-06-13 02:14:47 +04:00
} __attribute__ ( ( packed ) ) ;
2005-04-17 02:20:36 +04:00
2006-11-02 23:16:08 +03:00
# define ORB_SET_LOGIN_ID(v) ((v) & 0xffff)
# define ORB_SET_QUERY_LOGINS_RESP_LENGTH(v) ((v) & 0xffff)
2005-04-17 02:20:36 +04:00
struct sbp2_query_logins_orb {
u32 reserved1 ;
u32 reserved2 ;
u32 query_response_hi ;
u32 query_response_lo ;
u32 lun_misc ;
u32 reserved_resp_length ;
2006-01-31 08:13:33 +03:00
u32 status_fifo_hi ;
u32 status_fifo_lo ;
2006-06-13 02:14:47 +04:00
} __attribute__ ( ( packed ) ) ;
2005-04-17 02:20:36 +04:00
2006-11-02 23:16:08 +03:00
# define RESPONSE_GET_MAX_LOGINS(v) ((v) & 0xffff)
# define RESPONSE_GET_ACTIVE_LOGINS(v) ((RESPONSE_GET_LENGTH((v)) - 4) / 12)
2005-04-17 02:20:36 +04:00
struct sbp2_query_logins_response {
u32 length_max_logins ;
u32 misc_IDs ;
u32 initiator_misc_hi ;
u32 initiator_misc_lo ;
2006-06-13 02:14:47 +04:00
} __attribute__ ( ( packed ) ) ;
2005-04-17 02:20:36 +04:00
struct sbp2_reconnect_orb {
u32 reserved1 ;
u32 reserved2 ;
2005-11-07 14:31:39 +03:00
u32 reserved3 ;
u32 reserved4 ;
2005-04-17 02:20:36 +04:00
u32 login_ID_misc ;
u32 reserved5 ;
2006-01-31 08:13:33 +03:00
u32 status_fifo_hi ;
u32 status_fifo_lo ;
2006-06-13 02:14:47 +04:00
} __attribute__ ( ( packed ) ) ;
2005-04-17 02:20:36 +04:00
struct sbp2_logout_orb {
u32 reserved1 ;
u32 reserved2 ;
2005-11-07 14:31:39 +03:00
u32 reserved3 ;
u32 reserved4 ;
2005-04-17 02:20:36 +04:00
u32 login_ID_misc ;
u32 reserved5 ;
2006-01-31 08:13:33 +03:00
u32 status_fifo_hi ;
u32 status_fifo_lo ;
2006-06-13 02:14:47 +04:00
} __attribute__ ( ( packed ) ) ;
2005-04-17 02:20:36 +04:00
struct sbp2_unrestricted_page_table {
2008-08-14 11:28:14 +04:00
__be32 high ;
__be32 low ;
} ;
2005-04-17 02:20:36 +04:00
# define RESP_STATUS_REQUEST_COMPLETE 0x0
# define RESP_STATUS_TRANSPORT_FAILURE 0x1
# define RESP_STATUS_ILLEGAL_REQUEST 0x2
# define RESP_STATUS_VENDOR_DEPENDENT 0x3
# define SBP2_STATUS_NO_ADDITIONAL_INFO 0x0
# define SBP2_STATUS_REQ_TYPE_NOT_SUPPORTED 0x1
# define SBP2_STATUS_SPEED_NOT_SUPPORTED 0x2
# define SBP2_STATUS_PAGE_SIZE_NOT_SUPPORTED 0x3
# define SBP2_STATUS_ACCESS_DENIED 0x4
# define SBP2_STATUS_LU_NOT_SUPPORTED 0x5
# define SBP2_STATUS_MAX_PAYLOAD_TOO_SMALL 0x6
# define SBP2_STATUS_RESOURCES_UNAVAILABLE 0x8
# define SBP2_STATUS_FUNCTION_REJECTED 0x9
# define SBP2_STATUS_LOGIN_ID_NOT_RECOGNIZED 0xa
# define SBP2_STATUS_DUMMY_ORB_COMPLETED 0xb
# define SBP2_STATUS_REQUEST_ABORTED 0xc
# define SBP2_STATUS_UNSPECIFIED_ERROR 0xff
# define SFMT_CURRENT_ERROR 0x0
# define SFMT_DEFERRED_ERROR 0x1
# define SFMT_VENDOR_DEPENDENT_STATUS 0x3
2006-11-02 23:16:08 +03:00
# define STATUS_GET_SRC(v) (((v) >> 30) & 0x3)
# define STATUS_GET_RESP(v) (((v) >> 28) & 0x3)
# define STATUS_GET_LEN(v) (((v) >> 24) & 0x7)
# define STATUS_GET_SBP_STATUS(v) (((v) >> 16) & 0xff)
# define STATUS_GET_ORB_OFFSET_HI(v) ((v) & 0x0000ffff)
# define STATUS_TEST_DEAD(v) ((v) & 0x08000000)
2006-07-24 00:18:00 +04:00
/* test 'resp' | 'dead' | 'sbp2_status' */
2006-11-02 23:16:08 +03:00
# define STATUS_TEST_RDS(v) ((v) & 0x38ff0000)
2005-04-17 02:20:36 +04:00
struct sbp2_status_block {
u32 ORB_offset_hi_misc ;
u32 ORB_offset_lo ;
2005-11-07 14:31:39 +03:00
u8 command_set_dependent [ 24 ] ;
2006-06-13 02:14:47 +04:00
} __attribute__ ( ( packed ) ) ;
2005-04-17 02:20:36 +04:00
2006-11-02 23:16:08 +03:00
2005-04-17 02:20:36 +04:00
/*
2006-11-02 23:16:08 +03:00
* SBP2 related configuration ROM definitions
2005-04-17 02:20:36 +04:00
*/
2006-11-02 23:16:08 +03:00
# define SBP2_UNIT_DIRECTORY_OFFSET_KEY 0xd1
# define SBP2_CSR_OFFSET_KEY 0x54
# define SBP2_UNIT_SPEC_ID_KEY 0x12
# define SBP2_UNIT_SW_VERSION_KEY 0x13
# define SBP2_COMMAND_SET_SPEC_ID_KEY 0x38
# define SBP2_COMMAND_SET_KEY 0x39
# define SBP2_UNIT_CHARACTERISTICS_KEY 0x3a
# define SBP2_DEVICE_TYPE_AND_LUN_KEY 0x14
# define SBP2_FIRMWARE_REVISION_KEY 0x3c
2005-04-17 02:20:36 +04:00
2006-11-02 23:16:08 +03:00
# define SBP2_AGENT_STATE_OFFSET 0x00ULL
# define SBP2_AGENT_RESET_OFFSET 0x04ULL
# define SBP2_ORB_POINTER_OFFSET 0x08ULL
# define SBP2_DOORBELL_OFFSET 0x10ULL
# define SBP2_UNSOLICITED_STATUS_ENABLE_OFFSET 0x14ULL
# define SBP2_UNSOLICITED_STATUS_VALUE 0xf
2005-04-17 02:20:36 +04:00
2006-11-02 23:16:08 +03:00
# define SBP2_BUSY_TIMEOUT_ADDRESS 0xfffff0000210ULL
2006-11-02 23:16:08 +03:00
/* biggest possible value for Single Phase Retry count is 0xf */
2006-11-02 23:16:08 +03:00
# define SBP2_BUSY_TIMEOUT_VALUE 0xf
2005-04-17 02:20:36 +04:00
2006-11-02 23:16:08 +03:00
# define SBP2_AGENT_RESET_DATA 0xf
2005-04-17 02:20:36 +04:00
2006-11-02 23:16:08 +03:00
# define SBP2_UNIT_SPEC_ID_ENTRY 0x0000609e
# define SBP2_SW_VERSION_ENTRY 0x00010483
2005-04-17 02:20:36 +04:00
/*
2008-08-14 11:28:14 +04:00
* The default maximum s / g segment size of a FireWire controller is
* usually 0x10000 , but SBP - 2 only allows 0xffff . Since buffers have to
* be quadlet - aligned , we set the length limit to 0xffff & ~ 3.
2005-04-17 02:20:36 +04:00
*/
2008-08-14 11:28:14 +04:00
# define SBP2_MAX_SEG_SIZE 0xfffc
2005-04-17 02:20:36 +04:00
2008-08-14 11:28:14 +04:00
/*
* There is no real limitation of the queue depth ( i . e . length of the linked
2006-11-02 23:16:08 +03:00
* list of command ORBs ) at the target . The chosen depth is merely an
2008-08-14 11:28:14 +04:00
* implementation detail of the sbp2 driver .
*/
2006-11-02 23:16:08 +03:00
# define SBP2_MAX_CMDS 8
2005-04-17 02:20:36 +04:00
2006-11-02 23:16:08 +03:00
# define SBP2_SCSI_STATUS_GOOD 0x0
# define SBP2_SCSI_STATUS_CHECK_CONDITION 0x2
# define SBP2_SCSI_STATUS_CONDITION_MET 0x4
# define SBP2_SCSI_STATUS_BUSY 0x8
# define SBP2_SCSI_STATUS_RESERVATION_CONFLICT 0x18
# define SBP2_SCSI_STATUS_COMMAND_TERMINATED 0x22
# define SBP2_SCSI_STATUS_SELECTION_TIMEOUT 0xff
2006-05-16 00:04:59 +04:00
2006-11-02 23:16:08 +03:00
/*
* Representations of commands and devices
*/
/* Per SCSI command */
2005-04-17 02:20:36 +04:00
struct sbp2_command_info {
struct list_head list ;
2007-02-04 15:04:32 +03:00
struct sbp2_command_orb command_orb ;
dma_addr_t command_orb_dma ;
2005-04-17 02:20:36 +04:00
struct scsi_cmnd * Current_SCpnt ;
void ( * Current_done ) ( struct scsi_cmnd * ) ;
/* Also need s/g structure for each sbp2 command */
2006-11-02 23:16:08 +03:00
struct sbp2_unrestricted_page_table
2007-02-04 15:04:32 +03:00
scatter_gather_element [ SG_ALL ] __attribute__ ( ( aligned ( 8 ) ) ) ;
dma_addr_t sge_dma ;
2005-04-17 02:20:36 +04:00
} ;
2006-11-02 23:16:08 +03:00
/* Per FireWire host */
2006-11-02 23:16:08 +03:00
struct sbp2_fwhost_info {
2006-11-02 23:16:08 +03:00
struct hpsb_host * host ;
2006-11-02 23:16:08 +03:00
struct list_head logical_units ;
2006-11-02 23:16:08 +03:00
} ;
2005-04-17 02:20:36 +04:00
2006-11-02 23:16:08 +03:00
/* Per logical unit */
2006-11-02 23:16:08 +03:00
struct sbp2_lu {
2006-11-02 23:16:08 +03:00
/* Operation request blocks */
2005-04-17 02:20:36 +04:00
struct sbp2_command_orb * last_orb ;
dma_addr_t last_orb_dma ;
struct sbp2_login_orb * login_orb ;
dma_addr_t login_orb_dma ;
struct sbp2_login_response * login_response ;
dma_addr_t login_response_dma ;
struct sbp2_query_logins_orb * query_logins_orb ;
dma_addr_t query_logins_orb_dma ;
struct sbp2_query_logins_response * query_logins_response ;
dma_addr_t query_logins_response_dma ;
struct sbp2_reconnect_orb * reconnect_orb ;
dma_addr_t reconnect_orb_dma ;
struct sbp2_logout_orb * logout_orb ;
dma_addr_t logout_orb_dma ;
struct sbp2_status_block status_block ;
2006-11-02 23:16:08 +03:00
/* How to talk to the unit */
2006-11-02 23:16:08 +03:00
u64 management_agent_addr ;
u64 command_block_agent_addr ;
2005-04-17 02:20:36 +04:00
u32 speed_code ;
u32 max_payload_size ;
2006-11-02 23:16:08 +03:00
u16 lun ;
2005-04-17 02:20:36 +04:00
2006-11-02 23:16:08 +03:00
/* Address for the unit to write status blocks to */
2006-01-31 08:13:33 +03:00
u64 status_fifo_addr ;
2006-11-02 23:16:08 +03:00
/* Waitqueue flag for logins, reconnects, logouts, query logins */
2006-11-15 21:14:15 +03:00
unsigned int access_complete : 1 ;
2005-04-17 02:20:36 +04:00
2006-11-02 23:16:08 +03:00
/* Pool of command ORBs for this logical unit */
2006-11-02 23:16:08 +03:00
spinlock_t cmd_orb_lock ;
struct list_head cmd_orb_inuse ;
struct list_head cmd_orb_completed ;
2005-04-17 02:20:36 +04:00
2006-11-02 23:16:08 +03:00
/* Backlink to FireWire host; list of units attached to the host */
2006-11-02 23:16:08 +03:00
struct sbp2_fwhost_info * hi ;
2006-11-02 23:16:08 +03:00
struct list_head lu_list ;
2005-04-17 02:20:36 +04:00
2006-11-02 23:16:08 +03:00
/* IEEE 1394 core's device representations */
2005-04-17 02:20:36 +04:00
struct node_entry * ne ;
struct unit_directory * ud ;
2006-11-02 23:16:08 +03:00
/* SCSI core's device representations */
2005-04-17 02:20:36 +04:00
struct scsi_device * sdev ;
2006-11-02 23:16:08 +03:00
struct Scsi_Host * shost ;
2005-04-17 02:20:36 +04:00
/* Device specific workarounds/brokeness */
2006-05-16 00:04:59 +04:00
unsigned workarounds ;
2006-08-14 20:43:00 +04:00
2006-11-02 23:16:08 +03:00
/* Connection state */
2006-08-14 20:59:00 +04:00
atomic_t state ;
2006-11-02 23:16:08 +03:00
/* For deferred requests to the fetch agent */
2006-12-08 00:40:33 +03:00
struct work_struct protocol_work ;
2005-04-17 02:20:36 +04:00
} ;
2006-11-02 23:16:08 +03:00
/* For use in sbp2_lu.state */
2006-08-14 20:59:00 +04:00
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 */
} ;
2006-11-02 23:16:08 +03:00
/* For use in sbp2_lu.workarounds and in the corresponding
2006-11-02 23:16:08 +03:00
* module load parameter */
2006-11-02 23:16:08 +03:00
# define SBP2_WORKAROUND_128K_MAX_TRANS 0x1
# define SBP2_WORKAROUND_INQUIRY_36 0x2
# define SBP2_WORKAROUND_MODE_SENSE_8 0x4
# define SBP2_WORKAROUND_FIX_CAPACITY 0x8
2008-02-04 01:07:44 +03:00
# define SBP2_WORKAROUND_DELAY_INQUIRY 0x10
# define SBP2_INQUIRY_DELAY 12
2008-05-11 02:35:55 +04:00
# define SBP2_WORKAROUND_POWER_CONDITION 0x20
2006-11-02 23:16:08 +03:00
# define SBP2_WORKAROUND_OVERRIDE 0x100
2005-04-17 02:20:36 +04:00
# endif /* SBP2_H */