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