This source file includes following definitions.
- aac_attach
- aac_create_thread
- aac_startup
- aac_add_container
- aac_free
- aac_detach
- aac_shutdown
- aac_suspend
- aac_resume
- aac_intr
- aac_startio
- aac_map_command
- aac_command_thread
- aac_complete
- aac_bio_command
- aac_bio_complete
- aac_wait_command
- aac_alloc_command
- aac_release_command
- aac_alloc_commands
- aac_free_commands
- aac_map_command_sg
- aac_unmap_command
- aac_check_firmware
- aac_init
- aac_sync_command
- aac_alloc_sync_fib
- aac_release_sync_fib
- aac_sync_fib
- aac_enqueue_fib
- aac_dequeue_fib
- aac_enqueue_response
- aac_command_timeout
- aac_timeout
- aac_sa_get_fwstatus
- aac_rx_get_fwstatus
- aac_fa_get_fwstatus
- aac_rkt_get_fwstatus
- aac_sa_qnotify
- aac_rx_qnotify
- aac_fa_qnotify
- aac_rkt_qnotify
- aac_sa_get_istatus
- aac_rx_get_istatus
- aac_fa_get_istatus
- aac_rkt_get_istatus
- aac_sa_clear_istatus
- aac_rx_clear_istatus
- aac_fa_clear_istatus
- aac_rkt_clear_istatus
- aac_sa_set_mailbox
- aac_rx_set_mailbox
- aac_fa_set_mailbox
- aac_rkt_set_mailbox
- aac_sa_get_mailbox
- aac_rx_get_mailbox
- aac_fa_get_mailbox
- aac_rkt_get_mailbox
- aac_sa_set_interrupts
- aac_rx_set_interrupts
- aac_fa_set_interrupts
- aac_rkt_set_interrupts
- aac_eval_mapping
- aac_copy_internal_data
- aac_internal_cache_cmd
- aacminphys
- aac_raw_scsi_cmd
- aac_scsi_cmd
- aac_describe_controller
- aac_describe_code
- aac_print_fib
- aac_print_aif
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
43
44
45
46
47
48 #include <sys/param.h>
49 #include <sys/systm.h>
50 #include <sys/buf.h>
51 #include <sys/device.h>
52 #include <sys/kernel.h>
53 #include <sys/kthread.h>
54 #include <sys/malloc.h>
55 #include <sys/rwlock.h>
56 #include <sys/time.h>
57
58 #include <machine/bus.h>
59
60 #include <uvm/uvm_extern.h>
61
62 #include <scsi/scsi_all.h>
63 #include <scsi/scsi_disk.h>
64 #include <scsi/scsiconf.h>
65
66 #include <dev/ic/aacreg.h>
67 #include <dev/ic/aacvar.h>
68 #include <dev/ic/aac_tables.h>
69
70
71 #define AAC_MAXCYLS 1024
72 #define AAC_HEADS 64
73 #define AAC_SECS 32
74 #define AAC_MEDHEADS 127
75 #define AAC_MEDSECS 63
76 #define AAC_BIGHEADS 255
77 #define AAC_BIGSECS 63
78 #define AAC_SECS32 0x1f
79
80 struct scsi_xfer;
81
82 void aac_copy_internal_data(struct scsi_xfer *, u_int8_t *, size_t);
83 char *aac_describe_code(struct aac_code_lookup *, u_int32_t);
84 void aac_describe_controller(struct aac_softc *);
85 int aac_enqueue_fib(struct aac_softc *, int, struct aac_command *);
86 int aac_dequeue_fib(struct aac_softc *, int, u_int32_t *,
87 struct aac_fib **);
88 int aac_enqueue_response(struct aac_softc *sc, int queue,
89 struct aac_fib *fib);
90
91 void aac_eval_mapping(u_int32_t, int *, int *, int *);
92 void aac_print_printf(struct aac_softc *);
93 int aac_init(struct aac_softc *);
94 int aac_check_firmware(struct aac_softc *);
95 void aac_internal_cache_cmd(struct scsi_xfer *);
96
97
98 void aac_timeout(struct aac_softc *);
99 void aac_command_timeout(struct aac_command *);
100 int aac_map_command(struct aac_command *);
101 void aac_complete(void *);
102 int aac_bio_command(struct aac_softc *, struct aac_command **);
103 void aac_bio_complete(struct aac_command *);
104 int aac_wait_command(struct aac_command *, int);
105 void aac_create_thread(void *);
106 void aac_command_thread(void *);
107
108
109 void aac_map_command_sg(void *, bus_dma_segment_t *, int, int);
110 int aac_alloc_commands(struct aac_softc *);
111 void aac_free_commands(struct aac_softc *);
112 void aac_unmap_command(struct aac_command *);
113
114 int aac_raw_scsi_cmd(struct scsi_xfer *);
115 int aac_scsi_cmd(struct scsi_xfer *);
116 void aac_startio(struct aac_softc *);
117 void aac_startup(struct aac_softc *);
118 void aac_add_container(struct aac_softc *, struct aac_mntinforesp *, int);
119 void aac_shutdown(void *);
120 int aac_sync_command(struct aac_softc *, u_int32_t, u_int32_t,
121 u_int32_t, u_int32_t, u_int32_t, u_int32_t *);
122
123 struct cfdriver aac_cd = {
124 NULL, "aac", DV_DULL
125 };
126
127 struct scsi_adapter aac_switch = {
128 aac_scsi_cmd, aacminphys, 0, 0,
129 };
130
131 struct scsi_adapter aac_raw_switch = {
132 aac_raw_scsi_cmd, aacminphys, 0, 0,
133 };
134
135 struct scsi_device aac_dev = {
136 NULL, NULL, NULL, NULL
137 };
138
139
140 int aac_fa_get_fwstatus(struct aac_softc *);
141 void aac_fa_qnotify(struct aac_softc *, int);
142 int aac_fa_get_istatus(struct aac_softc *);
143 void aac_fa_clear_istatus(struct aac_softc *, int);
144 void aac_fa_set_mailbox(struct aac_softc *, u_int32_t, u_int32_t, u_int32_t,
145 u_int32_t, u_int32_t);
146 int aac_fa_get_mailbox(struct aac_softc *, int);
147 void aac_fa_set_interrupts(struct aac_softc *, int);
148
149 struct aac_interface aac_fa_interface = {
150 aac_fa_get_fwstatus,
151 aac_fa_qnotify,
152 aac_fa_get_istatus,
153 aac_fa_clear_istatus,
154 aac_fa_set_mailbox,
155 aac_fa_get_mailbox,
156 aac_fa_set_interrupts
157 };
158
159
160 int aac_sa_get_fwstatus(struct aac_softc *);
161 void aac_sa_qnotify(struct aac_softc *, int);
162 int aac_sa_get_istatus(struct aac_softc *);
163 void aac_sa_clear_istatus(struct aac_softc *, int);
164 void aac_sa_set_mailbox(struct aac_softc *, u_int32_t, u_int32_t,
165 u_int32_t, u_int32_t, u_int32_t);
166 int aac_sa_get_mailbox(struct aac_softc *, int);
167 void aac_sa_set_interrupts(struct aac_softc *, int);
168
169 struct aac_interface aac_sa_interface = {
170 aac_sa_get_fwstatus,
171 aac_sa_qnotify,
172 aac_sa_get_istatus,
173 aac_sa_clear_istatus,
174 aac_sa_set_mailbox,
175 aac_sa_get_mailbox,
176 aac_sa_set_interrupts
177 };
178
179
180 int aac_rx_get_fwstatus(struct aac_softc *);
181 void aac_rx_qnotify(struct aac_softc *, int);
182 int aac_rx_get_istatus(struct aac_softc *);
183 void aac_rx_clear_istatus(struct aac_softc *, int);
184 void aac_rx_set_mailbox(struct aac_softc *, u_int32_t, u_int32_t,
185 u_int32_t, u_int32_t, u_int32_t);
186 int aac_rx_get_mailbox(struct aac_softc *, int);
187 void aac_rx_set_interrupts(struct aac_softc *, int);
188
189 struct aac_interface aac_rx_interface = {
190 aac_rx_get_fwstatus,
191 aac_rx_qnotify,
192 aac_rx_get_istatus,
193 aac_rx_clear_istatus,
194 aac_rx_set_mailbox,
195 aac_rx_get_mailbox,
196 aac_rx_set_interrupts
197 };
198
199
200 int aac_rkt_get_fwstatus(struct aac_softc *);
201 void aac_rkt_qnotify(struct aac_softc *, int);
202 int aac_rkt_get_istatus(struct aac_softc *);
203 void aac_rkt_clear_istatus(struct aac_softc *, int);
204 void aac_rkt_set_mailbox(struct aac_softc *, u_int32_t,
205 u_int32_t, u_int32_t,
206 u_int32_t, u_int32_t);
207 int aac_rkt_get_mailbox(struct aac_softc *, int);
208 void aac_rkt_set_interrupts(struct aac_softc *, int);
209
210 struct aac_interface aac_rkt_interface = {
211 aac_rkt_get_fwstatus,
212 aac_rkt_qnotify,
213 aac_rkt_get_istatus,
214 aac_rkt_clear_istatus,
215 aac_rkt_set_mailbox,
216 aac_rkt_get_mailbox,
217 aac_rkt_set_interrupts
218 };
219
220 #ifdef AAC_DEBUG
221 int aac_debug = AAC_DEBUG;
222 #endif
223
224 int
225 aac_attach(struct aac_softc *sc)
226 {
227 struct scsibus_attach_args saa;
228 int error;
229
230
231
232
233 aac_initq_free(sc);
234 aac_initq_ready(sc);
235 aac_initq_busy(sc);
236 aac_initq_bio(sc);
237
238
239 AAC_MASK_INTERRUPTS(sc);
240
241
242 sc->aac_state |= AAC_STATE_SUSPEND;
243
244
245
246
247 error = aac_check_firmware(sc);
248 if (error)
249 return (error);
250
251
252
253
254 AAC_LOCK_INIT(&sc->aac_sync_lock, "AAC sync FIB lock");
255 AAC_LOCK_INIT(&sc->aac_aifq_lock, "AAC AIF lock");
256 AAC_LOCK_INIT(&sc->aac_io_lock, "AAC I/O lock");
257 AAC_LOCK_INIT(&sc->aac_container_lock, "AAC container lock");
258 TAILQ_INIT(&sc->aac_container_tqh);
259
260
261 sc->aac_aifq_head = sc->aac_aifq_tail = AAC_AIFQ_LENGTH;
262
263
264
265
266 error = aac_init(sc);
267 if (error)
268 return (error);
269
270
271 sc->aac_link.adapter_softc = sc;
272 sc->aac_link.adapter = &aac_switch;
273 sc->aac_link.device = &aac_dev;
274 sc->aac_link.openings = (sc->total_fibs - 8) /
275 (sc->aac_container_count ? sc->aac_container_count : 1);
276 sc->aac_link.adapter_buswidth = AAC_MAX_CONTAINERS;
277 sc->aac_link.adapter_target = AAC_MAX_CONTAINERS;
278
279 bzero(&saa, sizeof(saa));
280 saa.saa_sc_link = &sc->aac_link;
281
282 config_found(&sc->aac_dev, &saa, scsiprint);
283
284
285 sc->aifthread = 0;
286 sc->aifflags = 0;
287 kthread_create_deferred(aac_create_thread, sc);
288
289 #if 0
290
291 sc->aac_sdh = shutdownhook_establish(aac_shutdown, (void *)sc);
292 #endif
293
294 return (0);
295 }
296
297 void
298 aac_create_thread(void *arg)
299 {
300 struct aac_softc *sc = arg;
301
302 if (kthread_create(aac_command_thread, sc, &sc->aifthread, "%s",
303 sc->aac_dev.dv_xname)) {
304
305 printf("%s: failed to create kernel thread, disabled",
306 sc->aac_dev.dv_xname);
307 }
308 AAC_DPRINTF(AAC_D_MISC, ("%s: aac_create_thread\n",
309 sc->aac_dev.dv_xname));
310
311 }
312
313
314
315
316 void
317 aac_startup(struct aac_softc *sc)
318 {
319 struct aac_fib *fib;
320 struct aac_mntinfo *mi;
321 struct aac_mntinforesp *mir = NULL;
322 int count = 0, i = 0;
323
324
325 aac_alloc_sync_fib(sc, &fib, 0);
326 mi = (struct aac_mntinfo *)&fib->data[0];
327
328 AAC_DPRINTF(AAC_D_MISC, ("%s: aac startup\n", sc->aac_dev.dv_xname));
329
330 sc->aac_container_count = 0;
331
332 do {
333
334 bzero(mi, sizeof(struct aac_mntinfo));
335 mi->Command = VM_NameServe;
336 mi->MntType = FT_FILESYS;
337 mi->MntCount = i;
338 if (aac_sync_fib(sc, ContainerCommand, 0, fib,
339 sizeof(struct aac_mntinfo))) {
340 printf("%s: error probing container %d\n",
341 sc->aac_dev.dv_xname, i);
342 continue;
343 }
344
345 mir = (struct aac_mntinforesp *)&fib->data[0];
346
347 count = mir->MntRespCount;
348
349 #if 0
350 aac_add_container(sc, mir, 0);
351 #else
352
353
354
355
356 if (mir->Status == ST_OK &&
357 mir->MntTable[0].VolType != CT_NONE) {
358 int drv_cyls, drv_hds, drv_secs;
359
360 AAC_DPRINTF(AAC_D_MISC,
361 ("%s: %d: id %x name '%.16s' size %u type %d\n",
362 sc->aac_dev.dv_xname, i,
363 mir->MntTable[0].ObjectId,
364 mir->MntTable[0].FileSystemName,
365 mir->MntTable[0].Capacity,
366 mir->MntTable[0].VolType));
367
368 sc->aac_container_count++;
369 sc->aac_hdr[i].hd_present = 1;
370 sc->aac_hdr[i].hd_size = mir->MntTable[0].Capacity;
371
372
373
374
375 sc->aac_hdr[i].hd_size &= ~AAC_SECS32;
376 aac_eval_mapping(sc->aac_hdr[i].hd_size, &drv_cyls,
377 &drv_hds, &drv_secs);
378 sc->aac_hdr[i].hd_heads = drv_hds;
379 sc->aac_hdr[i].hd_secs = drv_secs;
380
381 sc->aac_hdr[i].hd_size = drv_cyls * drv_hds * drv_secs;
382
383 sc->aac_hdr[i].hd_devtype = mir->MntTable[0].VolType;
384
385
386 }
387 #endif
388
389 i++;
390 } while ((i < count) && (i < AAC_MAX_CONTAINERS));
391
392 aac_release_sync_fib(sc);
393
394 #if 0
395
396 if (bus_generic_attach(sc->aac_dev))
397 printf("%s: bus_generic_attach failed\n",
398 sc->aac_dev.dv_xname);
399 #endif
400
401
402
403 sc->aac_state &= ~AAC_STATE_SUSPEND;
404
405
406 AAC_UNMASK_INTERRUPTS(sc);
407 }
408
409 #if 0
410
411
412
413 void
414 aac_add_container(struct aac_softc *sc, struct aac_mntinforesp *mir, int f)
415 {
416 struct aac_container *co;
417 device_t child;
418
419
420
421
422
423 if ((mir->Status == ST_OK) && (mir->MntTable[0].VolType != CT_NONE)) {
424 co = (struct aac_container *)malloc(sizeof *co, M_DEVBUF,
425 M_NOWAIT);
426 if (co == NULL)
427 panic("Out of memory?!\n");
428 bzero(co, sizeof *co);
429 AAC_DPRINTF(AAC_D_MISC,
430 ("%s: id %x name '%.16s' size %u type %d\n",
431 sc->aac_dev.dv_xname,
432 mir->MntTable[0].ObjectId,
433 mir->MntTable[0].FileSystemName,
434 mir->MntTable[0].Capacity,
435 mir->MntTable[0].VolType);
436
437 if ((child = device_add_child(sc->aac_dev, "aacd", -1)) == NULL)
438 printf("%s: device_add_child failed\n",
439 sc->aac_dev.dv_xname);
440 else
441 device_set_ivars(child, co);
442 device_set_desc(child, aac_describe_code(aac_container_types,
443 mir->MntTable[0].VolType));
444 co->co_disk = child;
445 co->co_found = f;
446 bcopy(&mir->MntTable[0], &co->co_mntobj,
447 sizeof(struct aac_mntobj));
448 AAC_LOCK_ACQUIRE(&sc->aac_container_lock);
449 TAILQ_INSERT_TAIL(&sc->aac_container_tqh, co, co_link);
450 AAC_LOCK_RELEASE(&sc->aac_container_lock);
451 }
452 }
453 #endif
454
455 #if 0
456
457
458
459
460
461 void
462 aac_free(struct aac_softc *sc)
463 {
464
465 debug_called(1);
466
467
468 if (sc->aac_dev_t != NULL)
469 destroy_dev(sc->aac_dev_t);
470
471
472 aac_free_commands(sc);
473 if (sc->aac_fib_dmat)
474 bus_dma_tag_destroy(sc->aac_fib_dmat);
475
476 free(sc->aac_commands, M_AACBUF);
477
478
479 if (sc->aac_common) {
480 bus_dmamap_unload(sc->aac_common_dmat, sc->aac_common_dmamap);
481 bus_dmamem_free(sc->aac_common_dmat, sc->aac_common,
482 sc->aac_common_dmamap);
483 }
484 if (sc->aac_common_dmat)
485 bus_dma_tag_destroy(sc->aac_common_dmat);
486
487
488 if (sc->aac_intr)
489 bus_teardown_intr(sc->aac_dev, sc->aac_irq, sc->aac_intr);
490 if (sc->aac_irq != NULL)
491 bus_release_resource(sc->aac_dev, SYS_RES_IRQ, sc->aac_irq_rid,
492 sc->aac_irq);
493
494
495 if (sc->aac_buffer_dmat)
496 bus_dma_tag_destroy(sc->aac_buffer_dmat);
497
498
499 if (sc->aac_parent_dmat)
500 bus_dma_tag_destroy(sc->aac_parent_dmat);
501
502
503 if (sc->aac_regs_resource != NULL)
504 bus_release_resource(sc->aac_dev, SYS_RES_MEMORY,
505 sc->aac_regs_rid, sc->aac_regs_resource);
506 }
507
508
509
510
511 int
512 aac_detach(device_t dev)
513 {
514 struct aac_softc *sc;
515 struct aac_container *co;
516 struct aac_sim *sim;
517 int error;
518
519 debug_called(1);
520
521 sc = device_get_softc(dev);
522
523 if (sc->aac_state & AAC_STATE_OPEN)
524 return(EBUSY);
525
526
527 while ((co = TAILQ_FIRST(&sc->aac_container_tqh)) != NULL) {
528 error = device_delete_child(dev, co->co_disk);
529 if (error)
530 return (error);
531 TAILQ_REMOVE(&sc->aac_container_tqh, co, co_link);
532 free(co, M_AACBUF);
533 }
534
535
536 while ((sim = TAILQ_FIRST(&sc->aac_sim_tqh)) != NULL) {
537 TAILQ_REMOVE(&sc->aac_sim_tqh, sim, sim_link);
538 error = device_delete_child(dev, sim->sim_dev);
539 if (error)
540 return (error);
541 free(sim, M_AACBUF);
542 }
543
544 if (sc->aifflags & AAC_AIFFLAGS_RUNNING) {
545 sc->aifflags |= AAC_AIFFLAGS_EXIT;
546 wakeup(sc->aifthread);
547 tsleep(sc->aac_dev, PUSER | PCATCH, "aacdch", 30 * hz);
548 }
549
550 if (sc->aifflags & AAC_AIFFLAGS_RUNNING)
551 panic("Cannot shutdown AIF thread\n");
552
553 if ((error = aac_shutdown(dev)))
554 return(error);
555
556 EVENTHANDLER_DEREGISTER(shutdown_final, sc->eh);
557
558 aac_free(sc);
559
560 return(0);
561 }
562
563
564
565
566
567
568
569
570
571 int
572 aac_shutdown(device_t dev)
573 {
574 struct aac_softc *sc;
575 struct aac_fib *fib;
576 struct aac_close_command *cc;
577
578 debug_called(1);
579
580 sc = device_get_softc(dev);
581
582 sc->aac_state |= AAC_STATE_SUSPEND;
583
584
585
586
587
588
589 device_printf(sc->aac_dev, "shutting down controller...");
590
591 aac_alloc_sync_fib(sc, &fib, AAC_SYNC_LOCK_FORCE);
592 cc = (struct aac_close_command *)&fib->data[0];
593
594 bzero(cc, sizeof(struct aac_close_command));
595 cc->Command = VM_CloseAll;
596 cc->ContainerId = 0xffffffff;
597 if (aac_sync_fib(sc, ContainerCommand, 0, fib,
598 sizeof(struct aac_close_command)))
599 printf("FAILED.\n");
600 else
601 printf("done\n");
602 else {
603 fib->data[0] = 0;
604
605
606
607
608
609
610
611 if (aac_sync_fib(sc, FsaHostShutdown, AAC_FIBSTATE_SHUTDOWN,
612 fib, 1)) {
613 printf("FAILED.\n");
614 } else {
615 printf("done.\n");
616 }
617 }
618
619 AAC_MASK_INTERRUPTS(sc);
620
621 return(0);
622 }
623
624
625
626
627 int
628 aac_suspend(device_t dev)
629 {
630 struct aac_softc *sc;
631
632 debug_called(1);
633
634 sc = device_get_softc(dev);
635
636 sc->aac_state |= AAC_STATE_SUSPEND;
637
638 AAC_MASK_INTERRUPTS(sc);
639 return(0);
640 }
641
642
643
644
645 int
646 aac_resume(device_t dev)
647 {
648 struct aac_softc *sc;
649
650 debug_called(1);
651
652 sc = device_get_softc(dev);
653
654 sc->aac_state &= ~AAC_STATE_SUSPEND;
655 AAC_UNMASK_INTERRUPTS(sc);
656 return(0);
657 }
658 #endif
659
660
661
662
663 int
664 aac_intr(void *arg)
665 {
666 struct aac_softc *sc = arg;
667 u_int16_t reason;
668
669
670
671
672
673
674
675
676 reason = AAC_GET_ISTATUS(sc);
677 AAC_CLEAR_ISTATUS(sc, reason);
678 (void)AAC_GET_ISTATUS(sc);
679
680 if (reason == 0)
681 return (0);
682
683 AAC_DPRINTF(AAC_D_INTR, ("%s: intr: sc=%p: reason=%#x\n",
684 sc->aac_dev.dv_xname, sc, reason));
685
686
687 if (reason & (AAC_DB_PRINTF | AAC_DB_COMMAND_READY |
688 AAC_DB_RESPONSE_READY)) {
689
690 if (reason & AAC_DB_RESPONSE_READY) {
691
692 if (sc->aifflags & AAC_AIFFLAGS_RUNNING) {
693 sc->aifflags |= AAC_AIFFLAGS_COMPLETE;
694 } else {
695 AAC_LOCK_ACQUIRE(&sc->aac_io_lock);
696 aac_complete(sc);
697 AAC_LOCK_RELEASE(&sc->aac_io_lock);
698 }
699 }
700
701
702
703
704
705
706 if (reason & AAC_DB_PRINTF)
707 if (sc->aac_common->ac_printf[0] == 0)
708 sc->aac_common->ac_printf[0] = 32;
709
710
711
712
713
714
715
716
717 if (sc->aifthread)
718 wakeup(sc->aifthread);
719
720 }
721
722 return (1);
723 }
724
725
726
727
728
729
730
731
732 void
733 aac_startio(struct aac_softc *sc)
734 {
735 struct aac_command *cm;
736
737 AAC_DPRINTF(AAC_D_CMD, ("%s: start command", sc->aac_dev.dv_xname));
738
739 if (sc->flags & AAC_QUEUE_FRZN) {
740 AAC_DPRINTF(AAC_D_CMD, (": queue frozen"));
741 return;
742 }
743
744 AAC_DPRINTF(AAC_D_CMD, ("\n"));
745
746 for (;;) {
747
748
749
750
751 cm = aac_dequeue_ready(sc);
752
753
754
755
756
757 if (cm == NULL) {
758 AAC_DPRINTF(AAC_D_CMD, ("\n"));
759 aac_bio_command(sc, &cm);
760 AAC_DPRINTF(AAC_D_CMD, ("%s: start done bio",
761 sc->aac_dev.dv_xname));
762 }
763
764
765 if (cm == NULL)
766 break;
767
768
769
770
771
772 if (aac_map_command(cm) != 0)
773 panic("aac: error mapping command %p\n", cm);
774
775 AAC_DPRINTF(AAC_D_CMD, ("\n%s: another command",
776 sc->aac_dev.dv_xname));
777 }
778
779 AAC_DPRINTF(AAC_D_CMD, ("\n"));
780 }
781
782
783
784
785
786 int
787 aac_map_command(struct aac_command *cm)
788 {
789 struct aac_softc *sc = cm->cm_sc;
790 int error = 0;
791
792 AAC_DPRINTF(AAC_D_CMD, (": map command"));
793
794
795 if (cm->cm_flags & AAC_CMD_MAPPED)
796 panic("aac: command %p already mapped", cm);
797
798 if (cm->cm_datalen != 0) {
799 error = bus_dmamap_load(sc->aac_dmat, cm->cm_datamap,
800 cm->cm_data, cm->cm_datalen, NULL,
801 BUS_DMA_NOWAIT);
802 if (error)
803 return (error);
804
805 aac_map_command_sg(cm, cm->cm_datamap->dm_segs,
806 cm->cm_datamap->dm_nsegs, 0);
807 } else {
808 aac_map_command_sg(cm, NULL, 0, 0);
809 }
810
811 return (error);
812 }
813
814
815
816
817 void
818 aac_command_thread(void *arg)
819 {
820 struct aac_softc *sc = arg;
821 struct aac_fib *fib;
822 u_int32_t fib_size;
823 int size, retval;
824
825 AAC_DPRINTF(AAC_D_THREAD, ("%s: aac_command_thread: starting\n",
826 sc->aac_dev.dv_xname));
827 AAC_LOCK_ACQUIRE(&sc->aac_io_lock);
828 sc->aifflags = AAC_AIFFLAGS_RUNNING;
829
830 while ((sc->aifflags & AAC_AIFFLAGS_EXIT) == 0) {
831
832 AAC_DPRINTF(AAC_D_THREAD,
833 ("%s: aac_command_thread: aifflags=%#x\n",
834 sc->aac_dev.dv_xname, sc->aifflags));
835 retval = 0;
836
837 if ((sc->aifflags & AAC_AIFFLAGS_PENDING) == 0) {
838 AAC_DPRINTF(AAC_D_THREAD,
839 ("%s: command thread sleeping\n",
840 sc->aac_dev.dv_xname));
841 AAC_LOCK_RELEASE(&sc->aac_io_lock);
842 retval = tsleep(sc->aifthread, PRIBIO, "aifthd",
843 AAC_PERIODIC_INTERVAL * hz);
844 AAC_LOCK_ACQUIRE(&sc->aac_io_lock);
845 }
846
847 if ((sc->aifflags & AAC_AIFFLAGS_COMPLETE) != 0) {
848 aac_complete(sc);
849 sc->aifflags &= ~AAC_AIFFLAGS_COMPLETE;
850 }
851
852
853
854
855
856
857 if (retval == EWOULDBLOCK)
858 aac_timeout(sc);
859
860
861 if (sc->aac_common->ac_printf[0] != 0)
862 aac_print_printf(sc);
863
864
865 while (aac_dequeue_fib(sc, AAC_HOST_NORM_CMD_QUEUE,
866 &fib_size, &fib) == 0) {
867
868 AAC_PRINT_FIB(sc, fib);
869
870 switch (fib->Header.Command) {
871 case AifRequest:
872
873 break;
874 default:
875 printf("%s: unknown command from controller\n",
876 sc->aac_dev.dv_xname);
877 break;
878 }
879
880 if ((fib->Header.XferState == 0) ||
881 (fib->Header.StructType != AAC_FIBTYPE_TFIB))
882 break;
883
884
885 if (fib->Header.XferState & AAC_FIBSTATE_FROMADAP) {
886 fib->Header.XferState |= AAC_FIBSTATE_DONEHOST;
887 *(AAC_FSAStatus*)fib->data = ST_OK;
888
889
890 size = fib->Header.Size;
891 if (size > sizeof(struct aac_fib)) {
892 size = sizeof(struct aac_fib);
893 fib->Header.Size = size;
894 }
895
896
897
898
899
900
901 aac_enqueue_response(sc,
902 AAC_ADAP_NORM_RESP_QUEUE,
903 fib);
904 }
905 }
906 }
907 sc->aifflags &= ~AAC_AIFFLAGS_RUNNING;
908 AAC_LOCK_RELEASE(&sc->aac_io_lock);
909
910 #if 0
911
912
913
914
915 wakeup(sc->aac_dev);
916 #endif
917
918 AAC_DPRINTF(AAC_D_THREAD, ("%s: aac_command_thread: exiting\n",
919 sc->aac_dev.dv_xname));
920 kthread_exit(0);
921 }
922
923
924
925
926 void
927 aac_complete(void *context)
928 {
929 struct aac_softc *sc = (struct aac_softc *)context;
930 struct aac_command *cm;
931 struct aac_fib *fib;
932 u_int32_t fib_size;
933
934 AAC_DPRINTF(AAC_D_CMD, ("%s: complete", sc->aac_dev.dv_xname));
935
936
937 for (;;) {
938
939 if (aac_dequeue_fib(sc, AAC_HOST_NORM_RESP_QUEUE, &fib_size,
940 &fib))
941 break;
942
943
944 cm = sc->aac_commands + fib->Header.SenderData;
945 if (cm == NULL) {
946 AAC_PRINT_FIB(sc, fib);
947 break;
948 }
949
950 aac_remove_busy(cm);
951 aac_unmap_command(cm);
952 cm->cm_flags |= AAC_CMD_COMPLETED;
953
954
955 if (cm->cm_complete != NULL) {
956 cm->cm_complete(cm);
957 } else {
958
959 wakeup(cm);
960 }
961 }
962
963 AAC_DPRINTF(AAC_D_CMD, ("\n"));
964
965 sc->flags &= ~AAC_QUEUE_FRZN;
966 aac_startio(sc);
967 }
968
969
970
971
972 int
973 aac_bio_command(struct aac_softc *sc, struct aac_command **cmp)
974 {
975 struct aac_command *cm;
976 struct aac_fib *fib;
977 struct scsi_xfer *xs;
978 u_int8_t opcode = 0;
979
980 AAC_DPRINTF(AAC_D_CMD, ("%s: bio command", sc->aac_dev.dv_xname));
981
982
983 if ((cm = aac_dequeue_bio(sc)) == NULL)
984 goto fail;
985 xs = cm->cm_private;
986
987
988 fib = cm->cm_fib;
989 fib->Header.Size = sizeof(struct aac_fib_header);
990 fib->Header.XferState =
991 AAC_FIBSTATE_HOSTOWNED |
992 AAC_FIBSTATE_INITIALISED |
993 AAC_FIBSTATE_EMPTY |
994 AAC_FIBSTATE_FROMHOST |
995 AAC_FIBSTATE_REXPECTED |
996 AAC_FIBSTATE_NORM |
997 AAC_FIBSTATE_ASYNC |
998 AAC_FIBSTATE_FAST_RESPONSE;
999
1000 switch(xs->cmd->opcode) {
1001 case READ_COMMAND:
1002 case READ_BIG:
1003 opcode = READ_COMMAND;
1004 break;
1005 case WRITE_COMMAND:
1006 case WRITE_BIG:
1007 opcode = WRITE_COMMAND;
1008 break;
1009 default:
1010 panic("%s: invalid opcode %#x\n", sc->aac_dev.dv_xname,
1011 xs->cmd->opcode);
1012 }
1013
1014
1015 if ((sc->flags & AAC_FLAGS_SG_64BIT) == 0) {
1016 fib->Header.Command = ContainerCommand;
1017 if (opcode == READ_COMMAND) {
1018 struct aac_blockread *br;
1019 br = (struct aac_blockread *)&fib->data[0];
1020 br->Command = VM_CtBlockRead;
1021 br->ContainerId = xs->sc_link->target;
1022 br->BlockNumber = cm->cm_blkno;
1023 br->ByteCount = cm->cm_bcount * AAC_BLOCK_SIZE;
1024 fib->Header.Size += sizeof(struct aac_blockread);
1025 cm->cm_sgtable = &br->SgMap;
1026 cm->cm_flags |= AAC_CMD_DATAIN;
1027 } else {
1028 struct aac_blockwrite *bw;
1029 bw = (struct aac_blockwrite *)&fib->data[0];
1030 bw->Command = VM_CtBlockWrite;
1031 bw->ContainerId = xs->sc_link->target;
1032 bw->BlockNumber = cm->cm_blkno;
1033 bw->ByteCount = cm->cm_bcount * AAC_BLOCK_SIZE;
1034 bw->Stable = CUNSTABLE;
1035 fib->Header.Size += sizeof(struct aac_blockwrite);
1036 cm->cm_flags |= AAC_CMD_DATAOUT;
1037 cm->cm_sgtable = &bw->SgMap;
1038 }
1039 } else {
1040 fib->Header.Command = ContainerCommand64;
1041 if (opcode == READ_COMMAND) {
1042 struct aac_blockread64 *br;
1043 br = (struct aac_blockread64 *)&fib->data[0];
1044 br->Command = VM_CtHostRead64;
1045 br->ContainerId = xs->sc_link->target;
1046 br->BlockNumber = cm->cm_blkno;
1047 br->SectorCount = cm->cm_bcount;
1048 br->Pad = 0;
1049 br->Flags = 0;
1050 fib->Header.Size += sizeof(struct aac_blockread64);
1051 cm->cm_flags |= AAC_CMD_DATAOUT;
1052 (struct aac_sg_table64 *)cm->cm_sgtable = &br->SgMap64;
1053 } else {
1054 struct aac_blockwrite64 *bw;
1055 bw = (struct aac_blockwrite64 *)&fib->data[0];
1056 bw->Command = VM_CtHostWrite64;
1057 bw->ContainerId = xs->sc_link->target;
1058 bw->BlockNumber = cm->cm_blkno;
1059 bw->SectorCount = cm->cm_bcount;
1060 bw->Pad = 0;
1061 bw->Flags = 0;
1062 fib->Header.Size += sizeof(struct aac_blockwrite64);
1063 cm->cm_flags |= AAC_CMD_DATAIN;
1064 (struct aac_sg_table64 *)cm->cm_sgtable = &bw->SgMap64;
1065 }
1066 }
1067
1068 *cmp = cm;
1069 AAC_DPRINTF(AAC_D_CMD, ("\n"));
1070 return(0);
1071
1072 fail:
1073 AAC_DPRINTF(AAC_D_CMD, ("\n"));
1074 return(ENOMEM);
1075 }
1076
1077
1078
1079
1080 void
1081 aac_bio_complete(struct aac_command *cm)
1082 {
1083 struct aac_blockread_response *brr;
1084 struct aac_blockwrite_response *bwr;
1085 struct scsi_xfer *xs = (struct scsi_xfer *)cm->cm_private;
1086 AAC_FSAStatus status;
1087 int s;
1088
1089 AAC_DPRINTF(AAC_D_CMD,
1090 ("%s: bio complete\n", cm->cm_sc->aac_dev.dv_xname));
1091
1092
1093 if (xs->flags & SCSI_DATA_IN) {
1094 brr = (struct aac_blockread_response *)&cm->cm_fib->data[0];
1095 status = brr->Status;
1096 } else {
1097 bwr = (struct aac_blockwrite_response *)&cm->cm_fib->data[0];
1098 status = bwr->Status;
1099 }
1100
1101 s = splbio();
1102 aac_release_command(cm);
1103
1104 xs->error = status == ST_OK? XS_NOERROR : XS_DRIVER_STUFFUP;
1105 xs->resid = 0;
1106 xs->flags |= ITSDONE;
1107 scsi_done(xs);
1108 splx(s);
1109 }
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123 int
1124 aac_wait_command(struct aac_command *cm, int timeout)
1125 {
1126 struct aac_softc *sc = cm->cm_sc;
1127 int error = 0;
1128
1129 AAC_DPRINTF(AAC_D_CMD, (": wait for command"));
1130
1131
1132 cm->cm_queue = AAC_ADAP_NORM_CMD_QUEUE;
1133 aac_enqueue_ready(cm);
1134 AAC_DPRINTF(AAC_D_CMD, ("\n"));
1135 aac_startio(sc);
1136 while (!(cm->cm_flags & AAC_CMD_COMPLETED) && (error != EWOULDBLOCK)) {
1137 AAC_DPRINTF(AAC_D_MISC, ("%s: sleeping until command done\n",
1138 sc->aac_dev.dv_xname));
1139 AAC_LOCK_RELEASE(&sc->aac_io_lock);
1140 error = tsleep(cm, PRIBIO, "aacwait", timeout);
1141 AAC_LOCK_ACQUIRE(&sc->aac_io_lock);
1142 }
1143 return (error);
1144 }
1145
1146
1147
1148
1149
1150
1151
1152
1153 int
1154 aac_alloc_command(struct aac_softc *sc, struct aac_command **cmp)
1155 {
1156 struct aac_command *cm;
1157
1158 AAC_DPRINTF(AAC_D_CMD, (": allocate command"));
1159 if ((cm = aac_dequeue_free(sc)) == NULL) {
1160 AAC_DPRINTF(AAC_D_CMD, (" failed"));
1161 return (EBUSY);
1162 }
1163
1164 *cmp = cm;
1165 return(0);
1166 }
1167
1168
1169
1170
1171 void
1172 aac_release_command(struct aac_command *cm)
1173 {
1174 AAC_DPRINTF(AAC_D_CMD, (": release command"));
1175
1176
1177 cm->cm_sgtable = NULL;
1178 cm->cm_flags = 0;
1179 cm->cm_complete = NULL;
1180 cm->cm_private = NULL;
1181 cm->cm_fib->Header.XferState = AAC_FIBSTATE_EMPTY;
1182 cm->cm_fib->Header.StructType = AAC_FIBTYPE_TFIB;
1183 cm->cm_fib->Header.Flags = 0;
1184 cm->cm_fib->Header.SenderSize = sizeof(struct aac_fib);
1185
1186
1187
1188
1189
1190
1191 cm->cm_fib->Header.ReceiverFibAddress = (u_int32_t)cm->cm_fibphys;
1192 cm->cm_fib->Header.SenderData = 0;
1193
1194 aac_enqueue_free(cm);
1195 }
1196
1197
1198
1199
1200 int
1201 aac_alloc_commands(struct aac_softc *sc)
1202 {
1203 struct aac_command *cm;
1204 struct aac_fibmap *fm;
1205 int i, error;
1206
1207 if (sc->total_fibs + AAC_FIB_COUNT > sc->aac_max_fibs)
1208 return (ENOMEM);
1209
1210 fm = malloc(sizeof(struct aac_fibmap), M_DEVBUF, M_NOWAIT);
1211 if (fm == NULL)
1212 goto exit;
1213 bzero(fm, sizeof(struct aac_fibmap));
1214
1215
1216 if (bus_dmamem_alloc(sc->aac_dmat, AAC_FIBMAP_SIZE, PAGE_SIZE, 0,
1217 &fm->aac_seg, 1, &fm->aac_nsegs, BUS_DMA_NOWAIT)) {
1218 printf("%s: can't alloc FIBs\n", sc->aac_dev.dv_xname);
1219 error = ENOBUFS;
1220 goto exit_alloc;
1221 }
1222
1223 if (bus_dmamem_map(sc->aac_dmat, &fm->aac_seg, 1,
1224 AAC_FIBMAP_SIZE, (caddr_t *)&fm->aac_fibs, BUS_DMA_NOWAIT)) {
1225 printf("%s: can't map FIB structure\n", sc->aac_dev.dv_xname);
1226 error = ENOBUFS;
1227 goto exit_map;
1228 }
1229
1230 if (bus_dmamap_create(sc->aac_dmat, AAC_FIBMAP_SIZE, 1,
1231 AAC_FIBMAP_SIZE, 0, BUS_DMA_NOWAIT, &fm->aac_fibmap)) {
1232 printf("%s: can't create dma map\n", sc->aac_dev.dv_xname);
1233 error = ENOBUFS;
1234 goto exit_create;
1235 }
1236
1237 if (bus_dmamap_load(sc->aac_dmat, fm->aac_fibmap, fm->aac_fibs,
1238 AAC_FIBMAP_SIZE, NULL, BUS_DMA_NOWAIT)) {
1239 printf("%s: can't load dma map\n", sc->aac_dev.dv_xname);
1240 error = ENOBUFS;
1241 goto exit_load;
1242 }
1243
1244
1245 AAC_LOCK_ACQUIRE(&sc->aac_io_lock);
1246 bzero(fm->aac_fibs, AAC_FIB_COUNT * sizeof(struct aac_fib));
1247 for (i = 0; i < AAC_FIB_COUNT; i++) {
1248 cm = sc->aac_commands + sc->total_fibs;
1249 fm->aac_commands = cm;
1250 cm->cm_sc = sc;
1251 cm->cm_fib = fm->aac_fibs + i;
1252 cm->cm_fibphys = fm->aac_fibmap->dm_segs[0].ds_addr +
1253 (i * sizeof(struct aac_fib));
1254 cm->cm_index = sc->total_fibs;
1255
1256 if (bus_dmamap_create(sc->aac_dmat, MAXBSIZE, AAC_MAXSGENTRIES,
1257 MAXBSIZE, 0, BUS_DMA_NOWAIT, &cm->cm_datamap)) {
1258 break;
1259 }
1260 aac_release_command(cm);
1261 sc->total_fibs++;
1262 }
1263
1264 if (i > 0) {
1265 TAILQ_INSERT_TAIL(&sc->aac_fibmap_tqh, fm, fm_link);
1266 AAC_DPRINTF(AAC_D_MISC, ("%s: total_fibs= %d\n",
1267 sc->aac_dev.dv_xname,
1268 sc->total_fibs));
1269 AAC_LOCK_RELEASE(&sc->aac_io_lock);
1270 return (0);
1271 }
1272
1273 exit_load:
1274 bus_dmamap_destroy(sc->aac_dmat, fm->aac_fibmap);
1275 exit_create:
1276 bus_dmamem_unmap(sc->aac_dmat, (caddr_t)fm->aac_fibs, AAC_FIBMAP_SIZE);
1277 exit_map:
1278 bus_dmamem_free(sc->aac_dmat, &fm->aac_seg, fm->aac_nsegs);
1279 exit_alloc:
1280 free(fm, M_DEVBUF);
1281 exit:
1282 AAC_LOCK_RELEASE(&sc->aac_io_lock);
1283 return (error);
1284 }
1285
1286
1287
1288
1289 void
1290 aac_free_commands(struct aac_softc *sc)
1291 {
1292 struct aac_fibmap *fm;
1293 struct aac_command *cm;
1294 int i;
1295
1296 while ((fm = TAILQ_FIRST(&sc->aac_fibmap_tqh)) != NULL) {
1297
1298 TAILQ_REMOVE(&sc->aac_fibmap_tqh, fm, fm_link);
1299
1300
1301
1302
1303
1304 for (i = 0; i < AAC_FIB_COUNT && sc->total_fibs--; i++) {
1305 cm = fm->aac_commands + i;
1306 bus_dmamap_destroy(sc->aac_dmat, cm->cm_datamap);
1307 }
1308
1309 bus_dmamap_unload(sc->aac_dmat, fm->aac_fibmap);
1310 bus_dmamap_destroy(sc->aac_dmat, fm->aac_fibmap);
1311 bus_dmamem_unmap(sc->aac_dmat, (caddr_t)fm->aac_fibs,
1312 AAC_FIBMAP_SIZE);
1313 bus_dmamem_free(sc->aac_dmat, &fm->aac_seg, fm->aac_nsegs);
1314 free(fm, M_DEVBUF);
1315 }
1316 }
1317
1318
1319
1320
1321
1322 void
1323 aac_map_command_sg(void *arg, bus_dma_segment_t *segs, int nseg, int error)
1324 {
1325 struct aac_command *cm = arg;
1326 struct aac_softc *sc = cm->cm_sc;
1327 struct aac_fib *fib = cm->cm_fib;
1328 int i;
1329
1330
1331 if (cm->cm_sgtable != NULL) {
1332 if ((cm->cm_sc->flags & AAC_FLAGS_SG_64BIT) == 0) {
1333 struct aac_sg_table *sg = cm->cm_sgtable;
1334 sg->SgCount = nseg;
1335 for (i = 0; i < nseg; i++) {
1336 sg->SgEntry[i].SgAddress = segs[i].ds_addr;
1337 sg->SgEntry[i].SgByteCount = segs[i].ds_len;
1338 }
1339
1340 fib->Header.Size += nseg * sizeof(struct aac_sg_entry);
1341 } else {
1342 struct aac_sg_table64 *sg;
1343 sg = (struct aac_sg_table64 *)cm->cm_sgtable;
1344 sg->SgCount = nseg;
1345 for (i = 0; i < nseg; i++) {
1346 sg->SgEntry64[i].SgAddress = segs[i].ds_addr;
1347 sg->SgEntry64[i].SgByteCount = segs[i].ds_len;
1348 }
1349
1350 fib->Header.Size += nseg*sizeof(struct aac_sg_entry64);
1351 }
1352 }
1353
1354
1355
1356
1357
1358 cm->cm_fib->Header.SenderFibAddress = (cm->cm_index << 1);
1359 cm->cm_fib->Header.ReceiverFibAddress = cm->cm_fibphys;
1360
1361
1362 cm->cm_fib->Header.SenderData = cm->cm_index;
1363
1364 if (cm->cm_flags & AAC_CMD_DATAIN)
1365 bus_dmamap_sync(sc->aac_dmat, cm->cm_datamap, 0,
1366 cm->cm_datamap->dm_mapsize,
1367 BUS_DMASYNC_PREREAD);
1368 if (cm->cm_flags & AAC_CMD_DATAOUT)
1369 bus_dmamap_sync(sc->aac_dmat, cm->cm_datamap, 0,
1370 cm->cm_datamap->dm_mapsize,
1371 BUS_DMASYNC_PREWRITE);
1372 cm->cm_flags |= AAC_CMD_MAPPED;
1373
1374
1375 if (aac_enqueue_fib(sc, cm->cm_queue, cm) == EBUSY) {
1376 aac_remove_busy(cm);
1377 aac_unmap_command(cm);
1378 aac_requeue_ready(cm);
1379 }
1380 }
1381
1382
1383
1384
1385 void
1386 aac_unmap_command(struct aac_command *cm)
1387 {
1388 struct aac_softc *sc = cm->cm_sc;
1389
1390 if (!(cm->cm_flags & AAC_CMD_MAPPED))
1391 return;
1392
1393 if (cm->cm_datalen != 0) {
1394 if (cm->cm_flags & AAC_CMD_DATAIN)
1395 bus_dmamap_sync(sc->aac_dmat, cm->cm_datamap, 0,
1396 cm->cm_datamap->dm_mapsize,
1397 BUS_DMASYNC_POSTREAD);
1398 if (cm->cm_flags & AAC_CMD_DATAOUT)
1399 bus_dmamap_sync(sc->aac_dmat, cm->cm_datamap, 0,
1400 cm->cm_datamap->dm_mapsize,
1401 BUS_DMASYNC_POSTWRITE);
1402
1403 bus_dmamap_unload(sc->aac_dmat, cm->cm_datamap);
1404 }
1405 cm->cm_flags &= ~AAC_CMD_MAPPED;
1406 }
1407
1408
1409
1410
1411
1412
1413
1414
1415 int
1416 aac_check_firmware(struct aac_softc *sc)
1417 {
1418 u_int32_t major, minor, options;
1419
1420
1421
1422
1423
1424 if (sc->flags & AAC_FLAGS_PERC2QC) {
1425 if (aac_sync_command(sc, AAC_MONKER_GETKERNVER, 0, 0, 0, 0,
1426 NULL)) {
1427 printf("%s: Error reading firmware version\n",
1428 sc->aac_dev.dv_xname);
1429 return (EIO);
1430 }
1431
1432
1433 major = (AAC_GET_MAILBOX(sc, 1) & 0xff) - 0x30;
1434 minor = (AAC_GET_MAILBOX(sc, 2) & 0xff) - 0x30;
1435 if (major == 1) {
1436 printf("%s: Firmware version %d.%d is not supported\n",
1437 sc->aac_dev.dv_xname, major, minor);
1438 return (EINVAL);
1439 }
1440 }
1441
1442
1443
1444
1445
1446 if (aac_sync_command(sc, AAC_MONKER_GETINFO, 0, 0, 0, 0, NULL)) {
1447 printf("%s: RequestAdapterInfo failed\n",
1448 sc->aac_dev.dv_xname);
1449 return (EIO);
1450 }
1451 options = AAC_GET_MAILBOX(sc, 1);
1452 sc->supported_options = options;
1453
1454 if ((options & AAC_SUPPORTED_4GB_WINDOW) != 0 &&
1455 (sc->flags & AAC_FLAGS_NO4GB) == 0)
1456 sc->flags |= AAC_FLAGS_4GB_WINDOW;
1457 if (options & AAC_SUPPORTED_NONDASD)
1458 sc->flags |= AAC_FLAGS_ENABLE_CAM;
1459 if ((options & AAC_SUPPORTED_SGMAP_HOST64) != 0
1460 && (sizeof(bus_addr_t) > 4)) {
1461 printf("%s: Enabling 64-bit address support\n",
1462 sc->aac_dev.dv_xname);
1463 sc->flags |= AAC_FLAGS_SG_64BIT;
1464 }
1465
1466
1467 if ((sc->flags & AAC_FLAGS_256FIBS) == 0)
1468 sc->aac_max_fibs = AAC_MAX_FIBS;
1469 else
1470 sc->aac_max_fibs = 256;
1471
1472 return (0);
1473 }
1474
1475 int
1476 aac_init(struct aac_softc *sc)
1477 {
1478 bus_dma_segment_t seg;
1479 int nsegs;
1480 int i, error;
1481 int state = 0;
1482 struct aac_adapter_init *ip;
1483 time_t then;
1484 u_int32_t code, qoffset;
1485
1486
1487
1488
1489 then = time_uptime;
1490 for (i = 0; i < AAC_BOOT_TIMEOUT * 1000; i++) {
1491 code = AAC_GET_FWSTATUS(sc);
1492 if (code & AAC_SELF_TEST_FAILED) {
1493 printf("%s: FATAL: selftest failed\n",
1494 sc->aac_dev.dv_xname);
1495 return (ENXIO);
1496 }
1497 if (code & AAC_KERNEL_PANIC) {
1498 printf("%s: FATAL: controller kernel panic\n",
1499 sc->aac_dev.dv_xname);
1500 return (ENXIO);
1501 }
1502 if (code & AAC_UP_AND_RUNNING)
1503 break;
1504 DELAY(1000);
1505 }
1506 if (i == AAC_BOOT_TIMEOUT * 1000) {
1507 printf("%s: FATAL: controller not coming ready, status %x\n",
1508 sc->aac_dev.dv_xname, code);
1509 return (ENXIO);
1510 }
1511
1512
1513
1514
1515
1516
1517
1518 if (bus_dmamem_alloc(sc->aac_dmat, AAC_COMMON_ALLOCSIZE, PAGE_SIZE, 0,
1519 &seg, 1, &nsegs, BUS_DMA_NOWAIT)) {
1520 printf("%s: can't allocate common structure\n",
1521 sc->aac_dev.dv_xname);
1522 return (ENOMEM);
1523 }
1524 state++;
1525
1526 if (bus_dmamem_map(sc->aac_dmat, &seg, nsegs, AAC_COMMON_ALLOCSIZE,
1527 (caddr_t *)&sc->aac_common, BUS_DMA_NOWAIT)) {
1528 printf("%s: can't map common structure\n",
1529 sc->aac_dev.dv_xname);
1530 error = ENOMEM;
1531 goto bail_out;
1532 }
1533 state++;
1534
1535 if (bus_dmamap_create(sc->aac_dmat, AAC_COMMON_ALLOCSIZE, 1,
1536 AAC_COMMON_ALLOCSIZE, 0, BUS_DMA_NOWAIT, &sc->aac_common_map)) {
1537 printf("%s: can't create dma map\n", sc->aac_dev.dv_xname);
1538 error = ENOBUFS;
1539 goto bail_out;
1540 }
1541 state++;
1542
1543 if (bus_dmamap_load(sc->aac_dmat, sc->aac_common_map, sc->aac_common,
1544 AAC_COMMON_ALLOCSIZE, NULL, BUS_DMA_NOWAIT)) {
1545 printf("%s: can't load dma map\n", sc->aac_dev.dv_xname);
1546 error = ENOBUFS;
1547 goto bail_out;
1548 }
1549 state++;
1550
1551 sc->aac_common_busaddr = sc->aac_common_map->dm_segs[0].ds_addr;
1552
1553 if (sc->aac_common_busaddr < 8192) {
1554 (uint8_t *)sc->aac_common += 8192;
1555 sc->aac_common_busaddr += 8192;
1556 }
1557 bzero(sc->aac_common, sizeof *sc->aac_common);
1558
1559
1560 TAILQ_INIT(&sc->aac_fibmap_tqh);
1561 sc->aac_commands = malloc(AAC_MAX_FIBS * sizeof(struct aac_command),
1562 M_DEVBUF, M_WAITOK);
1563 bzero(sc->aac_commands, AAC_MAX_FIBS * sizeof(struct aac_command));
1564 while (sc->total_fibs < AAC_MAX_FIBS) {
1565 if (aac_alloc_commands(sc) != 0)
1566 break;
1567 }
1568 if (sc->total_fibs == 0)
1569 goto out;
1570
1571
1572
1573
1574
1575 ip = &sc->aac_common->ac_init;
1576 ip->InitStructRevision = AAC_INIT_STRUCT_REVISION;
1577 ip->MiniPortRevision = AAC_INIT_STRUCT_MINIPORT_REVISION;
1578
1579 ip->AdapterFibsPhysicalAddress = sc->aac_common_busaddr +
1580 offsetof(struct aac_common, ac_fibs);
1581 ip->AdapterFibsVirtualAddress = 0;
1582 ip->AdapterFibsSize = AAC_ADAPTER_FIBS * sizeof(struct aac_fib);
1583 ip->AdapterFibAlign = sizeof(struct aac_fib);
1584
1585 ip->PrintfBufferAddress = sc->aac_common_busaddr +
1586 offsetof(struct aac_common, ac_printf);
1587 ip->PrintfBufferSize = AAC_PRINTF_BUFSIZE;
1588
1589
1590
1591
1592
1593
1594
1595 ip->HostPhysMemPages = ctob(physmem) / AAC_PAGE_SIZE;
1596 if (sc->flags & AAC_FLAGS_BROKEN_MEMMAP) {
1597 ip->HostPhysMemPages =
1598 (ip->HostPhysMemPages + AAC_PAGE_SIZE) / AAC_PAGE_SIZE;
1599 }
1600 ip->HostElapsedSeconds = time_uptime;
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618 qoffset = offsetof(struct aac_common, ac_qbuf) + AAC_QUEUE_ALIGN;
1619 qoffset &= ~(AAC_QUEUE_ALIGN - 1);
1620 sc->aac_queues =
1621 (struct aac_queue_table *)((caddr_t)sc->aac_common + qoffset);
1622 ip->CommHeaderAddress = sc->aac_common_busaddr + qoffset;
1623
1624 sc->aac_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][AAC_PRODUCER_INDEX] =
1625 AAC_HOST_NORM_CMD_ENTRIES;
1626 sc->aac_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][AAC_CONSUMER_INDEX] =
1627 AAC_HOST_NORM_CMD_ENTRIES;
1628 sc->aac_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][AAC_PRODUCER_INDEX] =
1629 AAC_HOST_HIGH_CMD_ENTRIES;
1630 sc->aac_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][AAC_CONSUMER_INDEX] =
1631 AAC_HOST_HIGH_CMD_ENTRIES;
1632 sc->aac_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][AAC_PRODUCER_INDEX] =
1633 AAC_ADAP_NORM_CMD_ENTRIES;
1634 sc->aac_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][AAC_CONSUMER_INDEX] =
1635 AAC_ADAP_NORM_CMD_ENTRIES;
1636 sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][AAC_PRODUCER_INDEX] =
1637 AAC_ADAP_HIGH_CMD_ENTRIES;
1638 sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][AAC_CONSUMER_INDEX] =
1639 AAC_ADAP_HIGH_CMD_ENTRIES;
1640 sc->aac_queues->qt_qindex[AAC_HOST_NORM_RESP_QUEUE][AAC_PRODUCER_INDEX]=
1641 AAC_HOST_NORM_RESP_ENTRIES;
1642 sc->aac_queues->qt_qindex[AAC_HOST_NORM_RESP_QUEUE][AAC_CONSUMER_INDEX]=
1643 AAC_HOST_NORM_RESP_ENTRIES;
1644 sc->aac_queues->qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][AAC_PRODUCER_INDEX]=
1645 AAC_HOST_HIGH_RESP_ENTRIES;
1646 sc->aac_queues->qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][AAC_CONSUMER_INDEX]=
1647 AAC_HOST_HIGH_RESP_ENTRIES;
1648 sc->aac_queues->qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][AAC_PRODUCER_INDEX]=
1649 AAC_ADAP_NORM_RESP_ENTRIES;
1650 sc->aac_queues->qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][AAC_CONSUMER_INDEX]=
1651 AAC_ADAP_NORM_RESP_ENTRIES;
1652 sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][AAC_PRODUCER_INDEX]=
1653 AAC_ADAP_HIGH_RESP_ENTRIES;
1654 sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][AAC_CONSUMER_INDEX]=
1655 AAC_ADAP_HIGH_RESP_ENTRIES;
1656 sc->aac_qentries[AAC_HOST_NORM_CMD_QUEUE] =
1657 &sc->aac_queues->qt_HostNormCmdQueue[0];
1658 sc->aac_qentries[AAC_HOST_HIGH_CMD_QUEUE] =
1659 &sc->aac_queues->qt_HostHighCmdQueue[0];
1660 sc->aac_qentries[AAC_ADAP_NORM_CMD_QUEUE] =
1661 &sc->aac_queues->qt_AdapNormCmdQueue[0];
1662 sc->aac_qentries[AAC_ADAP_HIGH_CMD_QUEUE] =
1663 &sc->aac_queues->qt_AdapHighCmdQueue[0];
1664 sc->aac_qentries[AAC_HOST_NORM_RESP_QUEUE] =
1665 &sc->aac_queues->qt_HostNormRespQueue[0];
1666 sc->aac_qentries[AAC_HOST_HIGH_RESP_QUEUE] =
1667 &sc->aac_queues->qt_HostHighRespQueue[0];
1668 sc->aac_qentries[AAC_ADAP_NORM_RESP_QUEUE] =
1669 &sc->aac_queues->qt_AdapNormRespQueue[0];
1670 sc->aac_qentries[AAC_ADAP_HIGH_RESP_QUEUE] =
1671 &sc->aac_queues->qt_AdapHighRespQueue[0];
1672
1673
1674
1675
1676 switch (sc->aac_hwif) {
1677 case AAC_HWIF_I960RX:
1678 AAC_SETREG4(sc, AAC_RX_ODBR, ~0);
1679 break;
1680 case AAC_HWIF_RKT:
1681 AAC_SETREG4(sc, AAC_RKT_ODBR, ~0);
1682 break;
1683 default:
1684 break;
1685 }
1686
1687
1688
1689
1690 if (aac_sync_command(sc, AAC_MONKER_INITSTRUCT,
1691 sc->aac_common_busaddr +
1692 offsetof(struct aac_common, ac_init), 0, 0, 0,
1693 NULL)) {
1694 printf("%s: error establishing init structure\n",
1695 sc->aac_dev.dv_xname);
1696 error = EIO;
1697 goto bail_out;
1698 }
1699
1700 aac_describe_controller(sc);
1701 aac_startup(sc);
1702
1703 return (0);
1704
1705 bail_out:
1706 if (state > 3)
1707 bus_dmamap_unload(sc->aac_dmat, sc->aac_common_map);
1708 if (state > 2)
1709 bus_dmamap_destroy(sc->aac_dmat, sc->aac_common_map);
1710 if (state > 1)
1711 bus_dmamem_unmap(sc->aac_dmat, (caddr_t)sc->aac_common,
1712 sizeof *sc->aac_common);
1713 if (state > 0)
1714 bus_dmamem_free(sc->aac_dmat, &seg, 1);
1715
1716 out:
1717 return (error);
1718 }
1719
1720
1721
1722
1723 int
1724 aac_sync_command(struct aac_softc *sc, u_int32_t command, u_int32_t arg0,
1725 u_int32_t arg1, u_int32_t arg2, u_int32_t arg3, u_int32_t *sp)
1726 {
1727
1728 int i;
1729 u_int32_t status;
1730 u_int16_t reason;
1731
1732
1733 AAC_SET_MAILBOX(sc, command, arg0, arg1, arg2, arg3);
1734
1735
1736 AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND);
1737
1738
1739 AAC_QNOTIFY(sc, AAC_DB_SYNC_COMMAND);
1740
1741 #if 0
1742
1743 then = time_uptime;
1744 do {
1745 if (time_uptime > (then + AAC_IMMEDIATE_TIMEOUT)) {
1746 AAC_DPRINTF(AAC_D_MISC, ("timed out"));
1747 return(EIO);
1748 }
1749 } while (!(AAC_GET_ISTATUS(sc) & AAC_DB_SYNC_COMMAND));
1750 #else
1751 DELAY(AAC_SYNC_DELAY);
1752
1753
1754 for (i = 0; i < AAC_IMMEDIATE_TIMEOUT * 1000; i++) {
1755 reason = AAC_GET_ISTATUS(sc);
1756 if (reason & AAC_DB_SYNC_COMMAND)
1757 break;
1758 reason = AAC_GET_ISTATUS(sc);
1759 if (reason & AAC_DB_SYNC_COMMAND)
1760 break;
1761 reason = AAC_GET_ISTATUS(sc);
1762 if (reason & AAC_DB_SYNC_COMMAND)
1763 break;
1764 DELAY(1000);
1765 }
1766 if (i == AAC_IMMEDIATE_TIMEOUT * 1000) {
1767 printf("aac_sync_command: failed, reason=%#x\n", reason);
1768 return (EIO);
1769 }
1770 #endif
1771
1772
1773 AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND);
1774
1775
1776 status = AAC_GET_MAILBOX(sc, 0);
1777
1778 if (sp != NULL)
1779 *sp = status;
1780
1781 return(0);
1782 }
1783
1784
1785
1786
1787 int
1788 aac_alloc_sync_fib(struct aac_softc *sc, struct aac_fib **fib, int flags)
1789 {
1790
1791
1792
1793
1794
1795 if (!(flags & AAC_SYNC_LOCK_FORCE))
1796 AAC_LOCK_ACQUIRE(&sc->aac_sync_lock);
1797
1798 *fib = &sc->aac_common->ac_sync_fib;
1799
1800 return (1);
1801 }
1802
1803
1804
1805
1806 void
1807 aac_release_sync_fib(struct aac_softc *sc)
1808 {
1809 AAC_LOCK_RELEASE(&sc->aac_sync_lock);
1810 }
1811
1812
1813
1814
1815 int
1816 aac_sync_fib(struct aac_softc *sc, u_int32_t command, u_int32_t xferstate,
1817 struct aac_fib *fib, u_int16_t datasize)
1818 {
1819
1820 if (datasize > AAC_FIB_DATASIZE) {
1821 printf("aac_sync_fib 1: datasize=%d AAC_FIB_DATASIZE %lu\n",
1822 datasize, AAC_FIB_DATASIZE);
1823 return(EINVAL);
1824 }
1825
1826
1827
1828
1829 fib->Header.XferState = AAC_FIBSTATE_HOSTOWNED |
1830 AAC_FIBSTATE_INITIALISED |
1831 AAC_FIBSTATE_EMPTY;
1832 fib->Header.XferState |= xferstate;
1833 fib->Header.Command = command;
1834 fib->Header.StructType = AAC_FIBTYPE_TFIB;
1835 fib->Header.Size = sizeof(struct aac_fib) + datasize;
1836 fib->Header.SenderSize = sizeof(struct aac_fib);
1837 fib->Header.SenderFibAddress = 0;
1838 fib->Header.ReceiverFibAddress = sc->aac_common_busaddr +
1839 offsetof(struct aac_common,
1840 ac_sync_fib);
1841
1842
1843
1844
1845 if (aac_sync_command(sc, AAC_MONKER_SYNCFIB,
1846 fib->Header.ReceiverFibAddress, 0, 0, 0, NULL)) {
1847 AAC_DPRINTF(AAC_D_IO, ("%s: aac_sync_fib: IO error\n",
1848 sc->aac_dev.dv_xname));
1849 printf("aac_sync_fib 2\n");
1850 return(EIO);
1851 }
1852
1853 return (0);
1854 }
1855
1856
1857
1858
1859
1860
1861
1862 static struct {
1863 int size;
1864 int notify;
1865 } aac_qinfo[] = {
1866 { AAC_HOST_NORM_CMD_ENTRIES, AAC_DB_COMMAND_NOT_FULL },
1867 { AAC_HOST_HIGH_CMD_ENTRIES, 0 },
1868 { AAC_ADAP_NORM_CMD_ENTRIES, AAC_DB_COMMAND_READY },
1869 { AAC_ADAP_HIGH_CMD_ENTRIES, 0 },
1870 { AAC_HOST_NORM_RESP_ENTRIES, AAC_DB_RESPONSE_NOT_FULL },
1871 { AAC_HOST_HIGH_RESP_ENTRIES, 0 },
1872 { AAC_ADAP_NORM_RESP_ENTRIES, AAC_DB_RESPONSE_READY },
1873 { AAC_ADAP_HIGH_RESP_ENTRIES, 0 }
1874 };
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885 int
1886 aac_enqueue_fib(struct aac_softc *sc, int queue, struct aac_command *cm)
1887 {
1888 u_int32_t pi, ci;
1889 int error;
1890 u_int32_t fib_size;
1891 u_int32_t fib_addr;
1892
1893 fib_size = cm->cm_fib->Header.Size;
1894 fib_addr = cm->cm_fib->Header.ReceiverFibAddress;
1895
1896
1897 pi = sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX];
1898 ci = sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX];
1899
1900
1901 if (pi >= aac_qinfo[queue].size)
1902 pi = 0;
1903
1904
1905 if ((pi + 1) == ci) {
1906 error = EBUSY;
1907 goto out;
1908 }
1909
1910
1911 (sc->aac_qentries[queue] + pi)->aq_fib_size = fib_size;
1912 (sc->aac_qentries[queue] + pi)->aq_fib_addr = fib_addr;
1913
1914
1915 sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX] = pi + 1;
1916
1917
1918
1919
1920
1921 aac_enqueue_busy(cm);
1922
1923
1924 if (aac_qinfo[queue].notify != 0)
1925 AAC_QNOTIFY(sc, aac_qinfo[queue].notify);
1926
1927 error = 0;
1928
1929 out:
1930 return (error);
1931 }
1932
1933
1934
1935
1936
1937 int
1938 aac_dequeue_fib(struct aac_softc *sc, int queue, u_int32_t *fib_size,
1939 struct aac_fib **fib_addr)
1940 {
1941 u_int32_t pi, ci;
1942 u_int32_t fib_index;
1943 int notify;
1944 int error;
1945
1946
1947 pi = sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX];
1948 ci = sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX];
1949
1950
1951 if (ci == pi) {
1952 error = ENOENT;
1953 goto out;
1954 }
1955
1956
1957 if (pi >= aac_qinfo[queue].size)
1958 pi = 0;
1959
1960 notify = 0;
1961 if (ci == pi + 1)
1962 notify++;
1963
1964
1965 if (ci >= aac_qinfo[queue].size)
1966 ci = 0;
1967
1968
1969 *fib_size = (sc->aac_qentries[queue] + ci)->aq_fib_size;
1970
1971 switch (queue) {
1972 case AAC_HOST_NORM_CMD_QUEUE:
1973 case AAC_HOST_HIGH_CMD_QUEUE:
1974
1975
1976
1977
1978
1979
1980 fib_index = (sc->aac_qentries[queue] + ci)->aq_fib_addr /
1981 sizeof(struct aac_fib);
1982 *fib_addr = &sc->aac_common->ac_fibs[fib_index];
1983 break;
1984
1985 case AAC_HOST_NORM_RESP_QUEUE:
1986 case AAC_HOST_HIGH_RESP_QUEUE:
1987 {
1988 struct aac_command *cm;
1989
1990
1991
1992
1993
1994
1995
1996
1997 fib_index = (sc->aac_qentries[queue] + ci)->aq_fib_addr;
1998 cm = sc->aac_commands + (fib_index >> 1);
1999 *fib_addr = cm->cm_fib;
2000
2001
2002
2003
2004
2005 if (fib_index & 0x01) {
2006 (*fib_addr)->Header.XferState |= AAC_FIBSTATE_DONEADAP;
2007 *((u_int32_t*)((*fib_addr)->data)) = AAC_ERROR_NORMAL;
2008 }
2009 break;
2010 }
2011 default:
2012 panic("Invalid queue in aac_dequeue_fib()");
2013 break;
2014 }
2015
2016
2017
2018 sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX] = ci + 1;
2019
2020
2021 if (notify && (aac_qinfo[queue].notify != 0))
2022 AAC_QNOTIFY(sc, aac_qinfo[queue].notify);
2023 error = 0;
2024
2025 out:
2026 return (error);
2027 }
2028
2029
2030
2031
2032 int
2033 aac_enqueue_response(struct aac_softc *sc, int queue, struct aac_fib *fib)
2034 {
2035 u_int32_t pi, ci;
2036 int error;
2037 u_int32_t fib_size;
2038 u_int32_t fib_addr;
2039
2040
2041 fib_size = fib->Header.Size;
2042 fib_addr = fib->Header.SenderFibAddress;
2043 fib->Header.ReceiverFibAddress = fib_addr;
2044
2045
2046 pi = sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX];
2047 ci = sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX];
2048
2049
2050 if (pi >= aac_qinfo[queue].size)
2051 pi = 0;
2052
2053
2054 if ((pi + 1) == ci) {
2055 error = EBUSY;
2056 goto out;
2057 }
2058
2059
2060 (sc->aac_qentries[queue] + pi)->aq_fib_size = fib_size;
2061 (sc->aac_qentries[queue] + pi)->aq_fib_addr = fib_addr;
2062
2063
2064 sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX] = pi + 1;
2065
2066
2067 if (aac_qinfo[queue].notify != 0)
2068 AAC_QNOTIFY(sc, aac_qinfo[queue].notify);
2069
2070 error = 0;
2071
2072 out:
2073 return(error);
2074 }
2075
2076 void
2077 aac_command_timeout(struct aac_command *cm)
2078 {
2079 struct aac_softc *sc = cm->cm_sc;
2080
2081 printf("%s: COMMAND %p (flags=%#x) TIMEOUT AFTER %d SECONDS\n",
2082 sc->aac_dev.dv_xname, cm, cm->cm_flags,
2083 (int)(time_uptime - cm->cm_timestamp));
2084
2085 if (cm->cm_flags & AAC_CMD_TIMEDOUT)
2086 return;
2087
2088 cm->cm_flags |= AAC_CMD_TIMEDOUT;
2089
2090 AAC_PRINT_FIB(sc, cm->cm_fib);
2091
2092 if (cm->cm_flags & AAC_ON_AACQ_BIO) {
2093 struct scsi_xfer *xs = cm->cm_private;
2094 int s = splbio();
2095 xs->error = XS_DRIVER_STUFFUP;
2096 xs->flags |= ITSDONE;
2097 scsi_done(xs);
2098 splx(s);
2099
2100 aac_remove_bio(cm);
2101 aac_unmap_command(cm);
2102 }
2103 }
2104
2105 void
2106 aac_timeout(struct aac_softc *sc)
2107 {
2108 struct aac_command *cm;
2109 time_t deadline;
2110
2111
2112
2113
2114
2115 deadline = time_uptime - AAC_CMD_TIMEOUT;
2116 TAILQ_FOREACH(cm, &sc->aac_busy, cm_link) {
2117 if (cm->cm_timestamp < deadline)
2118 aac_command_timeout(cm);
2119 }
2120 }
2121
2122
2123
2124
2125
2126
2127
2128
2129 int
2130 aac_sa_get_fwstatus(struct aac_softc *sc)
2131 {
2132 return (AAC_GETREG4(sc, AAC_SA_FWSTATUS));
2133 }
2134
2135 int
2136 aac_rx_get_fwstatus(struct aac_softc *sc)
2137 {
2138 return (AAC_GETREG4(sc, AAC_RX_FWSTATUS));
2139 }
2140
2141 int
2142 aac_fa_get_fwstatus(struct aac_softc *sc)
2143 {
2144 return (AAC_GETREG4(sc, AAC_FA_FWSTATUS));
2145 }
2146
2147 int
2148 aac_rkt_get_fwstatus(struct aac_softc *sc)
2149 {
2150 return(AAC_GETREG4(sc, AAC_RKT_FWSTATUS));
2151 }
2152
2153
2154
2155
2156
2157 void
2158 aac_sa_qnotify(struct aac_softc *sc, int qbit)
2159 {
2160 AAC_SETREG2(sc, AAC_SA_DOORBELL1_SET, qbit);
2161 }
2162
2163 void
2164 aac_rx_qnotify(struct aac_softc *sc, int qbit)
2165 {
2166 AAC_SETREG4(sc, AAC_RX_IDBR, qbit);
2167 }
2168
2169 void
2170 aac_fa_qnotify(struct aac_softc *sc, int qbit)
2171 {
2172 AAC_SETREG2(sc, AAC_FA_DOORBELL1, qbit);
2173 AAC_FA_HACK(sc);
2174 }
2175
2176 void
2177 aac_rkt_qnotify(struct aac_softc *sc, int qbit)
2178 {
2179 AAC_SETREG4(sc, AAC_RKT_IDBR, qbit);
2180 }
2181
2182
2183
2184
2185 int
2186 aac_sa_get_istatus(struct aac_softc *sc)
2187 {
2188 return (AAC_GETREG2(sc, AAC_SA_DOORBELL0));
2189 }
2190
2191 int
2192 aac_rx_get_istatus(struct aac_softc *sc)
2193 {
2194 return (AAC_GETREG4(sc, AAC_RX_ODBR));
2195 }
2196
2197 int
2198 aac_fa_get_istatus(struct aac_softc *sc)
2199 {
2200 return (AAC_GETREG2(sc, AAC_FA_DOORBELL0));
2201 }
2202
2203 int
2204 aac_rkt_get_istatus(struct aac_softc *sc)
2205 {
2206 return(AAC_GETREG4(sc, AAC_RKT_ODBR));
2207 }
2208
2209
2210
2211
2212 void
2213 aac_sa_clear_istatus(struct aac_softc *sc, int mask)
2214 {
2215 AAC_SETREG2(sc, AAC_SA_DOORBELL0_CLEAR, mask);
2216 }
2217
2218 void
2219 aac_rx_clear_istatus(struct aac_softc *sc, int mask)
2220 {
2221 AAC_SETREG4(sc, AAC_RX_ODBR, mask);
2222 }
2223
2224 void
2225 aac_fa_clear_istatus(struct aac_softc *sc, int mask)
2226 {
2227 AAC_SETREG2(sc, AAC_FA_DOORBELL0_CLEAR, mask);
2228 AAC_FA_HACK(sc);
2229 }
2230
2231 void
2232 aac_rkt_clear_istatus(struct aac_softc *sc, int mask)
2233 {
2234 AAC_SETREG4(sc, AAC_RKT_ODBR, mask);
2235 }
2236
2237
2238
2239
2240 void
2241 aac_sa_set_mailbox(struct aac_softc *sc, u_int32_t command, u_int32_t arg0,
2242 u_int32_t arg1, u_int32_t arg2, u_int32_t arg3)
2243 {
2244 AAC_SETREG4(sc, AAC_SA_MAILBOX, command);
2245 AAC_SETREG4(sc, AAC_SA_MAILBOX + 4, arg0);
2246 AAC_SETREG4(sc, AAC_SA_MAILBOX + 8, arg1);
2247 AAC_SETREG4(sc, AAC_SA_MAILBOX + 12, arg2);
2248 AAC_SETREG4(sc, AAC_SA_MAILBOX + 16, arg3);
2249 }
2250
2251 void
2252 aac_rx_set_mailbox(struct aac_softc *sc, u_int32_t command, u_int32_t arg0,
2253 u_int32_t arg1, u_int32_t arg2, u_int32_t arg3)
2254 {
2255 AAC_SETREG4(sc, AAC_RX_MAILBOX, command);
2256 AAC_SETREG4(sc, AAC_RX_MAILBOX + 4, arg0);
2257 AAC_SETREG4(sc, AAC_RX_MAILBOX + 8, arg1);
2258 AAC_SETREG4(sc, AAC_RX_MAILBOX + 12, arg2);
2259 AAC_SETREG4(sc, AAC_RX_MAILBOX + 16, arg3);
2260 }
2261
2262 void
2263 aac_fa_set_mailbox(struct aac_softc *sc, u_int32_t command, u_int32_t arg0,
2264 u_int32_t arg1, u_int32_t arg2, u_int32_t arg3)
2265 {
2266 AAC_SETREG4(sc, AAC_FA_MAILBOX, command);
2267 AAC_FA_HACK(sc);
2268 AAC_SETREG4(sc, AAC_FA_MAILBOX + 4, arg0);
2269 AAC_FA_HACK(sc);
2270 AAC_SETREG4(sc, AAC_FA_MAILBOX + 8, arg1);
2271 AAC_FA_HACK(sc);
2272 AAC_SETREG4(sc, AAC_FA_MAILBOX + 12, arg2);
2273 AAC_FA_HACK(sc);
2274 AAC_SETREG4(sc, AAC_FA_MAILBOX + 16, arg3);
2275 AAC_FA_HACK(sc);
2276 }
2277
2278 void
2279 aac_rkt_set_mailbox(struct aac_softc *sc, u_int32_t command, u_int32_t arg0,
2280 u_int32_t arg1, u_int32_t arg2, u_int32_t arg3)
2281 {
2282 AAC_SETREG4(sc, AAC_RKT_MAILBOX, command);
2283 AAC_SETREG4(sc, AAC_RKT_MAILBOX + 4, arg0);
2284 AAC_SETREG4(sc, AAC_RKT_MAILBOX + 8, arg1);
2285 AAC_SETREG4(sc, AAC_RKT_MAILBOX + 12, arg2);
2286 AAC_SETREG4(sc, AAC_RKT_MAILBOX + 16, arg3);
2287 }
2288
2289
2290
2291
2292 int
2293 aac_sa_get_mailbox(struct aac_softc *sc, int mb)
2294 {
2295 return (AAC_GETREG4(sc, AAC_SA_MAILBOX + (mb * 4)));
2296 }
2297
2298 int
2299 aac_rx_get_mailbox(struct aac_softc *sc, int mb)
2300 {
2301 return (AAC_GETREG4(sc, AAC_RX_MAILBOX + (mb * 4)));
2302 }
2303
2304 int
2305 aac_fa_get_mailbox(struct aac_softc *sc, int mb)
2306 {
2307 return (AAC_GETREG4(sc, AAC_FA_MAILBOX + (mb * 4)));
2308 }
2309
2310 int
2311 aac_rkt_get_mailbox(struct aac_softc *sc, int mb)
2312 {
2313 return(AAC_GETREG4(sc, AAC_RKT_MAILBOX + (mb * 4)));
2314 }
2315
2316
2317
2318
2319 void
2320 aac_sa_set_interrupts(struct aac_softc *sc, int enable)
2321 {
2322 AAC_DPRINTF(AAC_D_INTR, ("%s: %sable interrupts\n",
2323 sc->aac_dev.dv_xname, enable ? "en" : "dis"));
2324
2325 if (enable)
2326 AAC_SETREG2((sc), AAC_SA_MASK0_CLEAR, AAC_DB_INTERRUPTS);
2327 else
2328 AAC_SETREG2((sc), AAC_SA_MASK0_SET, ~0);
2329 }
2330
2331 void
2332 aac_rx_set_interrupts(struct aac_softc *sc, int enable)
2333 {
2334 AAC_DPRINTF(AAC_D_INTR, ("%s: %sable interrupts",
2335 sc->aac_dev.dv_xname, enable ? "en" : "dis"));
2336
2337 if (enable)
2338 AAC_SETREG4(sc, AAC_RX_OIMR, ~AAC_DB_INTERRUPTS);
2339 else
2340 AAC_SETREG4(sc, AAC_RX_OIMR, ~0);
2341 }
2342
2343 void
2344 aac_fa_set_interrupts(struct aac_softc *sc, int enable)
2345 {
2346 AAC_DPRINTF(AAC_D_INTR, ("%s: %sable interrupts",
2347 sc->aac_dev.dv_xname, enable ? "en" : "dis"));
2348
2349 if (enable) {
2350 AAC_SETREG2((sc), AAC_FA_MASK0_CLEAR, AAC_DB_INTERRUPTS);
2351 AAC_FA_HACK(sc);
2352 } else {
2353 AAC_SETREG2((sc), AAC_FA_MASK0, ~0);
2354 AAC_FA_HACK(sc);
2355 }
2356 }
2357
2358 void
2359 aac_rkt_set_interrupts(struct aac_softc *sc, int enable)
2360 {
2361 AAC_DPRINTF(AAC_D_INTR, ("%s: %sable interrupts",
2362 sc->aac_dev.dv_xname, enable ? "en" : "dis"));
2363
2364 if (enable)
2365 AAC_SETREG4(sc, AAC_RKT_OIMR, ~AAC_DB_INTERRUPTS);
2366 else
2367 AAC_SETREG4(sc, AAC_RKT_OIMR, ~0);
2368 }
2369
2370 void
2371 aac_eval_mapping(size, cyls, heads, secs)
2372 u_int32_t size;
2373 int *cyls, *heads, *secs;
2374 {
2375 *cyls = size / AAC_HEADS / AAC_SECS;
2376 if (*cyls < AAC_MAXCYLS) {
2377 *heads = AAC_HEADS;
2378 *secs = AAC_SECS;
2379 } else {
2380
2381 *cyls = size / AAC_MEDHEADS / AAC_MEDSECS;
2382 if (*cyls < AAC_MAXCYLS) {
2383 *heads = AAC_MEDHEADS;
2384 *secs = AAC_MEDSECS;
2385 } else {
2386
2387 *cyls = size / AAC_BIGHEADS / AAC_BIGSECS;
2388 *heads = AAC_BIGHEADS;
2389 *secs = AAC_BIGSECS;
2390 }
2391 }
2392 }
2393
2394 void
2395 aac_copy_internal_data(struct scsi_xfer *xs, u_int8_t *data, size_t size)
2396 {
2397 struct aac_softc *sc = xs->sc_link->adapter_softc;
2398 size_t copy_cnt;
2399
2400 AAC_DPRINTF(AAC_D_MISC, ("%s: aac_copy_internal_data\n",
2401 sc->aac_dev.dv_xname));
2402
2403 if (!xs->datalen)
2404 printf("%s: uio move not yet supported\n",
2405 sc->aac_dev.dv_xname);
2406 else {
2407 copy_cnt = MIN(size, xs->datalen);
2408 bcopy(data, xs->data, copy_cnt);
2409 }
2410 }
2411
2412
2413 void
2414 aac_internal_cache_cmd(struct scsi_xfer *xs)
2415 {
2416 struct scsi_link *link = xs->sc_link;
2417 struct aac_softc *sc = link->adapter_softc;
2418 struct scsi_inquiry_data inq;
2419 struct scsi_sense_data sd;
2420 struct scsi_read_cap_data rcd;
2421 u_int8_t target = link->target;
2422
2423 AAC_DPRINTF(AAC_D_CMD, ("aac_internal_cache_cmd: ",
2424 sc->aac_dev.dv_xname));
2425
2426 switch (xs->cmd->opcode) {
2427 case TEST_UNIT_READY:
2428 case START_STOP:
2429 #if 0
2430 case VERIFY:
2431 #endif
2432 AAC_DPRINTF(AAC_D_CMD, ("opc %#x tgt %d ", xs->cmd->opcode,
2433 target));
2434 break;
2435
2436 case REQUEST_SENSE:
2437 AAC_DPRINTF(AAC_D_CMD, ("REQUEST SENSE tgt %d ", target));
2438 bzero(&sd, sizeof sd);
2439 sd.error_code = 0x70;
2440 sd.segment = 0;
2441 sd.flags = SKEY_NO_SENSE;
2442 aac_enc32(sd.info, 0);
2443 sd.extra_len = 0;
2444 aac_copy_internal_data(xs, (u_int8_t *)&sd, sizeof sd);
2445 break;
2446
2447 case INQUIRY:
2448 AAC_DPRINTF(AAC_D_CMD, ("INQUIRY tgt %d devtype %x ", target,
2449 sc->aac_hdr[target].hd_devtype));
2450 bzero(&inq, sizeof inq);
2451
2452 inq.device = T_DIRECT;
2453 inq.dev_qual2 = 0;
2454 inq.version = 2;
2455 inq.response_format = 2;
2456 inq.additional_length = 32;
2457 strlcpy(inq.vendor, "Adaptec", sizeof inq.vendor);
2458 snprintf(inq.product, sizeof inq.product, "Container #%02d",
2459 target);
2460 strlcpy(inq.revision, " ", sizeof inq.revision);
2461 aac_copy_internal_data(xs, (u_int8_t *)&inq, sizeof inq);
2462 break;
2463
2464 case READ_CAPACITY:
2465 AAC_DPRINTF(AAC_D_CMD, ("READ CAPACITY tgt %d ", target));
2466 bzero(&rcd, sizeof rcd);
2467 _lto4b(sc->aac_hdr[target].hd_size - 1, rcd.addr);
2468 _lto4b(AAC_BLOCK_SIZE, rcd.length);
2469 aac_copy_internal_data(xs, (u_int8_t *)&rcd, sizeof rcd);
2470 break;
2471
2472 default:
2473 AAC_DPRINTF(AAC_D_CMD, ("\n"));
2474 printf("aac_internal_cache_cmd got bad opcode: %#x\n",
2475 xs->cmd->opcode);
2476 xs->error = XS_DRIVER_STUFFUP;
2477 return;
2478 }
2479
2480 xs->error = XS_NOERROR;
2481 }
2482
2483 void
2484 aacminphys(struct buf *bp)
2485 {
2486 #if 0
2487 u_int8_t *buf = bp->b_data;
2488 paddr_t pa;
2489 long off;
2490 #endif
2491
2492 AAC_DPRINTF(AAC_D_MISC, ("aacminphys(0x%x)\n", bp));
2493
2494 #if 0
2495 if (bp->b_bcount > ((AAC_MAXOFFSETS - 1) * PAGE_SIZE))
2496 bp->b_bcount = ((AAC_MAXOFFSETS - 1) * PAGE_SIZE);
2497 #endif
2498
2499 #if 0
2500 for (off = PAGE_SIZE, pa = vtophys(buf); off < bp->b_bcount;
2501 off += PAGE_SIZE)
2502 if (pa + off != vtophys(buf + off)) {
2503 bp->b_bcount = off;
2504 break;
2505 }
2506 #endif
2507 minphys(bp);
2508 }
2509
2510 int
2511 aac_raw_scsi_cmd(struct scsi_xfer *xs)
2512 {
2513 #ifdef AAC_DEBUG
2514 struct aac_softc *sc = xs->sc_link->adapter_softc;
2515 #endif
2516 AAC_DPRINTF(AAC_D_CMD, ("%s: aac_raw_scsi_cmd\n",
2517 sc->aac_dev.dv_xname));
2518
2519
2520 xs->error = XS_DRIVER_STUFFUP;
2521 return (COMPLETE);
2522 }
2523
2524 int
2525 aac_scsi_cmd(struct scsi_xfer *xs)
2526 {
2527 struct scsi_link *link = xs->sc_link;
2528 struct aac_softc *sc = link->adapter_softc;
2529 u_int8_t target = link->target;
2530 struct aac_command *cm;
2531 u_int32_t blockno, blockcnt;
2532 struct scsi_rw *rw;
2533 struct scsi_rw_big *rwb;
2534 int retval = SUCCESSFULLY_QUEUED;
2535 int s = splbio();
2536
2537 xs->error = XS_NOERROR;
2538
2539 if (target >= AAC_MAX_CONTAINERS || !sc->aac_hdr[target].hd_present ||
2540 link->lun != 0) {
2541
2542
2543
2544
2545 xs->error = XS_DRIVER_STUFFUP;
2546 xs->flags |= ITSDONE;
2547 scsi_done(xs);
2548 splx(s);
2549 return (COMPLETE);
2550 }
2551
2552 AAC_DPRINTF(AAC_D_CMD, ("%s: aac_scsi_cmd: ", sc->aac_dev.dv_xname));
2553
2554 xs->error = XS_NOERROR;
2555 cm = NULL;
2556 link = xs->sc_link;
2557 target = link->target;
2558
2559 switch (xs->cmd->opcode) {
2560 case TEST_UNIT_READY:
2561 case REQUEST_SENSE:
2562 case INQUIRY:
2563 case START_STOP:
2564 case READ_CAPACITY:
2565 #if 0
2566 case VERIFY:
2567 #endif
2568 aac_internal_cache_cmd(xs);
2569 xs->flags |= ITSDONE;
2570 scsi_done(xs);
2571 goto ready;
2572
2573 case PREVENT_ALLOW:
2574 AAC_DPRINTF(AAC_D_CMD, ("PREVENT/ALLOW "));
2575
2576 xs->error = XS_NOERROR;
2577 xs->flags |= ITSDONE;
2578 scsi_done(xs);
2579 goto ready;
2580
2581 case SYNCHRONIZE_CACHE:
2582 AAC_DPRINTF(AAC_D_CMD, ("SYNCHRONIZE_CACHE "));
2583
2584 xs->error = XS_NOERROR;
2585 xs->flags |= ITSDONE;
2586 scsi_done(xs);
2587 goto ready;
2588
2589 default:
2590 AAC_DPRINTF(AAC_D_CMD, ("unknown opc %#x ", xs->cmd->opcode));
2591
2592 xs->error = XS_DRIVER_STUFFUP;
2593 xs->flags |= ITSDONE;
2594 scsi_done(xs);
2595 goto ready;
2596
2597 case READ_COMMAND:
2598 case READ_BIG:
2599 case WRITE_COMMAND:
2600 case WRITE_BIG:
2601 AAC_DPRINTF(AAC_D_CMD, ("rw opc %#x ", xs->cmd->opcode));
2602
2603
2604 if (xs->cmdlen == 6) {
2605 rw = (struct scsi_rw *)xs->cmd;
2606 blockno = _3btol(rw->addr) &
2607 (SRW_TOPADDR << 16 | 0xffff);
2608 blockcnt = rw->length ? rw->length : 0x100;
2609 } else {
2610 rwb = (struct scsi_rw_big *)xs->cmd;
2611 blockno = _4btol(rwb->addr);
2612 blockcnt = _2btol(rwb->length);
2613 }
2614
2615 AAC_DPRINTF(AAC_D_CMD, ("blkno=%d bcount=%d ",
2616 xs->cmd->opcode, blockno, blockcnt));
2617
2618 if (blockno >= sc->aac_hdr[target].hd_size ||
2619 blockno + blockcnt > sc->aac_hdr[target].hd_size) {
2620 AAC_DPRINTF(AAC_D_CMD, ("\n"));
2621 printf("%s: out of bounds %u-%u >= %u\n",
2622 sc->aac_dev.dv_xname, blockno,
2623 blockcnt, sc->aac_hdr[target].hd_size);
2624
2625
2626
2627
2628
2629 xs->error = XS_DRIVER_STUFFUP;
2630 xs->flags |= ITSDONE;
2631 scsi_done(xs);
2632 goto ready;
2633 }
2634
2635 if (aac_alloc_command(sc, &cm)) {
2636 AAC_DPRINTF(AAC_D_CMD,
2637 (": out of commands, try later\n"));
2638
2639
2640
2641
2642 splx(s);
2643 return (TRY_AGAIN_LATER);
2644 }
2645
2646
2647 cm->cm_data = (void *)xs->data;
2648 cm->cm_datalen = xs->datalen;
2649 cm->cm_complete = aac_bio_complete;
2650 cm->cm_private = xs;
2651 cm->cm_timestamp = time_uptime;
2652 cm->cm_queue = AAC_ADAP_NORM_CMD_QUEUE;
2653 cm->cm_blkno = blockno;
2654 cm->cm_bcount = blockcnt;
2655
2656 AAC_DPRINTF(AAC_D_CMD, ("\n"));
2657 aac_enqueue_bio(cm);
2658 aac_startio(sc);
2659
2660
2661 if (xs->flags & SCSI_POLL) {
2662 if (!aac_wait_command(cm, xs->timeout))
2663 {
2664 printf("%s: command timed out\n",
2665 sc->aac_dev.dv_xname);
2666 splx(s);
2667 return (TRY_AGAIN_LATER);
2668 }
2669 xs->flags |= ITSDONE;
2670 scsi_done(xs);
2671 }
2672 }
2673
2674 ready:
2675
2676
2677
2678 if (xs->flags & SCSI_POLL)
2679 retval = COMPLETE;
2680
2681 splx(s);
2682 AAC_DPRINTF(AAC_D_CMD, ("%s: scsi_cmd complete\n",
2683 sc->aac_dev.dv_xname));
2684 return (retval);
2685 }
2686
2687
2688
2689
2690
2691
2692
2693
2694 void
2695 aac_describe_controller(struct aac_softc *sc)
2696 {
2697 struct aac_fib *fib;
2698 struct aac_adapter_info *info;
2699
2700 aac_alloc_sync_fib(sc, &fib, 0);
2701
2702 fib->data[0] = 0;
2703 if (aac_sync_fib(sc, RequestAdapterInfo, 0, fib, 1)) {
2704 printf("%s: RequestAdapterInfo failed 2\n",
2705 sc->aac_dev.dv_xname);
2706 aac_release_sync_fib(sc);
2707 return;
2708 }
2709 info = (struct aac_adapter_info *)&fib->data[0];
2710
2711 printf("%s: %s %dMHz, %dMB cache memory, %s\n", sc->aac_dev.dv_xname,
2712 aac_describe_code(aac_cpu_variant, info->CpuVariant),
2713 info->ClockSpeed, info->BufferMem / (1024 * 1024),
2714 aac_describe_code(aac_battery_platform, info->batteryPlatform));
2715
2716
2717 sc->aac_revision = info->KernelRevision;
2718 printf("%s: Kernel %d.%d-%d, Build %d, S/N %6X\n",
2719 sc->aac_dev.dv_xname,
2720 info->KernelRevision.external.comp.major,
2721 info->KernelRevision.external.comp.minor,
2722 info->KernelRevision.external.comp.dash,
2723 info->KernelRevision.buildNumber,
2724 (u_int32_t)(info->SerialNumber & 0xffffff));
2725
2726 aac_release_sync_fib(sc);
2727
2728 #if 0
2729 if (1 || bootverbose) {
2730 device_printf(sc->aac_dev, "Supported Options=%b\n",
2731 sc->supported_options,
2732 "\20"
2733 "\1SNAPSHOT"
2734 "\2CLUSTERS"
2735 "\3WCACHE"
2736 "\4DATA64"
2737 "\5HOSTTIME"
2738 "\6RAID50"
2739 "\7WINDOW4GB"
2740 "\10SCSIUPGD"
2741 "\11SOFTERR"
2742 "\12NORECOND"
2743 "\13SGMAP64"
2744 "\14ALARM"
2745 "\15NONDASD");
2746 }
2747 #endif
2748 }
2749
2750
2751
2752
2753
2754 char *
2755 aac_describe_code(struct aac_code_lookup *table, u_int32_t code)
2756 {
2757 int i;
2758
2759 for (i = 0; table[i].string != NULL; i++)
2760 if (table[i].code == code)
2761 return(table[i].string);
2762 return(table[i + 1].string);
2763 }
2764
2765 #ifdef AAC_DEBUG
2766
2767
2768
2769 void
2770 aac_print_fib(struct aac_softc *sc, struct aac_fib *fib, const char *caller)
2771 {
2772 printf("%s: FIB @ %p\n", caller, fib);
2773 printf(" XferState %b\n", fib->Header.XferState, "\20"
2774 "\1HOSTOWNED"
2775 "\2ADAPTEROWNED"
2776 "\3INITIALISED"
2777 "\4EMPTY"
2778 "\5FROMPOOL"
2779 "\6FROMHOST"
2780 "\7FROMADAP"
2781 "\10REXPECTED"
2782 "\11RNOTEXPECTED"
2783 "\12DONEADAP"
2784 "\13DONEHOST"
2785 "\14HIGH"
2786 "\15NORM"
2787 "\16ASYNC"
2788 "\17PAGEFILEIO"
2789 "\20SHUTDOWN"
2790 "\21LAZYWRITE"
2791 "\22ADAPMICROFIB"
2792 "\23BIOSFIB"
2793 "\24FAST_RESPONSE"
2794 "\25APIFIB\n");
2795 printf(" Command %d\n", fib->Header.Command);
2796 printf(" StructType %d\n", fib->Header.StructType);
2797 printf(" Flags 0x%x\n", fib->Header.Flags);
2798 printf(" Size %d\n", fib->Header.Size);
2799 printf(" SenderSize %d\n", fib->Header.SenderSize);
2800 printf(" SenderAddress 0x%x\n", fib->Header.SenderFibAddress);
2801 printf(" ReceiverAddress 0x%x\n", fib->Header.ReceiverFibAddress);
2802 printf(" SenderData 0x%x\n", fib->Header.SenderData);
2803 switch(fib->Header.Command) {
2804 case ContainerCommand: {
2805 struct aac_blockread *br = (struct aac_blockread *)fib->data;
2806 struct aac_blockwrite *bw = (struct aac_blockwrite *)fib->data;
2807 struct aac_sg_table *sg = NULL;
2808 int i;
2809
2810 if (br->Command == VM_CtBlockRead) {
2811 printf(" BlockRead: container %d 0x%x/%d\n",
2812 br->ContainerId, br->BlockNumber, br->ByteCount);
2813 sg = &br->SgMap;
2814 }
2815 if (bw->Command == VM_CtBlockWrite) {
2816 printf(" BlockWrite: container %d 0x%x/%d (%s)\n",
2817 bw->ContainerId, bw->BlockNumber, bw->ByteCount,
2818 bw->Stable == CSTABLE ? "stable" : "unstable");
2819 sg = &bw->SgMap;
2820 }
2821 if (sg != NULL) {
2822 printf(" %d s/g entries\n", sg->SgCount);
2823 for (i = 0; i < sg->SgCount; i++)
2824 printf(" 0x%08x/%d\n",
2825 sg->SgEntry[i].SgAddress,
2826 sg->SgEntry[i].SgByteCount);
2827 }
2828 break;
2829 }
2830 default:
2831 printf(" %16D\n", fib->data, " ");
2832 printf(" %16D\n", fib->data + 16, " ");
2833 break;
2834 }
2835 }
2836
2837
2838
2839
2840 void
2841 aac_print_aif(struct aac_softc *sc, struct aac_aif_command *aif)
2842 {
2843 printf("%s: print_aif: ", sc->aac_dev.dv_xname);
2844
2845 switch(aif->command) {
2846 case AifCmdEventNotify:
2847 printf("EventNotify(%d)\n", aif->seqNumber);
2848
2849 switch(aif->data.EN.type) {
2850 case AifEnGeneric:
2851
2852 printf("\t(Generic) %.*s\n",
2853 (int)sizeof(aif->data.EN.data.EG),
2854 aif->data.EN.data.EG.text);
2855 break;
2856 case AifEnTaskComplete:
2857
2858 printf("\t(TaskComplete)\n");
2859 break;
2860 case AifEnConfigChange:
2861
2862 printf("\t(ConfigChange)\n");
2863 break;
2864 case AifEnContainerChange:
2865
2866 printf("\t(ContainerChange) container %d,%d\n",
2867 aif->data.EN.data.ECC.container[0],
2868 aif->data.EN.data.ECC.container[1]);
2869 break;
2870 case AifEnDeviceFailure:
2871
2872 printf("\t(DeviceFailure) handle %d\n",
2873 aif->data.EN.data.EDF.deviceHandle);
2874 break;
2875 case AifEnMirrorFailover:
2876
2877 printf("\t(MirrorFailover) container %d failed, "
2878 "migrating from slice %d to %d\n",
2879 aif->data.EN.data.EMF.container,
2880 aif->data.EN.data.EMF.failedSlice,
2881 aif->data.EN.data.EMF.creatingSlice);
2882 break;
2883 case AifEnContainerEvent:
2884
2885 printf("\t(ContainerEvent) container %d event %d\n",
2886 aif->data.EN.data.ECE.container,
2887 aif->data.EN.data.ECE.eventType);
2888 break;
2889 case AifEnFileSystemChange:
2890
2891 printf("\t(FileSystemChange)\n");
2892 break;
2893 case AifEnConfigPause:
2894
2895 printf("\t(ConfigPause)\n");
2896 break;
2897 case AifEnConfigResume:
2898
2899 printf("\t(ConfigResume)\n");
2900 break;
2901 case AifEnFailoverChange:
2902
2903 printf("\t(FailoverChange)\n");
2904 break;
2905 case AifEnRAID5RebuildDone:
2906
2907 printf("\t(RAID5RebuildDone)\n");
2908 break;
2909 case AifEnEnclosureManagement:
2910
2911 printf("\t(EnclosureManagement) EMPID %d unit %d "
2912 "event %d\n",
2913 aif->data.EN.data.EEE.empID,
2914 aif->data.EN.data.EEE.unitID,
2915 aif->data.EN.data.EEE.eventType);
2916 break;
2917 case AifEnBatteryEvent:
2918
2919 printf("\t(BatteryEvent) %d (state was %d, is %d\n",
2920 aif->data.EN.data.EBE.transition_type,
2921 aif->data.EN.data.EBE.current_state,
2922 aif->data.EN.data.EBE.prior_state);
2923 break;
2924 case AifEnAddContainer:
2925
2926 printf("\t(AddContainer)\n");
2927 break;
2928 case AifEnDeleteContainer:
2929
2930 printf("\t(DeleteContainer)\n");
2931 break;
2932 case AifEnBatteryNeedsRecond:
2933
2934 printf("\t(BatteryNeedsRecond)\n");
2935 break;
2936 case AifEnClusterEvent:
2937
2938 printf("\t(ClusterEvent) event %d\n",
2939 aif->data.EN.data.ECLE.eventType);
2940 break;
2941 case AifEnDiskSetEvent:
2942
2943 printf("(DiskSetEvent) event %d "
2944 "diskset %lld creator %lld\n",
2945 aif->data.EN.data.EDS.eventType,
2946 aif->data.EN.data.EDS.DsNum,
2947 aif->data.EN.data.EDS.CreatorId);
2948 break;
2949 case AifDenMorphComplete:
2950
2951 printf("\t(MorphComplete)\n");
2952 break;
2953 case AifDenVolumeExtendComplete:
2954
2955 printf("\t(VolumeExtendComplete)\n");
2956 break;
2957 default:
2958 printf("\t(%d)\n", aif->data.EN.type);
2959 break;
2960 }
2961 break;
2962 case AifCmdJobProgress:
2963 {
2964 char *status;
2965 switch(aif->data.PR[0].status) {
2966 case AifJobStsSuccess:
2967 status = "success"; break;
2968 case AifJobStsFinished:
2969 status = "finished"; break;
2970 case AifJobStsAborted:
2971 status = "aborted"; break;
2972 case AifJobStsFailed:
2973 status = "failed"; break;
2974 case AifJobStsSuspended:
2975 status = "suspended"; break;
2976 case AifJobStsRunning:
2977 status = "running"; break;
2978 default:
2979 status = "unknown status"; break;
2980 }
2981
2982 printf("JobProgress (%d) - %s (%d, %d)\n",
2983 aif->seqNumber, status,
2984 aif->data.PR[0].currentTick,
2985 aif->data.PR[0].finalTick);
2986
2987 switch(aif->data.PR[0].jd.type) {
2988 case AifJobScsiZero:
2989
2990 printf("\t(ScsiZero) handle %d\n",
2991 aif->data.PR[0].jd.client.scsi_dh);
2992 break;
2993 case AifJobScsiVerify:
2994
2995 printf("\t(ScsiVerify) handle %d\n",
2996 aif->data.PR[0].jd.client.scsi_dh);
2997 break;
2998 case AifJobScsiExercise:
2999
3000 printf("\t(ScsiExercise) handle %d\n",
3001 aif->data.PR[0].jd.client.scsi_dh);
3002 break;
3003 case AifJobScsiVerifyRepair:
3004
3005 printf("\t(ScsiVerifyRepair) handle %d\n",
3006 aif->data.PR[0].jd.client.scsi_dh);
3007 break;
3008 case AifJobCtrZero:
3009
3010 printf("\t(ContainerZero) container %d\n",
3011 aif->data.PR[0].jd.client.container.src);
3012 break;
3013 case AifJobCtrCopy:
3014
3015 printf("\t(ContainerCopy) container %d to %d\n",
3016 aif->data.PR[0].jd.client.container.src,
3017 aif->data.PR[0].jd.client.container.dst);
3018 break;
3019 case AifJobCtrCreateMirror:
3020
3021 printf("\t(ContainerCreateMirror) container %d\n",
3022 aif->data.PR[0].jd.client.container.src);
3023
3024 break;
3025 case AifJobCtrMergeMirror:
3026
3027 printf("\t(ContainerMergeMirror) container %d\n",
3028 aif->data.PR[0].jd.client.container.src);
3029
3030 break;
3031 case AifJobCtrScrubMirror:
3032
3033 printf("\t(ContainerScrubMirror) container %d\n",
3034 aif->data.PR[0].jd.client.container.src);
3035 break;
3036 case AifJobCtrRebuildRaid5:
3037
3038 printf("\t(ContainerRebuildRaid5) container %d\n",
3039 aif->data.PR[0].jd.client.container.src);
3040 break;
3041 case AifJobCtrScrubRaid5:
3042
3043 printf("\t(ContainerScrubRaid5) container %d\n",
3044 aif->data.PR[0].jd.client.container.src);
3045 break;
3046 case AifJobCtrMorph:
3047
3048 printf("\t(ContainerMorph) container %d\n",
3049 aif->data.PR[0].jd.client.container.src);
3050
3051 break;
3052 case AifJobCtrPartCopy:
3053
3054 printf("\t(ContainerPartCopy) container %d to %d\n",
3055 aif->data.PR[0].jd.client.container.src,
3056 aif->data.PR[0].jd.client.container.dst);
3057 break;
3058 case AifJobCtrRebuildMirror:
3059
3060 printf("\t(ContainerRebuildMirror) container %d\n",
3061 aif->data.PR[0].jd.client.container.src);
3062 break;
3063 case AifJobCtrCrazyCache:
3064
3065 printf("\t(ContainerCrazyCache) container %d\n",
3066 aif->data.PR[0].jd.client.container.src);
3067
3068 break;
3069 case AifJobFsCreate:
3070
3071 printf("\t(FsCreate)\n");
3072 break;
3073 case AifJobFsVerify:
3074
3075 printf("\t(FsVerivy)\n");
3076 break;
3077 case AifJobFsExtend:
3078
3079 printf("\t(FsExtend)\n");
3080 break;
3081 case AifJobApiFormatNTFS:
3082
3083 printf("\t(FormatNTFS)\n");
3084 break;
3085 case AifJobApiFormatFAT:
3086
3087 printf("\t(FormatFAT)\n");
3088 break;
3089 case AifJobApiUpdateSnapshot:
3090
3091 printf("\t(UpdateSnapshot)\n");
3092 break;
3093 case AifJobApiFormatFAT32:
3094
3095 printf("\t(FormatFAT32)\n");
3096 break;
3097 case AifJobCtlContinuousCtrVerify:
3098
3099 printf("\t(ContinuousCtrVerify)\n");
3100 break;
3101 default:
3102 printf("\t(%d)\n", aif->data.PR[0].jd.type);
3103 break;
3104 }
3105 break;
3106 }
3107 case AifCmdAPIReport:
3108 printf("APIReport (%d)\n", aif->seqNumber);
3109 break;
3110 case AifCmdDriverNotify:
3111 printf("DriverNotify (%d)\n", aif->seqNumber);
3112 break;
3113 default:
3114 printf("AIF %d (%d)\n", aif->command, aif->seqNumber);
3115 break;
3116 }
3117 }
3118 #endif