linux/drivers/scsi/mvumi.h
<<
>>
Prefs
   1/*
   2  * Marvell UMI head file
   3  *
   4  * Copyright 2011 Marvell. <jyli@marvell.com>
   5  *
   6  * This file is licensed under GPLv2.
   7  *
   8  * This program is free software; you can redistribute it and/or
   9  * modify it under the terms of the GNU General Public License as
  10  * published by the Free Software Foundation; version 2 of the
  11  * License.
  12  *
  13  * This program is distributed in the hope that it will be useful,
  14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16  * General Public License for more details.
  17  *
  18  * You should have received a copy of the GNU General Public License
  19  * along with this program; if not, write to the Free Software
  20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
  21  * USA
  22 */
  23
  24#ifndef MVUMI_H
  25#define MVUMI_H
  26
  27#define MAX_BASE_ADDRESS        6
  28
  29#define VER_MAJOR               1
  30#define VER_MINOR               1
  31#define VER_OEM                 0
  32#define VER_BUILD               1500
  33
  34#define MV_DRIVER_NAME                  "mvumi"
  35#define PCI_VENDOR_ID_MARVELL_2         0x1b4b
  36#define PCI_DEVICE_ID_MARVELL_MV9143    0x9143
  37#define PCI_DEVICE_ID_MARVELL_MV9580    0x9580
  38
  39#define MVUMI_INTERNAL_CMD_WAIT_TIME    45
  40#define MVUMI_INQUIRY_LENGTH            44
  41#define MVUMI_INQUIRY_UUID_OFF          36
  42#define MVUMI_INQUIRY_UUID_LEN          8
  43
  44#define IS_DMA64                        (sizeof(dma_addr_t) == 8)
  45
  46enum mvumi_qc_result {
  47        MV_QUEUE_COMMAND_RESULT_SENT = 0,
  48        MV_QUEUE_COMMAND_RESULT_NO_RESOURCE,
  49};
  50
  51struct mvumi_hw_regs {
  52        /* For CPU */
  53        void *main_int_cause_reg;
  54        void *enpointa_mask_reg;
  55        void *enpointb_mask_reg;
  56        void *rstoutn_en_reg;
  57        void *ctrl_sts_reg;
  58        void *rstoutn_mask_reg;
  59        void *sys_soft_rst_reg;
  60
  61        /* For Doorbell */
  62        void *pciea_to_arm_drbl_reg;
  63        void *arm_to_pciea_drbl_reg;
  64        void *arm_to_pciea_mask_reg;
  65        void *pciea_to_arm_msg0;
  66        void *pciea_to_arm_msg1;
  67        void *arm_to_pciea_msg0;
  68        void *arm_to_pciea_msg1;
  69
  70        /* reset register */
  71        void *reset_request;
  72        void *reset_enable;
  73
  74        /* For Message Unit */
  75        void *inb_list_basel;
  76        void *inb_list_baseh;
  77        void *inb_aval_count_basel;
  78        void *inb_aval_count_baseh;
  79        void *inb_write_pointer;
  80        void *inb_read_pointer;
  81        void *outb_list_basel;
  82        void *outb_list_baseh;
  83        void *outb_copy_basel;
  84        void *outb_copy_baseh;
  85        void *outb_copy_pointer;
  86        void *outb_read_pointer;
  87        void *inb_isr_cause;
  88        void *outb_isr_cause;
  89        void *outb_coal_cfg;
  90        void *outb_coal_timeout;
  91
  92        /* Bit setting for HW */
  93        u32 int_comaout;
  94        u32 int_comaerr;
  95        u32 int_dl_cpu2pciea;
  96        u32 int_mu;
  97        u32 int_drbl_int_mask;
  98        u32 int_main_int_mask;
  99        u32 cl_pointer_toggle;
 100        u32 cl_slot_num_mask;
 101        u32 clic_irq;
 102        u32 clic_in_err;
 103        u32 clic_out_err;
 104};
 105
 106struct mvumi_dyn_list_entry {
 107        u32 src_low_addr;
 108        u32 src_high_addr;
 109        u32 if_length;
 110        u32 reserve;
 111};
 112
 113#define SCSI_CMD_MARVELL_SPECIFIC       0xE1
 114#define CDB_CORE_MODULE                 0x1
 115#define CDB_CORE_SHUTDOWN               0xB
 116
 117enum {
 118        DRBL_HANDSHAKE                  = 1 << 0,
 119        DRBL_SOFT_RESET                 = 1 << 1,
 120        DRBL_BUS_CHANGE                 = 1 << 2,
 121        DRBL_EVENT_NOTIFY               = 1 << 3,
 122        DRBL_MU_RESET                   = 1 << 4,
 123        DRBL_HANDSHAKE_ISR              = DRBL_HANDSHAKE,
 124
 125        /*
 126        * Command flag is the flag for the CDB command itself
 127        */
 128        /* 1-non data; 0-data command */
 129        CMD_FLAG_NON_DATA               = 1 << 0,
 130        CMD_FLAG_DMA                    = 1 << 1,
 131        CMD_FLAG_PIO                    = 1 << 2,
 132        /* 1-host read data */
 133        CMD_FLAG_DATA_IN                = 1 << 3,
 134        /* 1-host write data */
 135        CMD_FLAG_DATA_OUT               = 1 << 4,
 136        CMD_FLAG_PRDT_IN_HOST           = 1 << 5,
 137};
 138
 139#define APICDB0_EVENT                   0xF4
 140#define APICDB1_EVENT_GETEVENT          0
 141#define APICDB1_HOST_GETEVENT           1
 142#define MAX_EVENTS_RETURNED             6
 143
 144#define DEVICE_OFFLINE  0
 145#define DEVICE_ONLINE   1
 146
 147struct mvumi_hotplug_event {
 148        u16 size;
 149        u8 dummy[2];
 150        u8 bitmap[0];
 151};
 152
 153struct mvumi_driver_event {
 154        u32     time_stamp;
 155        u32     sequence_no;
 156        u32     event_id;
 157        u8      severity;
 158        u8      param_count;
 159        u16     device_id;
 160        u32     params[4];
 161        u8      sense_data_length;
 162        u8      Reserved1;
 163        u8      sense_data[30];
 164};
 165
 166struct mvumi_event_req {
 167        unsigned char   count;
 168        unsigned char   reserved[3];
 169        struct mvumi_driver_event  events[MAX_EVENTS_RETURNED];
 170};
 171
 172struct mvumi_events_wq {
 173        struct work_struct work_q;
 174        struct mvumi_hba *mhba;
 175        unsigned int event;
 176        void *param;
 177};
 178
 179#define HS_CAPABILITY_SUPPORT_COMPACT_SG        (1U << 4)
 180#define HS_CAPABILITY_SUPPORT_PRD_HOST          (1U << 5)
 181#define HS_CAPABILITY_SUPPORT_DYN_SRC           (1U << 6)
 182#define HS_CAPABILITY_NEW_PAGE_IO_DEPTH_DEF     (1U << 14)
 183
 184#define MVUMI_MAX_SG_ENTRY      32
 185#define SGD_EOT                 (1L << 27)
 186#define SGD_EOT_CP              (1L << 22)
 187
 188struct mvumi_sgl {
 189        u32     baseaddr_l;
 190        u32     baseaddr_h;
 191        u32     flags;
 192        u32     size;
 193};
 194struct mvumi_compact_sgl {
 195        u32     baseaddr_l;
 196        u32     baseaddr_h;
 197        u32     flags;
 198};
 199
 200#define GET_COMPACT_SGD_SIZE(sgd)       \
 201        ((((struct mvumi_compact_sgl *)(sgd))->flags) & 0x3FFFFFL)
 202
 203#define SET_COMPACT_SGD_SIZE(sgd, sz) do {                      \
 204        (((struct mvumi_compact_sgl *)(sgd))->flags) &= ~0x3FFFFFL;     \
 205        (((struct mvumi_compact_sgl *)(sgd))->flags) |= (sz);           \
 206} while (0)
 207#define sgd_getsz(_mhba, sgd, sz) do {                          \
 208        if (_mhba->hba_capability & HS_CAPABILITY_SUPPORT_COMPACT_SG)   \
 209                (sz) = GET_COMPACT_SGD_SIZE(sgd);       \
 210        else \
 211                (sz) = (sgd)->size;                     \
 212} while (0)
 213
 214#define sgd_setsz(_mhba, sgd, sz) do {                          \
 215        if (_mhba->hba_capability & HS_CAPABILITY_SUPPORT_COMPACT_SG)   \
 216                SET_COMPACT_SGD_SIZE(sgd, sz);          \
 217        else \
 218                (sgd)->size = (sz);                     \
 219} while (0)
 220
 221#define sgd_inc(_mhba, sgd) do {        \
 222        if (_mhba->hba_capability & HS_CAPABILITY_SUPPORT_COMPACT_SG)   \
 223                sgd = (struct mvumi_sgl *)(((unsigned char *) (sgd)) + 12); \
 224        else \
 225                sgd = (struct mvumi_sgl *)(((unsigned char *) (sgd)) + 16); \
 226} while (0)
 227
 228struct mvumi_res {
 229        struct list_head entry;
 230        dma_addr_t bus_addr;
 231        void *virt_addr;
 232        unsigned int size;
 233        unsigned short type;    /* enum Resource_Type */
 234};
 235
 236/* Resource type */
 237enum resource_type {
 238        RESOURCE_CACHED_MEMORY = 0,
 239        RESOURCE_UNCACHED_MEMORY
 240};
 241
 242struct mvumi_sense_data {
 243        u8 error_code:7;
 244        u8 valid:1;
 245        u8 segment_number;
 246        u8 sense_key:4;
 247        u8 reserved:1;
 248        u8 incorrect_length:1;
 249        u8 end_of_media:1;
 250        u8 file_mark:1;
 251        u8 information[4];
 252        u8 additional_sense_length;
 253        u8 command_specific_information[4];
 254        u8 additional_sense_code;
 255        u8 additional_sense_code_qualifier;
 256        u8 field_replaceable_unit_code;
 257        u8 sense_key_specific[3];
 258};
 259
 260/* Request initiator must set the status to REQ_STATUS_PENDING. */
 261#define REQ_STATUS_PENDING              0x80
 262
 263struct mvumi_cmd {
 264        struct list_head queue_pointer;
 265        struct mvumi_msg_frame *frame;
 266        dma_addr_t frame_phys;
 267        struct scsi_cmnd *scmd;
 268        atomic_t sync_cmd;
 269        void *data_buf;
 270        unsigned short request_id;
 271        unsigned char cmd_status;
 272};
 273
 274/*
 275 * the function type of the in bound frame
 276 */
 277#define CL_FUN_SCSI_CMD                 0x1
 278
 279struct mvumi_msg_frame {
 280        u16 device_id;
 281        u16 tag;
 282        u8 cmd_flag;
 283        u8 req_function;
 284        u8 cdb_length;
 285        u8 sg_counts;
 286        u32 data_transfer_length;
 287        u16 request_id;
 288        u16 reserved1;
 289        u8 cdb[MAX_COMMAND_SIZE];
 290        u32 payload[1];
 291};
 292
 293/*
 294 * the respond flag for data_payload of the out bound frame
 295 */
 296#define CL_RSP_FLAG_NODATA              0x0
 297#define CL_RSP_FLAG_SENSEDATA           0x1
 298
 299struct mvumi_rsp_frame {
 300        u16 device_id;
 301        u16 tag;
 302        u8 req_status;
 303        u8 rsp_flag;    /* Indicates the type of Data_Payload.*/
 304        u16 request_id;
 305        u32 payload[1];
 306};
 307
 308struct mvumi_ob_data {
 309        struct list_head list;
 310        unsigned char data[0];
 311};
 312
 313struct version_info {
 314        u32 ver_major;
 315        u32 ver_minor;
 316        u32 ver_oem;
 317        u32 ver_build;
 318};
 319
 320#define FW_MAX_DELAY                    30
 321#define MVUMI_FW_BUSY                   (1U << 0)
 322#define MVUMI_FW_ATTACH                 (1U << 1)
 323#define MVUMI_FW_ALLOC                  (1U << 2)
 324
 325/*
 326 * State is the state of the MU
 327 */
 328#define FW_STATE_IDLE                   0
 329#define FW_STATE_STARTING               1
 330#define FW_STATE_HANDSHAKING            2
 331#define FW_STATE_STARTED                3
 332#define FW_STATE_ABORT                  4
 333
 334#define HANDSHAKE_SIGNATURE             0x5A5A5A5AL
 335#define HANDSHAKE_READYSTATE            0x55AA5AA5L
 336#define HANDSHAKE_DONESTATE             0x55AAA55AL
 337
 338/* HandShake Status definition */
 339#define HS_STATUS_OK                    1
 340#define HS_STATUS_ERR                   2
 341#define HS_STATUS_INVALID               3
 342
 343/* HandShake State/Cmd definition */
 344#define HS_S_START                      1
 345#define HS_S_RESET                      2
 346#define HS_S_PAGE_ADDR                  3
 347#define HS_S_QUERY_PAGE                 4
 348#define HS_S_SEND_PAGE                  5
 349#define HS_S_END                        6
 350#define HS_S_ABORT                      7
 351#define HS_PAGE_VERIFY_SIZE             128
 352
 353#define HS_GET_STATE(a)                 (a & 0xFFFF)
 354#define HS_GET_STATUS(a)                ((a & 0xFFFF0000) >> 16)
 355#define HS_SET_STATE(a, b)              (a |= (b & 0xFFFF))
 356#define HS_SET_STATUS(a, b)             (a |= ((b & 0xFFFF) << 16))
 357
 358/* handshake frame */
 359struct mvumi_hs_frame {
 360        u16 size;
 361        /* host information */
 362        u8 host_type;
 363        u8 reserved_1[1];
 364        struct version_info host_ver; /* bios or driver version */
 365
 366        /* controller information */
 367        u32 system_io_bus;
 368        u32 slot_number;
 369        u32 intr_level;
 370        u32 intr_vector;
 371
 372        /* communication list configuration */
 373        u32 ib_baseaddr_l;
 374        u32 ib_baseaddr_h;
 375        u32 ob_baseaddr_l;
 376        u32 ob_baseaddr_h;
 377
 378        u8 ib_entry_size;
 379        u8 ob_entry_size;
 380        u8 ob_depth;
 381        u8 ib_depth;
 382
 383        /* system time */
 384        u64 seconds_since1970;
 385};
 386
 387struct mvumi_hs_header {
 388        u8      page_code;
 389        u8      checksum;
 390        u16     frame_length;
 391        u32     frame_content[1];
 392};
 393
 394/*
 395 * the page code type of the handshake header
 396 */
 397#define HS_PAGE_FIRM_CAP        0x1
 398#define HS_PAGE_HOST_INFO       0x2
 399#define HS_PAGE_FIRM_CTL        0x3
 400#define HS_PAGE_CL_INFO         0x4
 401#define HS_PAGE_TOTAL           0x5
 402
 403#define HSP_SIZE(i)     sizeof(struct mvumi_hs_page##i)
 404
 405#define HSP_MAX_SIZE ({                                 \
 406        int size, m1, m2;                               \
 407        m1 = max(HSP_SIZE(1), HSP_SIZE(3));             \
 408        m2 = max(HSP_SIZE(2), HSP_SIZE(4));             \
 409        size = max(m1, m2);                             \
 410        size;                                           \
 411})
 412
 413/* The format of the page code for Firmware capability */
 414struct mvumi_hs_page1 {
 415        u8 pagecode;
 416        u8 checksum;
 417        u16 frame_length;
 418
 419        u16 number_of_ports;
 420        u16 max_devices_support;
 421        u16 max_io_support;
 422        u16 umi_ver;
 423        u32 max_transfer_size;
 424        struct version_info fw_ver;
 425        u8 cl_in_max_entry_size;
 426        u8 cl_out_max_entry_size;
 427        u8 cl_inout_list_depth;
 428        u8 total_pages;
 429        u16 capability;
 430        u16 reserved1;
 431};
 432
 433/* The format of the page code for Host information */
 434struct mvumi_hs_page2 {
 435        u8 pagecode;
 436        u8 checksum;
 437        u16 frame_length;
 438
 439        u8 host_type;
 440        u8 host_cap;
 441        u8 reserved[2];
 442        struct version_info host_ver;
 443        u32 system_io_bus;
 444        u32 slot_number;
 445        u32 intr_level;
 446        u32 intr_vector;
 447        u64 seconds_since1970;
 448};
 449
 450/* The format of the page code for firmware control  */
 451struct mvumi_hs_page3 {
 452        u8      pagecode;
 453        u8      checksum;
 454        u16     frame_length;
 455        u16     control;
 456        u8      reserved[2];
 457        u32     host_bufferaddr_l;
 458        u32     host_bufferaddr_h;
 459        u32     host_eventaddr_l;
 460        u32     host_eventaddr_h;
 461};
 462
 463struct mvumi_hs_page4 {
 464        u8      pagecode;
 465        u8      checksum;
 466        u16     frame_length;
 467        u32     ib_baseaddr_l;
 468        u32     ib_baseaddr_h;
 469        u32     ob_baseaddr_l;
 470        u32     ob_baseaddr_h;
 471        u8      ib_entry_size;
 472        u8      ob_entry_size;
 473        u8      ob_depth;
 474        u8      ib_depth;
 475};
 476
 477struct mvumi_tag {
 478        unsigned short *stack;
 479        unsigned short top;
 480        unsigned short size;
 481};
 482
 483struct mvumi_device {
 484        struct list_head list;
 485        struct scsi_device *sdev;
 486        u64     wwid;
 487        u8      dev_type;
 488        int     id;
 489};
 490
 491struct mvumi_hba {
 492        void *base_addr[MAX_BASE_ADDRESS];
 493        u32 pci_base[MAX_BASE_ADDRESS];
 494        void *mmio;
 495        struct list_head cmd_pool;
 496        struct Scsi_Host *shost;
 497        wait_queue_head_t int_cmd_wait_q;
 498        struct pci_dev *pdev;
 499        unsigned int unique_id;
 500        atomic_t fw_outstanding;
 501        struct mvumi_instance_template *instancet;
 502
 503        void *ib_list;
 504        dma_addr_t ib_list_phys;
 505
 506        void *ib_frame;
 507        dma_addr_t ib_frame_phys;
 508
 509        void *ob_list;
 510        dma_addr_t ob_list_phys;
 511
 512        void *ib_shadow;
 513        dma_addr_t ib_shadow_phys;
 514
 515        void *ob_shadow;
 516        dma_addr_t ob_shadow_phys;
 517
 518        void *handshake_page;
 519        dma_addr_t handshake_page_phys;
 520
 521        unsigned int global_isr;
 522        unsigned int isr_status;
 523
 524        unsigned short max_sge;
 525        unsigned short max_target_id;
 526        unsigned char *target_map;
 527        unsigned int max_io;
 528        unsigned int list_num_io;
 529        unsigned int ib_max_size;
 530        unsigned int ob_max_size;
 531        unsigned int ib_max_size_setting;
 532        unsigned int ob_max_size_setting;
 533        unsigned int max_transfer_size;
 534        unsigned char hba_total_pages;
 535        unsigned char fw_flag;
 536        unsigned char request_id_enabled;
 537        unsigned char eot_flag;
 538        unsigned short hba_capability;
 539        unsigned short io_seq;
 540
 541        unsigned int ib_cur_slot;
 542        unsigned int ob_cur_slot;
 543        unsigned int fw_state;
 544        struct mutex sas_discovery_mutex;
 545
 546        struct list_head ob_data_list;
 547        struct list_head free_ob_list;
 548        struct list_head res_list;
 549        struct list_head waiting_req_list;
 550
 551        struct mvumi_tag tag_pool;
 552        struct mvumi_cmd **tag_cmd;
 553        struct mvumi_hw_regs *regs;
 554        struct mutex device_lock;
 555        struct list_head mhba_dev_list;
 556        struct list_head shost_dev_list;
 557        struct task_struct *dm_thread;
 558        atomic_t pnp_count;
 559};
 560
 561struct mvumi_instance_template {
 562        void (*fire_cmd) (struct mvumi_hba *, struct mvumi_cmd *);
 563        void (*enable_intr) (struct mvumi_hba *);
 564        void (*disable_intr) (struct mvumi_hba *);
 565        int (*clear_intr) (void *);
 566        unsigned int (*read_fw_status_reg) (struct mvumi_hba *);
 567        unsigned int (*check_ib_list) (struct mvumi_hba *);
 568        int (*check_ob_list) (struct mvumi_hba *, unsigned int *,
 569                              unsigned int *);
 570        int (*reset_host) (struct mvumi_hba *);
 571};
 572
 573extern struct timezone sys_tz;
 574#endif
 575