This source file includes following definitions.
- aac_enc16
- aac_enc32
- aac_dec16
- aac_dec32
- aac_print_printf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42 #define time_second (mono_time.tv_sec)
43
44
45
46
47 #ifdef AAC_DEBUG
48 #define AAC_DPRINTF(mask, args) if (aac_debug & (mask)) printf args
49 #define AAC_D_INTR 0x001
50 #define AAC_D_MISC 0x002
51 #define AAC_D_CMD 0x004
52 #define AAC_D_QUEUE 0x008
53 #define AAC_D_IO 0x010
54 #define AAC_D_IOCTL 0x020
55 #define AAC_D_LOCK 0x040
56 #define AAC_D_THREAD 0x080
57 #define AAC_D_FIB 0x100
58 extern int aac_debug;
59
60 #define AAC_PRINT_FIB(sc, fib) do { \
61 if (aac_debug & AAC_D_FIB) \
62 aac_print_fib((sc), (fib), __func__); \
63 } while (0)
64 #else
65 #define AAC_DPRINTF(mask, args)
66 #define AAC_PRINT_FIB(sc, fib)
67 #endif
68
69 struct aac_code_lookup {
70 char *string;
71 u_int32_t code;
72 };
73
74 struct aac_softc;
75
76
77
78
79 #define AAC_ADAPTER_FIBS 8
80
81
82
83
84
85 #define AAC_FIB_COUNT (PAGE_SIZE/sizeof(struct aac_fib))
86 #define AAC_MAX_FIBS 512
87 #define AAC_FIBMAP_SIZE (PAGE_SIZE)
88
89
90
91
92
93 #define AAC_AIFQ_LENGTH 64
94
95
96
97
98 #define AAC_PRINTF_BUFSIZE 256
99
100
101
102
103
104 #define AAC_BOOT_TIMEOUT (3 * 60)
105
106
107
108
109 #define AAC_IMMEDIATE_TIMEOUT 30
110
111
112
113
114 #define AAC_CMD_TIMEOUT 30
115
116
117
118
119
120 #define AAC_PERIODIC_INTERVAL 20
121
122
123
124
125 #define AAC_WATCH_TIMEOUT 10000
126
127
128
129
130 #define AAC_SYNC_DELAY 20000
131
132
133
134
135
136 #define AAC_MAXSGENTRIES 64
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151 struct aac_common {
152
153 struct aac_fib ac_fibs[AAC_ADAPTER_FIBS];
154
155
156 struct aac_adapter_init ac_init;
157
158
159 u_int8_t ac_qbuf[sizeof(struct aac_queue_table) + AAC_QUEUE_ALIGN];
160
161
162 char ac_printf[AAC_PRINTF_BUFSIZE];
163
164
165 struct aac_fib ac_sync_fib;
166 };
167 #define AAC_COMMON_ALLOCSIZE (8192 + sizeof(struct aac_common))
168
169
170
171
172 struct aac_interface {
173 int (*aif_get_fwstatus)(struct aac_softc *);
174 void (*aif_qnotify)(struct aac_softc *, int);
175 int (*aif_get_istatus)(struct aac_softc *);
176 void (*aif_set_istatus)(struct aac_softc *, int);
177 void (*aif_set_mailbox)(struct aac_softc *, u_int32_t,
178 u_int32_t, u_int32_t, u_int32_t, u_int32_t);
179 int (*aif_get_mailbox)(struct aac_softc *, int mb);
180 void (*aif_set_interrupts)(struct aac_softc *, int);
181 };
182 extern struct aac_interface aac_fa_interface;
183 extern struct aac_interface aac_sa_interface;
184 extern struct aac_interface aac_rx_interface;
185 extern struct aac_interface aac_rkt_interface;
186
187 #define AAC_GET_FWSTATUS(sc) ((sc)->aac_if.aif_get_fwstatus(sc))
188 #define AAC_QNOTIFY(sc, qbit) \
189 ((sc)->aac_if.aif_qnotify((sc), (qbit)))
190 #define AAC_GET_ISTATUS(sc) ((sc)->aac_if.aif_get_istatus(sc))
191 #define AAC_CLEAR_ISTATUS(sc, mask) \
192 ((sc)->aac_if.aif_set_istatus((sc), (mask)))
193 #define AAC_SET_MAILBOX(sc, command, arg0, arg1, arg2, arg3) \
194 do { \
195 ((sc)->aac_if.aif_set_mailbox((sc), (command), (arg0), \
196 (arg1), (arg2), (arg3))); \
197 } while(0)
198 #define AAC_GET_MAILBOX(sc, mb) \
199 ((sc)->aac_if.aif_get_mailbox(sc, (mb)))
200 #define AAC_MASK_INTERRUPTS(sc) \
201 ((sc)->aac_if.aif_set_interrupts((sc), 0))
202 #define AAC_UNMASK_INTERRUPTS(sc) \
203 ((sc)->aac_if.aif_set_interrupts((sc), 1))
204
205 #define AAC_SETREG4(sc, reg, val) \
206 bus_space_write_4((sc)->aac_memt, (sc)->aac_memh, (reg), (val))
207 #define AAC_GETREG4(sc, reg) \
208 bus_space_read_4((sc)->aac_memt, (sc)->aac_memh, (reg))
209 #define AAC_SETREG2(sc, reg, val) \
210 bus_space_write_2((sc)->aac_memt, (sc)->aac_memh, (reg), (val))
211 #define AAC_GETREG2(sc, reg) \
212 bus_space_read_2((sc)->aac_memt, (sc)->aac_memh, (reg))
213 #define AAC_SETREG1(sc, reg, val) \
214 bus_space_write_1((sc)->aac_memt, (sc)->aac_memh, (reg), (val))
215 #define AAC_GETREG1(sc, reg) \
216 bus_space_read_1((sc)->aac_memt, (sc)->aac_memh, (reg))
217
218
219 typedef struct rwlock aac_lock_t;
220 #define AAC_LOCK_INIT(l, s) do { \
221 rw_init((l), "aaclock"); \
222 AAC_DPRINTF(AAC_D_LOCK, ("%s: init lock @%s: %d\n", \
223 sc->aac_dev.dv_xname, __FUNCTION__, __LINE__)); \
224 } while (0)
225
226 #define AAC_LOCK_ACQUIRE(l) do { \
227 AAC_DPRINTF(AAC_D_LOCK, ("%s: lock @%s: %d\n", \
228 sc->aac_dev.dv_xname, __FUNCTION__, __LINE__)); \
229 rw_enter_write((l)); \
230 } while (0)
231
232 #define AAC_LOCK_RELEASE(l) do { \
233 rw_exit_write((l)); \
234 AAC_DPRINTF(AAC_D_LOCK, ("%s: unlock @%s: %d\n", \
235 sc->aac_dev.dv_xname, __FUNCTION__, __LINE__)); \
236 } while (0)
237
238
239
240
241 struct aac_container
242 {
243 struct aac_mntobj co_mntobj;
244 int co_found;
245 TAILQ_ENTRY(aac_container) co_link;
246 };
247
248
249
250
251
252 struct aac_command
253 {
254 TAILQ_ENTRY(aac_command) cm_link;
255
256 struct aac_softc *cm_sc;
257
258 struct aac_fib *cm_fib;
259 bus_addr_t cm_fibphys;
260 void *cm_data;
261 size_t cm_datalen;
262 bus_dmamap_t cm_datamap;
263 struct aac_sg_table *cm_sgtable;
264
265 u_int cm_flags;
266 #define AAC_CMD_MAPPED (1<<0)
267 #define AAC_CMD_DATAIN (1<<1)
268
269 #define AAC_CMD_DATAOUT (1<<2)
270
271 #define AAC_CMD_COMPLETED (1<<3)
272 #define AAC_CMD_TIMEDOUT (1<<4)
273 #define AAC_ON_AACQ_FREE (1<<5)
274 #define AAC_ON_AACQ_READY (1<<6)
275 #define AAC_ON_AACQ_BUSY (1<<7)
276 #define AAC_ON_AACQ_BIO (1<<8)
277 #define AAC_ON_AACQ_MASK ((1<<5)|(1<<6)|(1<<7)|(1<<8))
278 #define AAC_QUEUE_FRZN (1<<9)
279
280 #define AAC_ACF_WATCHDOG (1<<10)
281
282 void (*cm_complete)(struct aac_command *);
283 void *cm_private;
284 u_int32_t cm_blkno;
285 u_int32_t cm_bcount;
286 time_t cm_timestamp;
287 int cm_queue;
288 int cm_index;
289 };
290
291 struct aac_fibmap {
292 TAILQ_ENTRY(aac_fibmap) fm_link;
293 struct aac_fib *aac_fibs;
294 bus_dmamap_t aac_fibmap;
295 bus_dma_segment_t aac_seg;
296 int aac_nsegs;
297 struct aac_command *aac_commands;
298 };
299
300
301
302
303 #define AACQ_FREE 0
304 #define AACQ_BIO 1
305 #define AACQ_READY 2
306 #define AACQ_BUSY 3
307 #define AACQ_COUNT 4
308
309 struct aac_qstat {
310 u_int32_t q_length;
311 u_int32_t q_max;
312 };
313
314
315
316
317 struct aac_softc
318 {
319 struct device aac_dev;
320 void *aac_ih;
321 struct scsi_link aac_link;
322
323 bus_space_tag_t aac_memt;
324 bus_space_handle_t aac_memh;
325 bus_dma_tag_t aac_dmat;
326
327
328 int aac_state;
329 #define AAC_STATE_SUSPEND (1<<0)
330 #define AAC_STATE_OPEN (1<<1)
331 #define AAC_STATE_INTERRUPTS_ON (1<<2)
332 #define AAC_STATE_AIF_SLEEPER (1<<3)
333 struct FsaRevision aac_revision;
334
335 int aac_hwif;
336 #define AAC_HWIF_I960RX 0
337 #define AAC_HWIF_STRONGARM 1
338 #define AAC_HWIF_FALCON 2
339 #define AAC_HWIF_RKT 3
340 #define AAC_HWIF_UNKNOWN -1
341
342 struct aac_common *aac_common;
343 bus_dmamap_t aac_common_map;
344 u_int32_t aac_common_busaddr;
345 struct aac_interface aac_if;
346
347
348 TAILQ_HEAD(,aac_fibmap) aac_fibmap_tqh;
349 u_int total_fibs;
350 struct aac_command *aac_commands;
351
352
353 TAILQ_HEAD(,aac_command) aac_free;
354
355 TAILQ_HEAD(,aac_command) aac_ready;
356
357 TAILQ_HEAD(,aac_command) aac_busy;
358 TAILQ_HEAD(,aac_command) aac_bio;
359
360
361 struct aac_queue_table *aac_queues;
362 struct aac_queue_entry *aac_qentries[AAC_QUEUE_COUNT];
363
364 struct aac_qstat aac_qstat[AACQ_COUNT];
365
366
367 TAILQ_HEAD(,aac_container) aac_container_tqh;
368 aac_lock_t aac_container_lock;
369
370
371 #define AAC_SYNC_LOCK_FORCE (1 << 0)
372 aac_lock_t aac_sync_lock;
373
374 aac_lock_t aac_io_lock;
375
376 struct {
377 u_int8_t hd_present;
378 u_int8_t hd_is_logdrv;
379 u_int8_t hd_is_arraydrv;
380 u_int8_t hd_is_master;
381 u_int8_t hd_is_parity;
382 u_int8_t hd_is_hotfix;
383 u_int8_t hd_master_no;
384 u_int8_t hd_lock;
385 u_int8_t hd_heads;
386 u_int8_t hd_secs;
387 u_int16_t hd_devtype;
388 u_int32_t hd_size;
389 u_int8_t hd_ldr_no;
390 u_int8_t hd_rw_attribs;
391 u_int32_t hd_start_sec;
392 } aac_hdr[AAC_MAX_CONTAINERS];
393 int aac_container_count;
394
395
396 aac_lock_t aac_aifq_lock;
397 struct aac_aif_command aac_aifq[AAC_AIFQ_LENGTH];
398 int aac_aifq_head;
399 int aac_aifq_tail;
400 struct selinfo aac_select;
401 struct proc *aifthread;
402 int aifflags;
403 #define AAC_AIFFLAGS_RUNNING (1 << 0)
404 #define AAC_AIFFLAGS_AIF (1 << 1)
405 #define AAC_AIFFLAGS_EXIT (1 << 2)
406 #define AAC_AIFFLAGS_EXITED (1 << 3)
407 #define AAC_AIFFLAGS_COMPLETE (1 << 4)
408 #define AAC_AIFFLAGS_PRINTF (1 << 5)
409 #define AAC_AIFFLAGS_PENDING (AAC_AIFFLAGS_AIF | AAC_AIFFLAGS_COMPLETE | \
410 AAC_AIFFLAGS_PRINTF)
411
412 u_int32_t flags;
413 #define AAC_FLAGS_PERC2QC (1 << 0)
414 #define AAC_FLAGS_ENABLE_CAM (1 << 1)
415 #define AAC_FLAGS_CAM_NORESET (1 << 2)
416 #define AAC_FLAGS_CAM_PASSONLY (1 << 3)
417 #define AAC_FLAGS_SG_64BIT (1 << 4)
418 #define AAC_FLAGS_4GB_WINDOW (1 << 5)
419
420 #define AAC_FLAGS_NO4GB (1 << 6)
421 #define AAC_FLAGS_256FIBS (1 << 7)
422 #define AAC_FLAGS_BROKEN_MEMMAP (1 << 8)
423
424 u_int32_t supported_options;
425 int aac_max_fibs;
426 void *aac_sdh;
427 };
428
429
430
431
432 extern int aac_wait_command(struct aac_command *, int);
433 extern int aac_alloc_command(struct aac_softc *, struct aac_command **);
434 extern void aac_release_command(struct aac_command *);
435 extern int aac_alloc_sync_fib(struct aac_softc *, struct aac_fib **, int);
436 extern void aac_release_sync_fib(struct aac_softc *);
437 extern int aac_sync_fib(struct aac_softc *, u_int32_t, u_int32_t,
438 struct aac_fib *, u_int16_t);
439
440 void aacminphys(struct buf *);
441 int aac_attach(struct aac_softc *);
442 int aac_intr(void *);
443
444
445 static __inline__ void aac_enc16(u_int8_t *, u_int16_t);
446 static __inline__ void aac_enc32(u_int8_t *, u_int32_t);
447 static __inline__ u_int16_t aac_dec16(u_int8_t *);
448 static __inline__ u_int32_t aac_dec32(u_int8_t *);
449
450 static __inline__ void
451 aac_enc16(addr, value)
452 u_int8_t *addr;
453 u_int16_t value;
454 {
455 *(u_int16_t *)addr = htole16(value);
456 }
457
458 static __inline__ void
459 aac_enc32(addr, value)
460 u_int8_t *addr;
461 u_int32_t value;
462 {
463 *(u_int32_t *)addr = htole32(value);
464 }
465
466 static __inline__ u_int16_t
467 aac_dec16(addr)
468 u_int8_t *addr;
469 {
470 return letoh16(*(u_int16_t *)addr);
471 }
472
473 static __inline__ u_int32_t
474 aac_dec32(addr)
475 u_int8_t *addr;
476 {
477 return letoh32(*(u_int32_t *)addr);
478 }
479
480
481 #ifdef AAC_DEBUG
482 void aac_print_fib(struct aac_softc *, struct aac_fib *, const char *);
483 void aac_print_aif(struct aac_softc *, struct aac_aif_command *);
484 #endif
485 void aac_handle_aif(struct aac_softc *, struct aac_fib *);
486
487
488
489
490
491
492
493
494 #define AACQ_ADD(sc, qname) \
495 do { \
496 struct aac_qstat *qs; \
497 \
498 qs = &(sc)->aac_qstat[qname]; \
499 \
500 qs->q_length++; \
501 if (qs->q_length > qs->q_max) \
502 qs->q_max = qs->q_length; \
503 } while (0)
504
505 #define AACQ_REMOVE(sc, qname) (sc)->aac_qstat[qname].q_length--
506 #define AACQ_INIT(sc, qname) \
507 do { \
508 sc->aac_qstat[qname].q_length = 0; \
509 sc->aac_qstat[qname].q_max = 0; \
510 } while (0)
511
512
513 #define AACQ_COMMAND_QUEUE(name, index) \
514 static __inline void \
515 aac_initq_ ## name (struct aac_softc *sc) \
516 { \
517 TAILQ_INIT(&sc->aac_ ## name); \
518 AACQ_INIT(sc, index); \
519 } \
520 static __inline void \
521 aac_enqueue_ ## name (struct aac_command *cm) \
522 { \
523 AAC_DPRINTF(AAC_D_CMD, (": enqueue " #name)); \
524 if ((cm->cm_flags & AAC_ON_AACQ_MASK) != 0) { \
525 printf("command %p is on another queue, flags = %#x\n", \
526 cm, cm->cm_flags); \
527 panic("command is on another queue"); \
528 } \
529 TAILQ_INSERT_TAIL(&cm->cm_sc->aac_ ## name, cm, cm_link); \
530 cm->cm_flags |= AAC_ON_ ## index; \
531 AACQ_ADD(cm->cm_sc, index); \
532 } \
533 static __inline void \
534 aac_requeue_ ## name (struct aac_command *cm) \
535 { \
536 AAC_DPRINTF(AAC_D_CMD, (": requeue " #name)); \
537 if ((cm->cm_flags & AAC_ON_AACQ_MASK) != 0) { \
538 printf("command %p is on another queue, flags = %#x\n", \
539 cm, cm->cm_flags); \
540 panic("command is on another queue"); \
541 } \
542 TAILQ_INSERT_HEAD(&cm->cm_sc->aac_ ## name, cm, cm_link); \
543 cm->cm_flags |= AAC_ON_ ## index; \
544 AACQ_ADD(cm->cm_sc, index); \
545 } \
546 static __inline struct aac_command * \
547 aac_dequeue_ ## name (struct aac_softc *sc) \
548 { \
549 struct aac_command *cm; \
550 \
551 if ((cm = TAILQ_FIRST(&sc->aac_ ## name)) != NULL) { \
552 AAC_DPRINTF(AAC_D_CMD, (": dequeue " #name)); \
553 if ((cm->cm_flags & AAC_ON_ ## index) == 0) { \
554 printf("dequeue - command %p not in queue, flags = %#x, " \
555 "bit = %#x\n", cm, cm->cm_flags, \
556 AAC_ON_ ## index); \
557 panic("command not in queue"); \
558 } \
559 TAILQ_REMOVE(&sc->aac_ ## name, cm, cm_link); \
560 cm->cm_flags &= ~AAC_ON_ ## index; \
561 AACQ_REMOVE(sc, index); \
562 } \
563 return(cm); \
564 } \
565 static __inline void \
566 aac_remove_ ## name (struct aac_command *cm) \
567 { \
568 AAC_DPRINTF(AAC_D_CMD, (": remove " #name)); \
569 if ((cm->cm_flags & AAC_ON_ ## index) == 0) { \
570 printf("remove - command %p not in queue, flags = %#x, " \
571 "bit = %#x\n", cm, cm->cm_flags, \
572 AAC_ON_ ## index); \
573 panic("command not in queue"); \
574 } \
575 TAILQ_REMOVE(&cm->cm_sc->aac_ ## name, cm, cm_link); \
576 cm->cm_flags &= ~AAC_ON_ ## index; \
577 AACQ_REMOVE(cm->cm_sc, index); \
578 } \
579 struct hack
580
581 AACQ_COMMAND_QUEUE(free, AACQ_FREE);
582 AACQ_COMMAND_QUEUE(ready, AACQ_READY);
583 AACQ_COMMAND_QUEUE(busy, AACQ_BUSY);
584 AACQ_COMMAND_QUEUE(bio, AACQ_BIO);
585
586 static __inline void
587 aac_print_printf(struct aac_softc *sc)
588 {
589
590
591
592
593 printf("** %s: %.*s", sc->aac_dev.dv_xname, AAC_PRINTF_BUFSIZE,
594 sc->aac_common->ac_printf);
595 sc->aac_common->ac_printf[0] = 0;
596 AAC_QNOTIFY(sc, AAC_DB_PRINTF);
597 }