0001
0002
0003
0004
0005
0006
0007
0008 #ifndef MVUMI_H
0009 #define MVUMI_H
0010
0011 #define MAX_BASE_ADDRESS 6
0012
0013 #define VER_MAJOR 1
0014 #define VER_MINOR 1
0015 #define VER_OEM 0
0016 #define VER_BUILD 1500
0017
0018 #define MV_DRIVER_NAME "mvumi"
0019 #define PCI_DEVICE_ID_MARVELL_MV9143 0x9143
0020 #define PCI_DEVICE_ID_MARVELL_MV9580 0x9580
0021
0022 #define MVUMI_INTERNAL_CMD_WAIT_TIME 45
0023 #define MVUMI_INQUIRY_LENGTH 44
0024 #define MVUMI_INQUIRY_UUID_OFF 36
0025 #define MVUMI_INQUIRY_UUID_LEN 8
0026
0027 #define IS_DMA64 (sizeof(dma_addr_t) == 8)
0028
0029 enum mvumi_qc_result {
0030 MV_QUEUE_COMMAND_RESULT_SENT = 0,
0031 MV_QUEUE_COMMAND_RESULT_NO_RESOURCE,
0032 };
0033
0034 struct mvumi_hw_regs {
0035
0036 void *main_int_cause_reg;
0037 void *enpointa_mask_reg;
0038 void *enpointb_mask_reg;
0039 void *rstoutn_en_reg;
0040 void *ctrl_sts_reg;
0041 void *rstoutn_mask_reg;
0042 void *sys_soft_rst_reg;
0043
0044
0045 void *pciea_to_arm_drbl_reg;
0046 void *arm_to_pciea_drbl_reg;
0047 void *arm_to_pciea_mask_reg;
0048 void *pciea_to_arm_msg0;
0049 void *pciea_to_arm_msg1;
0050 void *arm_to_pciea_msg0;
0051 void *arm_to_pciea_msg1;
0052
0053
0054 void *reset_request;
0055 void *reset_enable;
0056
0057
0058 void *inb_list_basel;
0059 void *inb_list_baseh;
0060 void *inb_aval_count_basel;
0061 void *inb_aval_count_baseh;
0062 void *inb_write_pointer;
0063 void *inb_read_pointer;
0064 void *outb_list_basel;
0065 void *outb_list_baseh;
0066 void *outb_copy_basel;
0067 void *outb_copy_baseh;
0068 void *outb_copy_pointer;
0069 void *outb_read_pointer;
0070 void *inb_isr_cause;
0071 void *outb_isr_cause;
0072 void *outb_coal_cfg;
0073 void *outb_coal_timeout;
0074
0075
0076 u32 int_comaout;
0077 u32 int_comaerr;
0078 u32 int_dl_cpu2pciea;
0079 u32 int_mu;
0080 u32 int_drbl_int_mask;
0081 u32 int_main_int_mask;
0082 u32 cl_pointer_toggle;
0083 u32 cl_slot_num_mask;
0084 u32 clic_irq;
0085 u32 clic_in_err;
0086 u32 clic_out_err;
0087 };
0088
0089 struct mvumi_dyn_list_entry {
0090 u32 src_low_addr;
0091 u32 src_high_addr;
0092 u32 if_length;
0093 u32 reserve;
0094 };
0095
0096 #define SCSI_CMD_MARVELL_SPECIFIC 0xE1
0097 #define CDB_CORE_MODULE 0x1
0098 #define CDB_CORE_SHUTDOWN 0xB
0099
0100 enum {
0101 DRBL_HANDSHAKE = 1 << 0,
0102 DRBL_SOFT_RESET = 1 << 1,
0103 DRBL_BUS_CHANGE = 1 << 2,
0104 DRBL_EVENT_NOTIFY = 1 << 3,
0105 DRBL_MU_RESET = 1 << 4,
0106 DRBL_HANDSHAKE_ISR = DRBL_HANDSHAKE,
0107
0108
0109
0110
0111
0112 CMD_FLAG_NON_DATA = 1 << 0,
0113 CMD_FLAG_DMA = 1 << 1,
0114 CMD_FLAG_PIO = 1 << 2,
0115
0116 CMD_FLAG_DATA_IN = 1 << 3,
0117
0118 CMD_FLAG_DATA_OUT = 1 << 4,
0119 CMD_FLAG_PRDT_IN_HOST = 1 << 5,
0120 };
0121
0122 #define APICDB0_EVENT 0xF4
0123 #define APICDB1_EVENT_GETEVENT 0
0124 #define APICDB1_HOST_GETEVENT 1
0125 #define MAX_EVENTS_RETURNED 6
0126
0127 #define DEVICE_OFFLINE 0
0128 #define DEVICE_ONLINE 1
0129
0130 struct mvumi_hotplug_event {
0131 u16 size;
0132 u8 dummy[2];
0133 u8 bitmap[];
0134 };
0135
0136 struct mvumi_driver_event {
0137 u32 time_stamp;
0138 u32 sequence_no;
0139 u32 event_id;
0140 u8 severity;
0141 u8 param_count;
0142 u16 device_id;
0143 u32 params[4];
0144 u8 sense_data_length;
0145 u8 Reserved1;
0146 u8 sense_data[30];
0147 };
0148
0149 struct mvumi_event_req {
0150 unsigned char count;
0151 unsigned char reserved[3];
0152 struct mvumi_driver_event events[MAX_EVENTS_RETURNED];
0153 };
0154
0155 struct mvumi_events_wq {
0156 struct work_struct work_q;
0157 struct mvumi_hba *mhba;
0158 unsigned int event;
0159 void *param;
0160 };
0161
0162 #define HS_CAPABILITY_SUPPORT_COMPACT_SG (1U << 4)
0163 #define HS_CAPABILITY_SUPPORT_PRD_HOST (1U << 5)
0164 #define HS_CAPABILITY_SUPPORT_DYN_SRC (1U << 6)
0165 #define HS_CAPABILITY_NEW_PAGE_IO_DEPTH_DEF (1U << 14)
0166
0167 #define MVUMI_MAX_SG_ENTRY 32
0168 #define SGD_EOT (1L << 27)
0169 #define SGD_EOT_CP (1L << 22)
0170
0171 struct mvumi_sgl {
0172 u32 baseaddr_l;
0173 u32 baseaddr_h;
0174 u32 flags;
0175 u32 size;
0176 };
0177 struct mvumi_compact_sgl {
0178 u32 baseaddr_l;
0179 u32 baseaddr_h;
0180 u32 flags;
0181 };
0182
0183 #define GET_COMPACT_SGD_SIZE(sgd) \
0184 ((((struct mvumi_compact_sgl *)(sgd))->flags) & 0x3FFFFFL)
0185
0186 #define SET_COMPACT_SGD_SIZE(sgd, sz) do { \
0187 (((struct mvumi_compact_sgl *)(sgd))->flags) &= ~0x3FFFFFL; \
0188 (((struct mvumi_compact_sgl *)(sgd))->flags) |= (sz); \
0189 } while (0)
0190 #define sgd_getsz(_mhba, sgd, sz) do { \
0191 if (_mhba->hba_capability & HS_CAPABILITY_SUPPORT_COMPACT_SG) \
0192 (sz) = GET_COMPACT_SGD_SIZE(sgd); \
0193 else \
0194 (sz) = (sgd)->size; \
0195 } while (0)
0196
0197 #define sgd_setsz(_mhba, sgd, sz) do { \
0198 if (_mhba->hba_capability & HS_CAPABILITY_SUPPORT_COMPACT_SG) \
0199 SET_COMPACT_SGD_SIZE(sgd, sz); \
0200 else \
0201 (sgd)->size = (sz); \
0202 } while (0)
0203
0204 #define sgd_inc(_mhba, sgd) do { \
0205 if (_mhba->hba_capability & HS_CAPABILITY_SUPPORT_COMPACT_SG) \
0206 sgd = (struct mvumi_sgl *)(((unsigned char *) (sgd)) + 12); \
0207 else \
0208 sgd = (struct mvumi_sgl *)(((unsigned char *) (sgd)) + 16); \
0209 } while (0)
0210
0211 struct mvumi_res {
0212 struct list_head entry;
0213 dma_addr_t bus_addr;
0214 void *virt_addr;
0215 unsigned int size;
0216 unsigned short type;
0217 };
0218
0219
0220 enum resource_type {
0221 RESOURCE_CACHED_MEMORY = 0,
0222 RESOURCE_UNCACHED_MEMORY
0223 };
0224
0225 struct mvumi_sense_data {
0226 u8 error_code:7;
0227 u8 valid:1;
0228 u8 segment_number;
0229 u8 sense_key:4;
0230 u8 reserved:1;
0231 u8 incorrect_length:1;
0232 u8 end_of_media:1;
0233 u8 file_mark:1;
0234 u8 information[4];
0235 u8 additional_sense_length;
0236 u8 command_specific_information[4];
0237 u8 additional_sense_code;
0238 u8 additional_sense_code_qualifier;
0239 u8 field_replaceable_unit_code;
0240 u8 sense_key_specific[3];
0241 };
0242
0243
0244 #define REQ_STATUS_PENDING 0x80
0245
0246 struct mvumi_cmd {
0247 struct list_head queue_pointer;
0248 struct mvumi_msg_frame *frame;
0249 dma_addr_t frame_phys;
0250 struct scsi_cmnd *scmd;
0251 atomic_t sync_cmd;
0252 void *data_buf;
0253 unsigned short request_id;
0254 unsigned char cmd_status;
0255 };
0256
0257 struct mvumi_cmd_priv {
0258 struct mvumi_cmd *cmd_priv;
0259 };
0260
0261 static inline struct mvumi_cmd_priv *mvumi_priv(struct scsi_cmnd *cmd)
0262 {
0263 return scsi_cmd_priv(cmd);
0264 }
0265
0266
0267
0268
0269 #define CL_FUN_SCSI_CMD 0x1
0270
0271 struct mvumi_msg_frame {
0272 u16 device_id;
0273 u16 tag;
0274 u8 cmd_flag;
0275 u8 req_function;
0276 u8 cdb_length;
0277 u8 sg_counts;
0278 u32 data_transfer_length;
0279 u16 request_id;
0280 u16 reserved1;
0281 u8 cdb[MAX_COMMAND_SIZE];
0282 u32 payload[1];
0283 };
0284
0285
0286
0287
0288 #define CL_RSP_FLAG_NODATA 0x0
0289 #define CL_RSP_FLAG_SENSEDATA 0x1
0290
0291 struct mvumi_rsp_frame {
0292 u16 device_id;
0293 u16 tag;
0294 u8 req_status;
0295 u8 rsp_flag;
0296 u16 request_id;
0297 u32 payload[1];
0298 };
0299
0300 struct mvumi_ob_data {
0301 struct list_head list;
0302 unsigned char data[];
0303 };
0304
0305 struct version_info {
0306 u32 ver_major;
0307 u32 ver_minor;
0308 u32 ver_oem;
0309 u32 ver_build;
0310 };
0311
0312 #define FW_MAX_DELAY 30
0313 #define MVUMI_FW_BUSY (1U << 0)
0314 #define MVUMI_FW_ATTACH (1U << 1)
0315 #define MVUMI_FW_ALLOC (1U << 2)
0316
0317
0318
0319
0320 #define FW_STATE_IDLE 0
0321 #define FW_STATE_STARTING 1
0322 #define FW_STATE_HANDSHAKING 2
0323 #define FW_STATE_STARTED 3
0324 #define FW_STATE_ABORT 4
0325
0326 #define HANDSHAKE_SIGNATURE 0x5A5A5A5AL
0327 #define HANDSHAKE_READYSTATE 0x55AA5AA5L
0328 #define HANDSHAKE_DONESTATE 0x55AAA55AL
0329
0330
0331 #define HS_STATUS_OK 1
0332 #define HS_STATUS_ERR 2
0333 #define HS_STATUS_INVALID 3
0334
0335
0336 #define HS_S_START 1
0337 #define HS_S_RESET 2
0338 #define HS_S_PAGE_ADDR 3
0339 #define HS_S_QUERY_PAGE 4
0340 #define HS_S_SEND_PAGE 5
0341 #define HS_S_END 6
0342 #define HS_S_ABORT 7
0343 #define HS_PAGE_VERIFY_SIZE 128
0344
0345 #define HS_GET_STATE(a) (a & 0xFFFF)
0346 #define HS_GET_STATUS(a) ((a & 0xFFFF0000) >> 16)
0347 #define HS_SET_STATE(a, b) (a |= (b & 0xFFFF))
0348 #define HS_SET_STATUS(a, b) (a |= ((b & 0xFFFF) << 16))
0349
0350
0351 struct mvumi_hs_frame {
0352 u16 size;
0353
0354 u8 host_type;
0355 u8 reserved_1[1];
0356 struct version_info host_ver;
0357
0358
0359 u32 system_io_bus;
0360 u32 slot_number;
0361 u32 intr_level;
0362 u32 intr_vector;
0363
0364
0365 u32 ib_baseaddr_l;
0366 u32 ib_baseaddr_h;
0367 u32 ob_baseaddr_l;
0368 u32 ob_baseaddr_h;
0369
0370 u8 ib_entry_size;
0371 u8 ob_entry_size;
0372 u8 ob_depth;
0373 u8 ib_depth;
0374
0375
0376 u64 seconds_since1970;
0377 };
0378
0379 struct mvumi_hs_header {
0380 u8 page_code;
0381 u8 checksum;
0382 u16 frame_length;
0383 u32 frame_content[1];
0384 };
0385
0386
0387
0388
0389 #define HS_PAGE_FIRM_CAP 0x1
0390 #define HS_PAGE_HOST_INFO 0x2
0391 #define HS_PAGE_FIRM_CTL 0x3
0392 #define HS_PAGE_CL_INFO 0x4
0393 #define HS_PAGE_TOTAL 0x5
0394
0395 #define HSP_SIZE(i) sizeof(struct mvumi_hs_page##i)
0396
0397 #define HSP_MAX_SIZE ({ \
0398 int size, m1, m2; \
0399 m1 = max(HSP_SIZE(1), HSP_SIZE(3)); \
0400 m2 = max(HSP_SIZE(2), HSP_SIZE(4)); \
0401 size = max(m1, m2); \
0402 size; \
0403 })
0404
0405
0406 struct mvumi_hs_page1 {
0407 u8 pagecode;
0408 u8 checksum;
0409 u16 frame_length;
0410
0411 u16 number_of_ports;
0412 u16 max_devices_support;
0413 u16 max_io_support;
0414 u16 umi_ver;
0415 u32 max_transfer_size;
0416 struct version_info fw_ver;
0417 u8 cl_in_max_entry_size;
0418 u8 cl_out_max_entry_size;
0419 u8 cl_inout_list_depth;
0420 u8 total_pages;
0421 u16 capability;
0422 u16 reserved1;
0423 };
0424
0425
0426 struct mvumi_hs_page2 {
0427 u8 pagecode;
0428 u8 checksum;
0429 u16 frame_length;
0430
0431 u8 host_type;
0432 u8 host_cap;
0433 u8 reserved[2];
0434 struct version_info host_ver;
0435 u32 system_io_bus;
0436 u32 slot_number;
0437 u32 intr_level;
0438 u32 intr_vector;
0439 u64 seconds_since1970;
0440 };
0441
0442
0443 struct mvumi_hs_page3 {
0444 u8 pagecode;
0445 u8 checksum;
0446 u16 frame_length;
0447 u16 control;
0448 u8 reserved[2];
0449 u32 host_bufferaddr_l;
0450 u32 host_bufferaddr_h;
0451 u32 host_eventaddr_l;
0452 u32 host_eventaddr_h;
0453 };
0454
0455 struct mvumi_hs_page4 {
0456 u8 pagecode;
0457 u8 checksum;
0458 u16 frame_length;
0459 u32 ib_baseaddr_l;
0460 u32 ib_baseaddr_h;
0461 u32 ob_baseaddr_l;
0462 u32 ob_baseaddr_h;
0463 u8 ib_entry_size;
0464 u8 ob_entry_size;
0465 u8 ob_depth;
0466 u8 ib_depth;
0467 };
0468
0469 struct mvumi_tag {
0470 unsigned short *stack;
0471 unsigned short top;
0472 unsigned short size;
0473 };
0474
0475 struct mvumi_device {
0476 struct list_head list;
0477 struct scsi_device *sdev;
0478 u64 wwid;
0479 u8 dev_type;
0480 int id;
0481 };
0482
0483 struct mvumi_hba {
0484 void *base_addr[MAX_BASE_ADDRESS];
0485 u32 pci_base[MAX_BASE_ADDRESS];
0486 void *mmio;
0487 struct list_head cmd_pool;
0488 struct Scsi_Host *shost;
0489 wait_queue_head_t int_cmd_wait_q;
0490 struct pci_dev *pdev;
0491 unsigned int unique_id;
0492 atomic_t fw_outstanding;
0493 struct mvumi_instance_template *instancet;
0494
0495 void *ib_list;
0496 dma_addr_t ib_list_phys;
0497
0498 void *ib_frame;
0499 dma_addr_t ib_frame_phys;
0500
0501 void *ob_list;
0502 dma_addr_t ob_list_phys;
0503
0504 void *ib_shadow;
0505 dma_addr_t ib_shadow_phys;
0506
0507 void *ob_shadow;
0508 dma_addr_t ob_shadow_phys;
0509
0510 void *handshake_page;
0511 dma_addr_t handshake_page_phys;
0512
0513 unsigned int global_isr;
0514 unsigned int isr_status;
0515
0516 unsigned short max_sge;
0517 unsigned short max_target_id;
0518 unsigned char *target_map;
0519 unsigned int max_io;
0520 unsigned int list_num_io;
0521 unsigned int ib_max_size;
0522 unsigned int ob_max_size;
0523 unsigned int ib_max_size_setting;
0524 unsigned int ob_max_size_setting;
0525 unsigned int max_transfer_size;
0526 unsigned char hba_total_pages;
0527 unsigned char fw_flag;
0528 unsigned char request_id_enabled;
0529 unsigned char eot_flag;
0530 unsigned short hba_capability;
0531 unsigned short io_seq;
0532
0533 unsigned int ib_cur_slot;
0534 unsigned int ob_cur_slot;
0535 unsigned int fw_state;
0536 struct mutex sas_discovery_mutex;
0537
0538 struct list_head ob_data_list;
0539 struct list_head free_ob_list;
0540 struct list_head res_list;
0541 struct list_head waiting_req_list;
0542
0543 struct mvumi_tag tag_pool;
0544 struct mvumi_cmd **tag_cmd;
0545 struct mvumi_hw_regs *regs;
0546 struct mutex device_lock;
0547 struct list_head mhba_dev_list;
0548 struct list_head shost_dev_list;
0549 struct task_struct *dm_thread;
0550 atomic_t pnp_count;
0551 };
0552
0553 struct mvumi_instance_template {
0554 void (*fire_cmd) (struct mvumi_hba *, struct mvumi_cmd *);
0555 void (*enable_intr) (struct mvumi_hba *);
0556 void (*disable_intr) (struct mvumi_hba *);
0557 int (*clear_intr) (void *);
0558 unsigned int (*read_fw_status_reg) (struct mvumi_hba *);
0559 unsigned int (*check_ib_list) (struct mvumi_hba *);
0560 int (*check_ob_list) (struct mvumi_hba *, unsigned int *,
0561 unsigned int *);
0562 int (*reset_host) (struct mvumi_hba *);
0563 };
0564
0565 extern struct timezone sys_tz;
0566 #endif