Merge branch 'drm-intel-fixes' of git://people.freedesktop.org/~danvet/drm-intel
[pandora-kernel.git] / drivers / scsi / mvumi.h
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
46 enum mvumi_qc_result {
47         MV_QUEUE_COMMAND_RESULT_SENT = 0,
48         MV_QUEUE_COMMAND_RESULT_NO_RESOURCE,
49 };
50
51 struct 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
106 struct 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
117 enum {
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
147 struct mvumi_hotplug_event {
148         u16 size;
149         u8 dummy[2];
150         u8 bitmap[0];
151 };
152
153 struct 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
166 struct mvumi_event_req {
167         unsigned char   count;
168         unsigned char   reserved[3];
169         struct mvumi_driver_event  events[MAX_EVENTS_RETURNED];
170 };
171
172 struct 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
188 struct mvumi_sgl {
189         u32     baseaddr_l;
190         u32     baseaddr_h;
191         u32     flags;
192         u32     size;
193 };
194 struct 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
228 struct 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 */
237 enum resource_type {
238         RESOURCE_CACHED_MEMORY = 0,
239         RESOURCE_UNCACHED_MEMORY
240 };
241
242 struct 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
263 struct 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
279 struct 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
299 struct 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
308 struct mvumi_ob_data {
309         struct list_head list;
310         unsigned char data[0];
311 };
312
313 struct 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 */
359 struct 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
387 struct 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 */
414 struct 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 */
434 struct 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  */
451 struct 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
463 struct 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
477 struct mvumi_tag {
478         unsigned short *stack;
479         unsigned short top;
480         unsigned short size;
481 };
482
483 struct mvumi_device {
484         struct list_head list;
485         struct scsi_device *sdev;
486         u64     wwid;
487         u8      dev_type;
488         int     id;
489 };
490
491 struct 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
561 struct 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
573 extern struct timezone sys_tz;
574 #endif