2 * Generic register and struct definitions for the Adaptech 154x/164x
3 * SCSI host adapters. Product specific probe and attach routines can
5 * aha 1540/1542B/1542C/1542CF/1542CP aha_isa.c
7 * Copyright (c) 1998 M. Warner Losh.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification, immediately at the beginning of the file.
17 * 2. The name of the author may not be used to endorse or promote products
18 * derived from this software without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
24 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * Derived from bt.c written by:
34 * Copyright (c) 1998 Justin T. Gibbs.
35 * All rights reserved.
37 * Redistribution and use in source and binary forms, with or without
38 * modification, are permitted provided that the following conditions
40 * 1. Redistributions of source code must retain the above copyright
41 * notice, this list of conditions, and the following disclaimer,
42 * without modification, immediately at the beginning of the file.
43 * 2. The name of the author may not be used to endorse or promote products
44 * derived from this software without specific prior written permission.
46 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
47 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
48 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
49 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
50 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
51 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
52 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
53 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
54 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
55 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58 * $FreeBSD: src/sys/dev/aha/aha.c,v 1.34.2.1 2000/08/02 22:24:39 peter Exp $
59 * $DragonFly: src/sys/dev/disk/aha/aha.c,v 1.20 2008/05/18 20:30:21 pavalos Exp $
62 #include <sys/param.h>
64 #include <sys/systm.h>
65 #include <sys/malloc.h>
67 #include <sys/kernel.h>
68 #include <sys/thread2.h>
70 #include <machine/clock.h>
72 #include <bus/cam/cam.h>
73 #include <bus/cam/cam_ccb.h>
74 #include <bus/cam/cam_sim.h>
75 #include <bus/cam/cam_xpt_sim.h>
76 #include <bus/cam/cam_debug.h>
78 #include <bus/cam/scsi/scsi_message.h>
85 struct aha_softc
*aha_softcs
[NAHATOT
];
87 #define PRVERB(x) do { if (bootverbose) device_printf x; } while(0)
89 /* Macro to determine that a rev is potentially a new valid one
90 * so that the driver doesn't keep breaking on new revs as it
91 * did for the CF and CP.
93 #define PROBABLY_NEW_BOARD(REV) (REV > 0x43 && REV < 0x56)
95 /* MailBox Management functions */
96 static __inline
void ahanextinbox(struct aha_softc
*aha
);
97 static __inline
void ahanextoutbox(struct aha_softc
*aha
);
99 #define aha_name(aha) device_get_nameunit(aha->dev)
102 ahanextinbox(struct aha_softc
*aha
)
104 if (aha
->cur_inbox
== aha
->last_inbox
)
105 aha
->cur_inbox
= aha
->in_boxes
;
111 ahanextoutbox(struct aha_softc
*aha
)
113 if (aha
->cur_outbox
== aha
->last_outbox
)
114 aha
->cur_outbox
= aha
->out_boxes
;
119 #define ahautoa24(u,s3) \
120 (s3)[0] = ((u) >> 16) & 0xff; \
121 (s3)[1] = ((u) >> 8) & 0xff; \
122 (s3)[2] = (u) & 0xff;
124 #define aha_a24tou(s3) \
125 (((s3)[0] << 16) | ((s3)[1] << 8) | (s3)[2])
127 /* CCB Mangement functions */
128 static __inline u_int32_t
ahaccbvtop(struct aha_softc
*aha
,
129 struct aha_ccb
*accb
);
130 static __inline
struct aha_ccb
* ahaccbptov(struct aha_softc
*aha
,
133 static __inline u_int32_t
134 ahaccbvtop(struct aha_softc
*aha
, struct aha_ccb
*accb
)
136 return (aha
->aha_ccb_physbase
137 + (u_int32_t
)((caddr_t
)accb
- (caddr_t
)aha
->aha_ccb_array
));
139 static __inline
struct aha_ccb
*
140 ahaccbptov(struct aha_softc
*aha
, u_int32_t ccb_addr
)
142 return (aha
->aha_ccb_array
+
143 + ((struct aha_ccb
*)ccb_addr
-(struct aha_ccb
*)aha
->aha_ccb_physbase
));
146 static struct aha_ccb
* ahagetccb(struct aha_softc
*aha
);
147 static __inline
void ahafreeccb(struct aha_softc
*aha
, struct aha_ccb
*accb
);
148 static void ahaallocccbs(struct aha_softc
*aha
);
149 static bus_dmamap_callback_t ahaexecuteccb
;
150 static void ahadone(struct aha_softc
*aha
, struct aha_ccb
*accb
,
151 aha_mbi_comp_code_t comp_code
);
153 /* Host adapter command functions */
154 static int ahareset(struct aha_softc
* aha
, int hard_reset
);
156 /* Initialization functions */
157 static int ahainitmboxes(struct aha_softc
*aha
);
158 static bus_dmamap_callback_t ahamapmboxes
;
159 static bus_dmamap_callback_t ahamapccbs
;
160 static bus_dmamap_callback_t ahamapsgs
;
162 /* Transfer Negotiation Functions */
163 static void ahafetchtransinfo(struct aha_softc
*aha
,
164 struct ccb_trans_settings
*cts
);
166 /* CAM SIM entry points */
167 #define ccb_accb_ptr spriv_ptr0
168 #define ccb_aha_ptr spriv_ptr1
169 static void ahaaction(struct cam_sim
*sim
, union ccb
*ccb
);
170 static void ahapoll(struct cam_sim
*sim
);
172 /* Our timeout handler */
173 static timeout_t ahatimeout
;
178 * Do our own re-probe protection until a configuration
179 * manager can do it for us. This ensures that we don't
180 * reprobe a card already found by the EISA or PCI probes.
182 static struct aha_isa_port aha_isa_ports
[] =
193 * I/O ports listed in the order enumerated by the
194 * card for certain op codes.
196 static u_int16_t aha_board_ports
[] =
206 /* Exported functions */
208 aha_alloc(device_t dev
, bus_space_tag_t tag
, bus_space_handle_t bsh
)
210 struct aha_softc
*aha
;
212 int unit
= device_get_unit(dev
);
213 if (unit
!= AHA_TEMP_UNIT
) {
214 if (unit
>= NAHATOT
) {
215 device_printf(dev
, "unit number (%d) too high\n", unit
);
220 * Allocate a storage area for us
222 if (aha_softcs
[unit
]) {
223 device_printf(dev
, "memory already allocated\n");
228 aha
= kmalloc(sizeof(struct aha_softc
), M_DEVBUF
, M_INTWAIT
| M_ZERO
);
229 SLIST_INIT(&aha
->free_aha_ccbs
);
230 LIST_INIT(&aha
->pending_ccbs
);
231 SLIST_INIT(&aha
->sg_maps
);
235 aha
->ccb_sg_opcode
= INITIATOR_SG_CCB_WRESID
;
236 aha
->ccb_ccb_opcode
= INITIATOR_CCB_WRESID
;
238 if (unit
!= AHA_TEMP_UNIT
) {
239 aha_softcs
[unit
] = aha
;
245 aha_free(struct aha_softc
*aha
)
247 int unit
= device_get_unit(aha
->dev
);
249 switch (aha
->init_level
) {
253 struct sg_map_node
*sg_map
;
255 while ((sg_map
= SLIST_FIRST(&aha
->sg_maps
))!= NULL
) {
256 SLIST_REMOVE_HEAD(&aha
->sg_maps
, links
);
257 bus_dmamap_unload(aha
->sg_dmat
,
259 bus_dmamem_free(aha
->sg_dmat
, sg_map
->sg_vaddr
,
261 kfree(sg_map
, M_DEVBUF
);
263 bus_dma_tag_destroy(aha
->sg_dmat
);
267 bus_dmamap_unload(aha
->ccb_dmat
, aha
->ccb_dmamap
);
270 bus_dmamap_destroy(aha
->ccb_dmat
, aha
->ccb_dmamap
);
271 bus_dmamem_free(aha
->ccb_dmat
, aha
->aha_ccb_array
,
275 bus_dma_tag_destroy(aha
->ccb_dmat
);
278 bus_dmamap_unload(aha
->mailbox_dmat
, aha
->mailbox_dmamap
);
281 bus_dmamem_free(aha
->mailbox_dmat
, aha
->in_boxes
,
282 aha
->mailbox_dmamap
);
283 bus_dmamap_destroy(aha
->mailbox_dmat
, aha
->mailbox_dmamap
);
286 bus_dma_tag_destroy(aha
->buffer_dmat
);
289 bus_dma_tag_destroy(aha
->mailbox_dmat
);
294 if (unit
!= AHA_TEMP_UNIT
) {
295 aha_softcs
[unit
] = NULL
;
297 kfree(aha
, M_DEVBUF
);
301 * Probe the adapter and verify that the card is an Adaptec.
304 aha_probe(struct aha_softc
* aha
)
309 board_id_data_t board_id
;
312 * See if the three I/O ports look reasonable.
313 * Touch the minimal number of registers in the
316 status
= aha_inb(aha
, STATUS_REG
);
318 || (status
& (DIAG_ACTIVE
|CMD_REG_BUSY
|
319 STATUS_REG_RSVD
)) != 0) {
320 PRVERB((aha
->dev
, "status reg test failed %x\n", status
));
324 intstat
= aha_inb(aha
, INTSTAT_REG
);
325 if ((intstat
& INTSTAT_REG_RSVD
) != 0) {
326 PRVERB((aha
->dev
, "Failed Intstat Reg Test\n"));
331 * Looking good so far. Final test is to reset the
332 * adapter and fetch the board ID and ensure we aren't
333 * looking at a BusLogic.
335 if ((error
= ahareset(aha
, /*hard_reset*/TRUE
)) != 0) {
336 PRVERB((aha
->dev
, "Failed Reset\n"));
341 * Get the board ID. We use this to see if we're dealing with
342 * a buslogic card or a aha card (or clone).
344 error
= aha_cmd(aha
, AOP_INQUIRE_BOARD_ID
, NULL
, /*parmlen*/0,
345 (u_int8_t
*)&board_id
, sizeof(board_id
),
346 DEFAULT_CMD_TIMEOUT
);
348 PRVERB((aha
->dev
, "INQUIRE failed %x\n", error
));
351 aha
->fw_major
= board_id
.firmware_rev_major
;
352 aha
->fw_minor
= board_id
.firmware_rev_minor
;
353 aha
->boardid
= board_id
.board_type
;
356 * The Buslogic cards have an id of either 0x41 or 0x42. So
357 * if those come up in the probe, we test the geometry register
358 * of the board. Adaptec boards that are this old will not have
359 * this register, and return 0xff, while buslogic cards will return
360 * something different.
362 * It appears that for reasons unknow, for the for the
363 * aha-1542B cards, we need to wait a little bit before trying
364 * to read the geometry register. I picked 10ms since we have
365 * reports that a for loop to 1000 did the trick, and this
366 * errs on the side of conservatism. Besides, no one will
367 * notice a 10mS delay here, even the 1542B card users :-)
369 * Some compatible cards return 0 here. Some cards also
370 * seem to return 0x7f.
372 * XXX I'm not sure how this will impact other cloned cards
374 * This really should be replaced with the esetup command, since
375 * that appears to be more reliable. This becomes more and more
376 * true over time as we discover more cards that don't read the
377 * geometry register consistantly.
379 if (aha
->boardid
<= 0x42) {
380 /* Wait 10ms before reading */
382 status
= aha_inb(aha
, GEOMETRY_REG
);
383 if (status
!= 0xff && status
!= 0x00 && status
!= 0x7f) {
384 PRVERB((aha
->dev
, "Geometry Register test failed 0x%x\n", status
));
393 * Pull the boards setup information and record it in our softc.
396 aha_fetch_adapter_info(struct aha_softc
*aha
)
398 setup_data_t setup_info
;
399 config_data_t config_data
;
400 u_int8_t length_param
;
402 struct aha_extbios extbios
;
404 switch (aha
->boardid
) {
405 case BOARD_1540_16HEAD_BIOS
:
406 ksnprintf(aha
->model
, sizeof(aha
->model
), "1540 16 head BIOS");
408 case BOARD_1540_64HEAD_BIOS
:
409 ksnprintf(aha
->model
, sizeof(aha
->model
), "1540 64 head BIOS");
412 ksnprintf(aha
->model
, sizeof(aha
->model
), "1540/1542 64 head BIOS");
415 ksnprintf(aha
->model
, sizeof(aha
->model
), "1640");
418 ksnprintf(aha
->model
, sizeof(aha
->model
), "1740A/1742A/1744");
421 ksnprintf(aha
->model
, sizeof(aha
->model
), "1542C");
424 ksnprintf(aha
->model
, sizeof(aha
->model
), "1542CF");
427 ksnprintf(aha
->model
, sizeof(aha
->model
), "1542CP");
430 ksnprintf(aha
->model
, sizeof(aha
->model
), "Unknown");
434 * If we are a new type of 1542 board (anything newer than a 1542C)
435 * then disable the extended bios so that the
436 * mailbox interface is unlocked.
437 * This is also true for the 1542B Version 3.20. First Adaptec
438 * board that supports >1Gb drives.
439 * No need to check the extended bios flags as some of the
440 * extensions that cause us problems are not flagged in that byte.
442 if (PROBABLY_NEW_BOARD(aha
->boardid
) ||
443 (aha
->boardid
== 0x41
444 && aha
->fw_major
== 0x31 &&
445 aha
->fw_minor
>= 0x34)) {
446 error
= aha_cmd(aha
, AOP_RETURN_EXT_BIOS_INFO
, NULL
,
447 /*paramlen*/0, (u_char
*)&extbios
, sizeof(extbios
),
448 DEFAULT_CMD_TIMEOUT
);
449 error
= aha_cmd(aha
, AOP_MBOX_IF_ENABLE
, (u_int8_t
*)&extbios
,
450 /*paramlen*/2, NULL
, 0, DEFAULT_CMD_TIMEOUT
);
452 if (aha
->boardid
< 0x41)
453 device_printf(aha
->dev
, "Warning: aha-1542A won't likely work.\n");
455 aha
->max_sg
= 17; /* Need >= 17 to do 64k I/O */
457 aha
->extended_lun
= 0;
458 aha
->extended_trans
= 0;
460 /* Determine Sync/Wide/Disc settings */
461 length_param
= sizeof(setup_info
);
462 error
= aha_cmd(aha
, AOP_INQUIRE_SETUP_INFO
, &length_param
,
463 /*paramlen*/1, (u_int8_t
*)&setup_info
,
464 sizeof(setup_info
), DEFAULT_CMD_TIMEOUT
);
466 device_printf(aha
->dev
, "aha_fetch_adapter_info - Failed "
470 if (setup_info
.initiate_sync
!= 0) {
471 aha
->sync_permitted
= ALL_TARGETS
;
473 aha
->disc_permitted
= ALL_TARGETS
;
475 /* We need as many mailboxes as we can have ccbs */
476 aha
->num_boxes
= aha
->max_ccbs
;
478 /* Determine our SCSI ID */
480 error
= aha_cmd(aha
, AOP_INQUIRE_CONFIG
, NULL
, /*parmlen*/0,
481 (u_int8_t
*)&config_data
, sizeof(config_data
),
482 DEFAULT_CMD_TIMEOUT
);
484 device_printf(aha
->dev
, "aha_fetch_adapter_info - Failed Get Config\n");
487 aha
->scsi_id
= config_data
.scsi_id
;
492 * Start the board, ready for normal operation
495 aha_init(struct aha_softc
* aha
)
497 /* Announce the Adapter */
498 device_printf(aha
->dev
, "AHA-%s FW Rev. %c.%c (ID=%x) ",
499 aha
->model
, aha
->fw_major
, aha
->fw_minor
, aha
->boardid
);
501 if (aha
->diff_bus
!= 0)
503 kprintf("SCSI Host Adapter, SCSI ID %d, %d CCBs\n", aha
->scsi_id
,
507 * Create our DMA tags. These tags define the kinds of device
508 * accessible memory allocations and memory mappings we will
509 * need to perform during normal operation.
511 * Unless we need to further restrict the allocation, we rely
512 * on the restrictions of the parent dmat, hence the common
513 * use of MAXADDR and MAXSIZE.
516 /* DMA tag for mapping buffers into device visible space. */
517 if (bus_dma_tag_create(aha
->parent_dmat
, /*alignment*/1, /*boundary*/0,
518 /*lowaddr*/BUS_SPACE_MAXADDR
,
519 /*highaddr*/BUS_SPACE_MAXADDR
,
520 /*filter*/NULL
, /*filterarg*/NULL
,
521 /*maxsize*/MAXBSIZE
, /*nsegments*/AHA_NSEG
,
522 /*maxsegsz*/BUS_SPACE_MAXSIZE_24BIT
,
523 /*flags*/BUS_DMA_ALLOCNOW
,
524 &aha
->buffer_dmat
) != 0) {
529 /* DMA tag for our mailboxes */
530 if (bus_dma_tag_create(aha
->parent_dmat
, /*alignment*/1, /*boundary*/0,
531 /*lowaddr*/BUS_SPACE_MAXADDR
,
532 /*highaddr*/BUS_SPACE_MAXADDR
,
533 /*filter*/NULL
, /*filterarg*/NULL
,
534 aha
->num_boxes
* (sizeof(aha_mbox_in_t
)
535 + sizeof(aha_mbox_out_t
)),
537 /*maxsegsz*/BUS_SPACE_MAXSIZE_24BIT
,
538 /*flags*/0, &aha
->mailbox_dmat
) != 0) {
544 /* Allocation for our mailboxes */
545 if (bus_dmamem_alloc(aha
->mailbox_dmat
, (void **)&aha
->out_boxes
,
546 BUS_DMA_NOWAIT
, &aha
->mailbox_dmamap
) != 0) {
552 /* And permanently map them */
553 bus_dmamap_load(aha
->mailbox_dmat
, aha
->mailbox_dmamap
,
555 aha
->num_boxes
* (sizeof(aha_mbox_in_t
)
556 + sizeof(aha_mbox_out_t
)),
557 ahamapmboxes
, aha
, /*flags*/0);
561 aha
->in_boxes
= (aha_mbox_in_t
*)&aha
->out_boxes
[aha
->num_boxes
];
565 /* DMA tag for our ccb structures */
566 if (bus_dma_tag_create(aha
->parent_dmat
, /*alignment*/1, /*boundary*/0,
567 /*lowaddr*/BUS_SPACE_MAXADDR
,
568 /*highaddr*/BUS_SPACE_MAXADDR
,
569 /*filter*/NULL
, /*filterarg*/NULL
,
570 aha
->max_ccbs
* sizeof(struct aha_ccb
),
572 /*maxsegsz*/BUS_SPACE_MAXSIZE_24BIT
,
573 /*flags*/0, &aha
->ccb_dmat
) != 0) {
579 /* Allocation for our ccbs */
580 if (bus_dmamem_alloc(aha
->ccb_dmat
, (void **)&aha
->aha_ccb_array
,
581 BUS_DMA_NOWAIT
, &aha
->ccb_dmamap
) != 0) {
587 /* And permanently map them */
588 bus_dmamap_load(aha
->ccb_dmat
, aha
->ccb_dmamap
,
590 aha
->max_ccbs
* sizeof(struct aha_ccb
),
591 ahamapccbs
, aha
, /*flags*/0);
595 /* DMA tag for our S/G structures. We allocate in page sized chunks */
596 if (bus_dma_tag_create(aha
->parent_dmat
, /*alignment*/1, /*boundary*/0,
597 /*lowaddr*/BUS_SPACE_MAXADDR
,
598 /*highaddr*/BUS_SPACE_MAXADDR
,
599 /*filter*/NULL
, /*filterarg*/NULL
,
600 PAGE_SIZE
, /*nsegments*/1,
601 /*maxsegsz*/BUS_SPACE_MAXSIZE_24BIT
,
602 /*flags*/0, &aha
->sg_dmat
) != 0) {
608 /* Perform initial CCB allocation */
609 bzero(aha
->aha_ccb_array
, aha
->max_ccbs
* sizeof(struct aha_ccb
));
612 if (aha
->num_ccbs
== 0) {
613 device_printf(aha
->dev
,
614 "aha_init - Unable to allocate initial ccbs\n");
619 * Note that we are going and return (to probe)
629 aha_attach(struct aha_softc
*aha
)
631 int tagged_dev_openings
;
632 struct cam_devq
*devq
;
635 * We don't do tagged queueing, since the aha cards don't
638 tagged_dev_openings
= 0;
641 * Create the device queue for our SIM.
643 devq
= cam_simq_alloc(aha
->max_ccbs
- 1);
648 * Construct our SIM entry
650 aha
->sim
= cam_sim_alloc(ahaaction
, ahapoll
, "aha", aha
, device_get_unit(aha
->dev
),
651 &sim_mplock
, 2, tagged_dev_openings
, devq
);
652 cam_simq_release(devq
);
653 if (aha
->sim
== NULL
) {
657 if (xpt_bus_register(aha
->sim
, 0) != CAM_SUCCESS
) {
658 cam_sim_free(aha
->sim
);
662 if (xpt_create_path(&aha
->path
, /*periph*/NULL
,
663 cam_sim_path(aha
->sim
), CAM_TARGET_WILDCARD
,
664 CAM_LUN_WILDCARD
) != CAM_REQ_CMP
) {
665 xpt_bus_deregister(cam_sim_path(aha
->sim
));
666 cam_sim_free(aha
->sim
);
674 aha_find_probe_range(int ioport
, int *port_index
, int *max_port_index
)
679 for (i
= 0;i
< AHA_NUM_ISAPORTS
; i
++)
680 if (ioport
<= aha_isa_ports
[i
].addr
)
682 if ((i
>= AHA_NUM_ISAPORTS
)
683 || (ioport
!= aha_isa_ports
[i
].addr
)) {
685 "aha_isa_probe: Invalid baseport of 0x%x specified.\n"
686 "aha_isa_probe: Nearest valid baseport is 0x%x.\n"
687 "aha_isa_probe: Failing probe.\n",
689 (i
< AHA_NUM_ISAPORTS
)
690 ? aha_isa_ports
[i
].addr
691 : aha_isa_ports
[AHA_NUM_ISAPORTS
- 1].addr
);
692 *port_index
= *max_port_index
= -1;
695 *port_index
= *max_port_index
= aha_isa_ports
[i
].bio
;
698 *max_port_index
= AHA_NUM_ISAPORTS
- 1;
703 aha_iop_from_bio(isa_compat_io_t bio_index
)
705 if (bio_index
>= 0 && bio_index
< AHA_NUM_ISAPORTS
)
706 return (aha_board_ports
[bio_index
]);
711 ahaallocccbs(struct aha_softc
*aha
)
713 struct aha_ccb
*next_ccb
;
714 struct sg_map_node
*sg_map
;
720 next_ccb
= &aha
->aha_ccb_array
[aha
->num_ccbs
];
722 sg_map
= kmalloc(sizeof(*sg_map
), M_DEVBUF
, M_INTWAIT
);
724 /* Allocate S/G space for the next batch of CCBS */
725 if (bus_dmamem_alloc(aha
->sg_dmat
, (void **)&sg_map
->sg_vaddr
,
726 BUS_DMA_NOWAIT
, &sg_map
->sg_dmamap
) != 0) {
727 kfree(sg_map
, M_DEVBUF
);
731 SLIST_INSERT_HEAD(&aha
->sg_maps
, sg_map
, links
);
733 bus_dmamap_load(aha
->sg_dmat
, sg_map
->sg_dmamap
, sg_map
->sg_vaddr
,
734 PAGE_SIZE
, ahamapsgs
, aha
, /*flags*/0);
736 segs
= sg_map
->sg_vaddr
;
737 physaddr
= sg_map
->sg_physaddr
;
739 newcount
= (PAGE_SIZE
/ (AHA_NSEG
* sizeof(aha_sg_t
)));
740 for (i
= 0; aha
->num_ccbs
< aha
->max_ccbs
&& i
< newcount
; i
++) {
743 next_ccb
->sg_list
= segs
;
744 next_ccb
->sg_list_phys
= physaddr
;
745 next_ccb
->flags
= ACCB_FREE
;
746 error
= bus_dmamap_create(aha
->buffer_dmat
, /*flags*/0,
750 SLIST_INSERT_HEAD(&aha
->free_aha_ccbs
, next_ccb
, links
);
752 physaddr
+= (AHA_NSEG
* sizeof(aha_sg_t
));
757 /* Reserve a CCB for error recovery */
758 if (aha
->recovery_accb
== NULL
) {
759 aha
->recovery_accb
= SLIST_FIRST(&aha
->free_aha_ccbs
);
760 SLIST_REMOVE_HEAD(&aha
->free_aha_ccbs
, links
);
765 ahafreeccb(struct aha_softc
*aha
, struct aha_ccb
*accb
)
768 if ((accb
->flags
& ACCB_ACTIVE
) != 0)
769 LIST_REMOVE(&accb
->ccb
->ccb_h
, sim_links
.le
);
770 if (aha
->resource_shortage
!= 0
771 && (accb
->ccb
->ccb_h
.status
& CAM_RELEASE_SIMQ
) == 0) {
772 accb
->ccb
->ccb_h
.status
|= CAM_RELEASE_SIMQ
;
773 aha
->resource_shortage
= FALSE
;
775 accb
->flags
= ACCB_FREE
;
776 SLIST_INSERT_HEAD(&aha
->free_aha_ccbs
, accb
, links
);
781 static struct aha_ccb
*
782 ahagetccb(struct aha_softc
*aha
)
784 struct aha_ccb
* accb
;
787 if ((accb
= SLIST_FIRST(&aha
->free_aha_ccbs
)) != NULL
) {
788 SLIST_REMOVE_HEAD(&aha
->free_aha_ccbs
, links
);
790 } else if (aha
->num_ccbs
< aha
->max_ccbs
) {
792 accb
= SLIST_FIRST(&aha
->free_aha_ccbs
);
794 device_printf(aha
->dev
, "Can't malloc ACCB\n");
796 SLIST_REMOVE_HEAD(&aha
->free_aha_ccbs
, links
);
806 ahaaction(struct cam_sim
*sim
, union ccb
*ccb
)
808 struct aha_softc
*aha
;
810 CAM_DEBUG(ccb
->ccb_h
.path
, CAM_DEBUG_TRACE
, ("ahaaction\n"));
812 aha
= (struct aha_softc
*)cam_sim_softc(sim
);
814 switch (ccb
->ccb_h
.func_code
) {
815 /* Common cases first */
816 case XPT_SCSI_IO
: /* Execute the requested I/O operation */
817 case XPT_RESET_DEV
: /* Bus Device Reset the specified SCSI device */
819 struct aha_ccb
*accb
;
820 struct aha_hccb
*hccb
;
825 if ((accb
= ahagetccb(aha
)) == NULL
) {
827 aha
->resource_shortage
= TRUE
;
829 xpt_freeze_simq(aha
->sim
, /*count*/1);
830 ccb
->ccb_h
.status
= CAM_REQUEUE_REQ
;
838 * So we can find the ACCB when an abort is requested
841 ccb
->ccb_h
.ccb_accb_ptr
= accb
;
842 ccb
->ccb_h
.ccb_aha_ptr
= aha
;
845 * Put all the arguments for the xfer in the accb
847 hccb
->target
= ccb
->ccb_h
.target_id
;
848 hccb
->lun
= ccb
->ccb_h
.target_lun
;
852 if (ccb
->ccb_h
.func_code
== XPT_SCSI_IO
) {
853 struct ccb_scsiio
*csio
;
854 struct ccb_hdr
*ccbh
;
858 hccb
->opcode
= aha
->ccb_ccb_opcode
;
859 hccb
->datain
= (ccb
->ccb_h
.flags
& CAM_DIR_IN
) != 0;
860 hccb
->dataout
= (ccb
->ccb_h
.flags
& CAM_DIR_OUT
) != 0;
861 hccb
->cmd_len
= csio
->cdb_len
;
862 if (hccb
->cmd_len
> sizeof(hccb
->scsi_cdb
)) {
863 ccb
->ccb_h
.status
= CAM_REQ_INVALID
;
864 ahafreeccb(aha
, accb
);
868 hccb
->sense_len
= csio
->sense_len
;
869 if ((ccbh
->flags
& CAM_CDB_POINTER
) != 0) {
870 if ((ccbh
->flags
& CAM_CDB_PHYS
) == 0) {
871 bcopy(csio
->cdb_io
.cdb_ptr
,
872 hccb
->scsi_cdb
, hccb
->cmd_len
);
874 /* I guess I could map it in... */
875 ccbh
->status
= CAM_REQ_INVALID
;
876 ahafreeccb(aha
, accb
);
881 bcopy(csio
->cdb_io
.cdb_bytes
,
882 hccb
->scsi_cdb
, hccb
->cmd_len
);
885 * If we have any data to send with this command,
886 * map it into bus space.
888 /* Only use S/G if there is a transfer */
889 if ((ccbh
->flags
& CAM_DIR_MASK
) != CAM_DIR_NONE
) {
890 if ((ccbh
->flags
& CAM_SCATTER_VALID
) == 0) {
892 * We've been given a pointer
893 * to a single buffer.
895 if ((ccbh
->flags
& CAM_DATA_PHYS
)==0) {
899 error
= bus_dmamap_load(
907 if (error
== EINPROGRESS
) {
910 * ordering, freeze the
912 * until our mapping is
915 xpt_freeze_simq(aha
->sim
,
917 csio
->ccb_h
.status
|=
922 struct bus_dma_segment seg
;
924 /* Pointer to physical buffer */
926 (bus_addr_t
)csio
->data_ptr
;
927 seg
.ds_len
= csio
->dxfer_len
;
928 ahaexecuteccb(accb
, &seg
, 1, 0);
931 struct bus_dma_segment
*segs
;
933 if ((ccbh
->flags
& CAM_DATA_PHYS
) != 0)
934 panic("ahaaction - Physical "
938 if ((ccbh
->flags
&CAM_SG_LIST_PHYS
)==0)
939 panic("ahaaction - Virtual "
943 /* Just use the segments provided */
944 segs
= (struct bus_dma_segment
*)
946 ahaexecuteccb(accb
, segs
,
947 csio
->sglist_cnt
, 0);
950 ahaexecuteccb(accb
, NULL
, 0, 0);
953 hccb
->opcode
= INITIATOR_BUS_DEV_RESET
;
954 /* No data transfer */
956 hccb
->dataout
= TRUE
;
959 ahaexecuteccb(accb
, NULL
, 0, 0);
963 case XPT_EN_LUN
: /* Enable LUN as a target */
964 case XPT_TARGET_IO
: /* Execute target I/O request */
965 case XPT_ACCEPT_TARGET_IO
: /* Accept Host Target Mode CDB */
966 case XPT_CONT_TARGET_IO
: /* Continue Host Target I/O Connection*/
967 case XPT_ABORT
: /* Abort the specified CCB */
969 ccb
->ccb_h
.status
= CAM_REQ_INVALID
;
972 case XPT_SET_TRAN_SETTINGS
:
975 ccb
->ccb_h
.status
= CAM_PROVIDE_FAIL
;
979 case XPT_GET_TRAN_SETTINGS
:
980 /* Get default/user set transfer settings for the target */
982 struct ccb_trans_settings
*cts
= &ccb
->cts
;
983 u_int target_mask
= 0x01 << ccb
->ccb_h
.target_id
;
984 struct ccb_trans_settings_scsi
*scsi
=
985 &cts
->proto_specific
.scsi
;
986 struct ccb_trans_settings_spi
*spi
=
987 &cts
->xport_specific
.spi
;
989 cts
->protocol
= PROTO_SCSI
;
990 cts
->protocol_version
= SCSI_REV_2
;
991 cts
->transport
= XPORT_SPI
;
992 cts
->transport_version
= 2;
993 if (cts
->type
== CTS_TYPE_USER_SETTINGS
) {
995 if ((aha
->disc_permitted
& target_mask
) != 0)
996 spi
->flags
|= CTS_SPI_FLAGS_DISC_ENB
;
997 spi
->bus_width
= MSG_EXT_WDTR_BUS_8_BIT
;
998 if ((aha
->sync_permitted
& target_mask
) != 0) {
999 if (aha
->boardid
>= BOARD_1542CF
)
1000 spi
->sync_period
= 25;
1002 spi
->sync_period
= 50;
1004 spi
->sync_period
= 0;
1007 if (spi
->sync_period
!= 0)
1008 spi
->sync_offset
= 15;
1010 spi
->valid
= CTS_SPI_VALID_SYNC_RATE
1011 | CTS_SPI_VALID_SYNC_OFFSET
1012 | CTS_SPI_VALID_BUS_WIDTH
1013 | CTS_SPI_VALID_DISC
;
1014 scsi
->valid
= CTS_SCSI_VALID_TQ
;
1016 ahafetchtransinfo(aha
, cts
);
1019 ccb
->ccb_h
.status
= CAM_REQ_CMP
;
1023 case XPT_CALC_GEOMETRY
:
1025 struct ccb_calc_geometry
*ccg
;
1027 u_int32_t secs_per_cylinder
;
1030 size_mb
= ccg
->volume_size
1031 / ((1024L * 1024L) / ccg
->block_size
);
1033 if (size_mb
>= 1024 && (aha
->extended_trans
!= 0)) {
1034 if (size_mb
>= 2048) {
1036 ccg
->secs_per_track
= 63;
1039 ccg
->secs_per_track
= 32;
1043 ccg
->secs_per_track
= 32;
1045 secs_per_cylinder
= ccg
->heads
* ccg
->secs_per_track
;
1046 ccg
->cylinders
= ccg
->volume_size
/ secs_per_cylinder
;
1047 ccb
->ccb_h
.status
= CAM_REQ_CMP
;
1051 case XPT_RESET_BUS
: /* Reset the specified SCSI bus */
1053 ahareset(aha
, /*hardreset*/TRUE
);
1054 ccb
->ccb_h
.status
= CAM_REQ_CMP
;
1058 case XPT_TERM_IO
: /* Terminate the I/O process */
1060 ccb
->ccb_h
.status
= CAM_REQ_INVALID
;
1063 case XPT_PATH_INQ
: /* Path routing inquiry */
1065 struct ccb_pathinq
*cpi
= &ccb
->cpi
;
1067 cpi
->version_num
= 1; /* XXX??? */
1068 cpi
->hba_inquiry
= PI_SDTR_ABLE
;
1069 cpi
->target_sprt
= 0;
1071 cpi
->hba_eng_cnt
= 0;
1072 cpi
->max_target
= 7;
1074 cpi
->initiator_id
= aha
->scsi_id
;
1075 cpi
->bus_id
= cam_sim_bus(sim
);
1076 cpi
->base_transfer_speed
= 3300;
1077 strncpy(cpi
->sim_vid
, "FreeBSD", SIM_IDLEN
);
1078 strncpy(cpi
->hba_vid
, "Adaptec", HBA_IDLEN
);
1079 strncpy(cpi
->dev_name
, cam_sim_name(sim
), DEV_IDLEN
);
1080 cpi
->unit_number
= cam_sim_unit(sim
);
1081 cpi
->transport
= XPORT_SPI
;
1082 cpi
->transport_version
= 2;
1083 cpi
->protocol
= PROTO_SCSI
;
1084 cpi
->protocol_version
= SCSI_REV_2
;
1085 cpi
->ccb_h
.status
= CAM_REQ_CMP
;
1090 ccb
->ccb_h
.status
= CAM_REQ_INVALID
;
1097 ahaexecuteccb(void *arg
, bus_dma_segment_t
*dm_segs
, int nseg
, int error
)
1099 struct aha_ccb
*accb
;
1101 struct aha_softc
*aha
;
1104 accb
= (struct aha_ccb
*)arg
;
1106 aha
= (struct aha_softc
*)ccb
->ccb_h
.ccb_aha_ptr
;
1110 device_printf(aha
->dev
,
1111 "Unexpected error 0x%x returned from "
1112 "bus_dmamap_load\n", error
);
1113 if (ccb
->ccb_h
.status
== CAM_REQ_INPROG
) {
1114 xpt_freeze_devq(ccb
->ccb_h
.path
, /*count*/1);
1115 ccb
->ccb_h
.status
= CAM_REQ_TOO_BIG
|CAM_DEV_QFRZN
;
1117 ahafreeccb(aha
, accb
);
1124 bus_dma_segment_t
*end_seg
;
1125 bus_dmasync_op_t op
;
1127 end_seg
= dm_segs
+ nseg
;
1129 /* Copy the segments into our SG list */
1131 while (dm_segs
< end_seg
) {
1132 ahautoa24(dm_segs
->ds_len
, sg
->len
);
1133 ahautoa24(dm_segs
->ds_addr
, sg
->addr
);
1139 accb
->hccb
.opcode
= aha
->ccb_sg_opcode
;
1140 ahautoa24((sizeof(aha_sg_t
) * nseg
),
1141 accb
->hccb
.data_len
);
1142 ahautoa24(accb
->sg_list_phys
, accb
->hccb
.data_addr
);
1144 bcopy(accb
->sg_list
->len
, accb
->hccb
.data_len
, 3);
1145 bcopy(accb
->sg_list
->addr
, accb
->hccb
.data_addr
, 3);
1148 if ((ccb
->ccb_h
.flags
& CAM_DIR_MASK
) == CAM_DIR_IN
)
1149 op
= BUS_DMASYNC_PREREAD
;
1151 op
= BUS_DMASYNC_PREWRITE
;
1153 bus_dmamap_sync(aha
->buffer_dmat
, accb
->dmamap
, op
);
1156 accb
->hccb
.opcode
= INITIATOR_CCB
;
1157 ahautoa24(0, accb
->hccb
.data_len
);
1158 ahautoa24(0, accb
->hccb
.data_addr
);
1164 * Last time we need to check if this CCB needs to
1167 if (ccb
->ccb_h
.status
!= CAM_REQ_INPROG
) {
1169 bus_dmamap_unload(aha
->buffer_dmat
, accb
->dmamap
);
1170 ahafreeccb(aha
, accb
);
1176 accb
->flags
= ACCB_ACTIVE
;
1177 ccb
->ccb_h
.status
|= CAM_SIM_QUEUED
;
1178 LIST_INSERT_HEAD(&aha
->pending_ccbs
, &ccb
->ccb_h
, sim_links
.le
);
1180 callout_reset(&ccb
->ccb_h
.timeout_ch
, (ccb
->ccb_h
.timeout
* hz
) / 1000,
1183 /* Tell the adapter about this command */
1184 if (aha
->cur_outbox
->action_code
!= AMBO_FREE
) {
1186 * We should never encounter a busy mailbox.
1187 * If we do, warn the user, and treat it as
1188 * a resource shortage. If the controller is
1189 * hung, one of the pending transactions will
1190 * timeout causing us to start recovery operations.
1192 device_printf(aha
->dev
,
1193 "Encountered busy mailbox with %d out of %d "
1194 "commands active!!!", aha
->active_ccbs
, aha
->max_ccbs
);
1195 callout_stop(&ccb
->ccb_h
.timeout_ch
);
1197 bus_dmamap_unload(aha
->buffer_dmat
, accb
->dmamap
);
1198 ahafreeccb(aha
, accb
);
1199 aha
->resource_shortage
= TRUE
;
1200 xpt_freeze_simq(aha
->sim
, /*count*/1);
1201 ccb
->ccb_h
.status
= CAM_REQUEUE_REQ
;
1206 paddr
= ahaccbvtop(aha
, accb
);
1207 ahautoa24(paddr
, aha
->cur_outbox
->ccb_addr
);
1208 aha
->cur_outbox
->action_code
= AMBO_START
;
1209 aha_outb(aha
, COMMAND_REG
, AOP_START_MBOX
);
1218 struct aha_softc
*aha
;
1221 aha
= (struct aha_softc
*)arg
;
1222 while (((intstat
= aha_inb(aha
, INTSTAT_REG
)) & INTR_PENDING
) != 0) {
1223 if ((intstat
& CMD_COMPLETE
) != 0) {
1224 aha
->latched_status
= aha_inb(aha
, STATUS_REG
);
1225 aha
->command_cmp
= TRUE
;
1228 aha_outb(aha
, CONTROL_REG
, RESET_INTR
);
1230 if ((intstat
& IMB_LOADED
) != 0) {
1231 while (aha
->cur_inbox
->comp_code
!= AMBI_FREE
) {
1233 paddr
= aha_a24tou(aha
->cur_inbox
->ccb_addr
);
1235 ahaccbptov(aha
, paddr
),
1236 aha
->cur_inbox
->comp_code
);
1237 aha
->cur_inbox
->comp_code
= AMBI_FREE
;
1242 if ((intstat
& SCSI_BUS_RESET
) != 0) {
1243 ahareset(aha
, /*hardreset*/FALSE
);
1249 ahadone(struct aha_softc
*aha
, struct aha_ccb
*accb
, aha_mbi_comp_code_t comp_code
)
1252 struct ccb_scsiio
*csio
;
1255 csio
= &accb
->ccb
->csio
;
1257 if ((accb
->flags
& ACCB_ACTIVE
) == 0) {
1258 device_printf(aha
->dev
,
1259 "ahadone - Attempt to free non-active ACCB %p\n",
1264 if ((ccb
->ccb_h
.flags
& CAM_DIR_MASK
) != CAM_DIR_NONE
) {
1265 bus_dmasync_op_t op
;
1267 if ((ccb
->ccb_h
.flags
& CAM_DIR_MASK
) == CAM_DIR_IN
)
1268 op
= BUS_DMASYNC_POSTREAD
;
1270 op
= BUS_DMASYNC_POSTWRITE
;
1271 bus_dmamap_sync(aha
->buffer_dmat
, accb
->dmamap
, op
);
1272 bus_dmamap_unload(aha
->buffer_dmat
, accb
->dmamap
);
1275 if (accb
== aha
->recovery_accb
) {
1277 * The recovery ACCB does not have a CCB associated
1278 * with it, so short circuit the normal error handling.
1279 * We now traverse our list of pending CCBs and process
1280 * any that were terminated by the recovery CCBs action.
1281 * We also reinstate timeouts for all remaining, pending,
1284 struct cam_path
*path
;
1285 struct ccb_hdr
*ccb_h
;
1288 /* Notify all clients that a BDR occured */
1289 error
= xpt_create_path(&path
, /*periph*/NULL
,
1290 cam_sim_path(aha
->sim
),
1294 if (error
== CAM_REQ_CMP
)
1295 xpt_async(AC_SENT_BDR
, path
, NULL
);
1297 ccb_h
= LIST_FIRST(&aha
->pending_ccbs
);
1298 while (ccb_h
!= NULL
) {
1299 struct aha_ccb
*pending_accb
;
1301 pending_accb
= (struct aha_ccb
*)ccb_h
->ccb_accb_ptr
;
1302 if (pending_accb
->hccb
.target
== accb
->hccb
.target
) {
1303 pending_accb
->hccb
.ahastat
= AHASTAT_HA_BDR
;
1304 ccb_h
= LIST_NEXT(ccb_h
, sim_links
.le
);
1305 ahadone(aha
, pending_accb
, AMBI_ERROR
);
1307 callout_reset(&ccb_h
->timeout_ch
,
1308 (ccb_h
->timeout
* hz
) / 1000,
1309 ahatimeout
, pending_accb
);
1310 ccb_h
= LIST_NEXT(ccb_h
, sim_links
.le
);
1313 device_printf(aha
->dev
, "No longer in timeout\n");
1317 callout_stop(&ccb
->ccb_h
.timeout_ch
);
1319 switch (comp_code
) {
1321 device_printf(aha
->dev
,
1322 "ahadone - CCB completed with free status!\n");
1324 case AMBI_NOT_FOUND
:
1325 device_printf(aha
->dev
,
1326 "ahadone - CCB Abort failed to find CCB\n");
1330 /* An error occured */
1331 if (accb
->hccb
.opcode
< INITIATOR_CCB_WRESID
)
1334 csio
->resid
= aha_a24tou(accb
->hccb
.data_len
);
1335 switch(accb
->hccb
.ahastat
) {
1336 case AHASTAT_DATARUN_ERROR
:
1338 if (csio
->resid
<= 0) {
1339 csio
->ccb_h
.status
= CAM_DATA_RUN_ERR
;
1344 case AHASTAT_NOERROR
:
1345 csio
->scsi_status
= accb
->hccb
.sdstat
;
1346 csio
->ccb_h
.status
|= CAM_SCSI_STATUS_ERROR
;
1347 switch(csio
->scsi_status
) {
1348 case SCSI_STATUS_CHECK_COND
:
1349 case SCSI_STATUS_CMD_TERMINATED
:
1350 csio
->ccb_h
.status
|= CAM_AUTOSNS_VALID
;
1352 * The aha writes the sense data at different
1353 * offsets based on the scsi cmd len
1355 bcopy((caddr_t
) &accb
->hccb
.scsi_cdb
+
1357 (caddr_t
) &csio
->sense_data
,
1358 accb
->hccb
.sense_len
);
1362 case SCSI_STATUS_OK
:
1363 csio
->ccb_h
.status
= CAM_REQ_CMP
;
1367 case AHASTAT_SELTIMEOUT
:
1368 csio
->ccb_h
.status
= CAM_SEL_TIMEOUT
;
1370 case AHASTAT_UNEXPECTED_BUSFREE
:
1371 csio
->ccb_h
.status
= CAM_UNEXP_BUSFREE
;
1373 case AHASTAT_INVALID_PHASE
:
1374 csio
->ccb_h
.status
= CAM_SEQUENCE_FAIL
;
1376 case AHASTAT_INVALID_ACTION_CODE
:
1377 panic("%s: Inavlid Action code", aha_name(aha
));
1379 case AHASTAT_INVALID_OPCODE
:
1380 if (accb
->hccb
.opcode
< INITIATOR_CCB_WRESID
)
1381 panic("%s: Invalid CCB Opcode %x hccb = %p",
1382 aha_name(aha
), accb
->hccb
.opcode
,
1384 device_printf(aha
->dev
,
1385 "AHA-1540A detected, compensating\n");
1386 aha
->ccb_sg_opcode
= INITIATOR_SG_CCB
;
1387 aha
->ccb_ccb_opcode
= INITIATOR_CCB
;
1388 xpt_freeze_devq(ccb
->ccb_h
.path
, /*count*/1);
1389 csio
->ccb_h
.status
= CAM_REQUEUE_REQ
;
1391 case AHASTAT_LINKED_CCB_LUN_MISMATCH
:
1392 /* We don't even support linked commands... */
1393 panic("%s: Linked CCB Lun Mismatch", aha_name(aha
));
1395 case AHASTAT_INVALID_CCB_OR_SG_PARAM
:
1396 panic("%s: Invalid CCB or SG list", aha_name(aha
));
1398 case AHASTAT_HA_SCSI_BUS_RESET
:
1399 if ((csio
->ccb_h
.status
& CAM_STATUS_MASK
)
1401 csio
->ccb_h
.status
= CAM_SCSI_BUS_RESET
;
1403 case AHASTAT_HA_BDR
:
1404 if ((accb
->flags
& ACCB_DEVICE_RESET
) == 0)
1405 csio
->ccb_h
.status
= CAM_BDR_SENT
;
1407 csio
->ccb_h
.status
= CAM_CMD_TIMEOUT
;
1410 if (csio
->ccb_h
.status
!= CAM_REQ_CMP
) {
1411 xpt_freeze_devq(csio
->ccb_h
.path
, /*count*/1);
1412 csio
->ccb_h
.status
|= CAM_DEV_QFRZN
;
1414 if ((accb
->flags
& ACCB_RELEASE_SIMQ
) != 0)
1415 ccb
->ccb_h
.status
|= CAM_RELEASE_SIMQ
;
1416 ahafreeccb(aha
, accb
);
1420 /* All completed without incident */
1421 /* XXX DO WE NEED TO COPY SENSE BYTES HERE???? XXX */
1422 /* I don't think so since it works???? */
1423 ccb
->ccb_h
.status
|= CAM_REQ_CMP
;
1424 if ((accb
->flags
& ACCB_RELEASE_SIMQ
) != 0)
1425 ccb
->ccb_h
.status
|= CAM_RELEASE_SIMQ
;
1426 ahafreeccb(aha
, accb
);
1433 ahareset(struct aha_softc
* aha
, int hard_reset
)
1435 struct ccb_hdr
*ccb_h
;
1438 u_int8_t reset_type
;
1440 if (hard_reset
!= 0)
1441 reset_type
= HARD_RESET
;
1443 reset_type
= SOFT_RESET
;
1444 aha_outb(aha
, CONTROL_REG
, reset_type
);
1446 /* Wait 5sec. for Diagnostic start */
1447 timeout
= 5 * 10000;
1449 status
= aha_inb(aha
, STATUS_REG
);
1450 if ((status
& DIAG_ACTIVE
) != 0)
1455 PRVERB((aha
->dev
, "ahareset - Diagnostic Active failed to "
1456 "assert. status = 0x%x\n", status
));
1460 /* Wait 10sec. for Diagnostic end */
1461 timeout
= 10 * 10000;
1463 status
= aha_inb(aha
, STATUS_REG
);
1464 if ((status
& DIAG_ACTIVE
) == 0)
1469 panic("%s: ahareset - Diagnostic Active failed to drop. "
1470 "status = 0x%x\n", aha_name(aha
), status
);
1474 /* Wait for the host adapter to become ready or report a failure */
1477 status
= aha_inb(aha
, STATUS_REG
);
1478 if ((status
& (DIAG_FAIL
|HA_READY
|DATAIN_REG_READY
)) != 0)
1483 device_printf(aha
->dev
, "ahareset - Host adapter failed to "
1484 "come ready. status = 0x%x\n", status
);
1488 /* If the diagnostics failed, tell the user */
1489 if ((status
& DIAG_FAIL
) != 0
1490 || (status
& HA_READY
) == 0) {
1491 device_printf(aha
->dev
, "ahareset - Adapter failed diagnostics\n");
1492 if ((status
& DATAIN_REG_READY
) != 0)
1493 device_printf(aha
->dev
, "ahareset - Host Adapter "
1494 "Error code = 0x%x\n", aha_inb(aha
, DATAIN_REG
));
1498 /* If we've allocated mailboxes, initialize them */
1499 if (aha
->init_level
> 4)
1502 /* If we've attached to the XPT, tell it about the event */
1503 if (aha
->path
!= NULL
)
1504 xpt_async(AC_BUS_RESET
, aha
->path
, NULL
);
1507 * Perform completion processing for all outstanding CCBs.
1509 while ((ccb_h
= LIST_FIRST(&aha
->pending_ccbs
)) != NULL
) {
1510 struct aha_ccb
*pending_accb
;
1512 pending_accb
= (struct aha_ccb
*)ccb_h
->ccb_accb_ptr
;
1513 pending_accb
->hccb
.ahastat
= AHASTAT_HA_SCSI_BUS_RESET
;
1514 ahadone(aha
, pending_accb
, AMBI_ERROR
);
1521 * Send a command to the adapter.
1524 aha_cmd(struct aha_softc
*aha
, aha_op_t opcode
, u_int8_t
*params
,
1525 u_int param_len
, u_int8_t
*reply_data
, u_int reply_len
,
1532 u_int reply_buf_size
;
1536 /* No data returned to start */
1537 reply_buf_size
= reply_len
;
1545 * All commands except for the "start mailbox" and the "enable
1546 * outgoing mailbox read interrupt" commands cannot be issued
1547 * while there are pending transactions. Freeze our SIMQ
1548 * and wait for all completions to occur if necessary.
1552 while (LIST_FIRST(&aha
->pending_ccbs
) != NULL
&& --timeout
) {
1553 /* Fire the interrupt handler in case interrupts are blocked */
1562 device_printf(aha
->dev
, "aha_cmd: Timeout waiting for adapter idle\n");
1565 aha
->command_cmp
= 0;
1567 * Wait up to 10 sec. for the adapter to become
1568 * ready to accept commands.
1573 status
= aha_inb(aha
, STATUS_REG
);
1574 if ((status
& HA_READY
) != 0
1575 && (status
& CMD_REG_BUSY
) == 0)
1578 * Throw away any pending data which may be
1579 * left over from earlier commands that we
1582 if ((status
& DATAIN_REG_READY
) != 0)
1583 (void)aha_inb(aha
, DATAIN_REG
);
1587 device_printf(aha
->dev
, "aha_cmd: Timeout waiting for adapter "
1588 "ready, status = 0x%x\n", status
);
1593 * Send the opcode followed by any necessary parameter bytes.
1595 aha_outb(aha
, COMMAND_REG
, opcode
);
1598 * Wait for up to 1sec to get the parameter list sent
1601 while (param_len
&& --timeout
) {
1604 status
= aha_inb(aha
, STATUS_REG
);
1605 intstat
= aha_inb(aha
, INTSTAT_REG
);
1608 if ((intstat
& (INTR_PENDING
|CMD_COMPLETE
))
1609 == (INTR_PENDING
|CMD_COMPLETE
)) {
1610 saved_status
= status
;
1615 if (aha
->command_cmp
!= 0) {
1616 saved_status
= aha
->latched_status
;
1620 if ((status
& DATAIN_REG_READY
) != 0)
1622 if ((status
& CMD_REG_BUSY
) == 0) {
1623 aha_outb(aha
, COMMAND_REG
, *params
++);
1629 device_printf(aha
->dev
, "aha_cmd: Timeout sending parameters, "
1630 "status = 0x%x\n", status
);
1635 * For all other commands, we wait for any output data
1636 * and the final comand completion interrupt.
1638 while (cmd_complete
== 0 && --cmd_timeout
) {
1641 status
= aha_inb(aha
, STATUS_REG
);
1642 intstat
= aha_inb(aha
, INTSTAT_REG
);
1645 if (aha
->command_cmp
!= 0) {
1647 saved_status
= aha
->latched_status
;
1648 } else if ((intstat
& (INTR_PENDING
|CMD_COMPLETE
))
1649 == (INTR_PENDING
|CMD_COMPLETE
)) {
1651 * Our poll (in case interrupts are blocked)
1652 * saw the CMD_COMPLETE interrupt.
1655 saved_status
= status
;
1657 if ((status
& DATAIN_REG_READY
) != 0) {
1660 data
= aha_inb(aha
, DATAIN_REG
);
1661 if (reply_len
< reply_buf_size
) {
1662 *reply_data
++ = data
;
1664 device_printf(aha
->dev
, "aha_cmd - Discarded reply data "
1665 "byte for opcode 0x%x\n", opcode
);
1668 * Reset timeout to ensure at least a second
1669 * between response bytes.
1671 cmd_timeout
= MAX(cmd_timeout
, 10000);
1676 if (cmd_timeout
== 0) {
1677 device_printf(aha
->dev
, "aha_cmd: Timeout: status = 0x%x, "
1678 "intstat = 0x%x, reply_len = %d\n", status
, intstat
,
1684 * Clear any pending interrupts. Block interrupts so our
1685 * interrupt handler is not re-entered.
1695 * If the command was rejected by the controller, tell the caller.
1697 if ((saved_status
& CMD_INVALID
) != 0) {
1698 PRVERB((aha
->dev
, "Invalid Command 0x%x\n", opcode
));
1700 * Some early adapters may not recover properly from
1701 * an invalid command. If it appears that the controller
1702 * has wedged (i.e. status was not cleared by our interrupt
1703 * reset above), perform a soft reset.
1706 status
= aha_inb(aha
, STATUS_REG
);
1707 if ((status
& (CMD_INVALID
|STATUS_REG_RSVD
|DATAIN_REG_READY
|
1708 CMD_REG_BUSY
|DIAG_FAIL
|DIAG_ACTIVE
)) != 0
1709 || (status
& (HA_READY
|INIT_REQUIRED
))
1710 != (HA_READY
|INIT_REQUIRED
)) {
1711 ahareset(aha
, /*hard_reset*/FALSE
);
1716 if (param_len
> 0) {
1717 /* The controller did not accept the full argument list */
1718 PRVERB((aha
->dev
, "Controller did not accept full argument "
1719 "list (%d > 0)\n", param_len
));
1723 if (reply_len
!= reply_buf_size
) {
1724 /* Too much or too little data received */
1725 PRVERB((aha
->dev
,"data received mistmatch (%d != %d)\n",
1726 reply_len
, reply_buf_size
));
1730 /* We were successful */
1735 ahainitmboxes(struct aha_softc
*aha
)
1738 init_24b_mbox_params_t init_mbox
;
1740 bzero(aha
->in_boxes
, sizeof(aha_mbox_in_t
) * aha
->num_boxes
);
1741 bzero(aha
->out_boxes
, sizeof(aha_mbox_out_t
) * aha
->num_boxes
);
1742 aha
->cur_inbox
= aha
->in_boxes
;
1743 aha
->last_inbox
= aha
->in_boxes
+ aha
->num_boxes
- 1;
1744 aha
->cur_outbox
= aha
->out_boxes
;
1745 aha
->last_outbox
= aha
->out_boxes
+ aha
->num_boxes
- 1;
1747 /* Tell the adapter about them */
1748 init_mbox
.num_mboxes
= aha
->num_boxes
;
1749 ahautoa24(aha
->mailbox_physbase
, init_mbox
.base_addr
);
1750 error
= aha_cmd(aha
, AOP_INITIALIZE_MBOX
, (u_int8_t
*)&init_mbox
,
1751 /*parmlen*/sizeof(init_mbox
), /*reply_buf*/NULL
,
1752 /*reply_len*/0, DEFAULT_CMD_TIMEOUT
);
1755 device_printf(aha
->dev
,
1756 "ahainitmboxes: Initialization command failed\n");
1761 * Update the XPT's idea of the negotiated transfer
1762 * parameters for a particular target.
1765 ahafetchtransinfo(struct aha_softc
*aha
, struct ccb_trans_settings
* cts
)
1767 setup_data_t setup_info
;
1773 targ_syncinfo_t sync_info
;
1774 struct ccb_trans_settings_spi
*spi
= &cts
->xport_specific
.spi
;
1776 target
= cts
->ccb_h
.target_id
;
1777 targ_offset
= (target
& 0x7);
1780 * Inquire Setup Information. This command retreives
1781 * the sync info for older models.
1783 param
= sizeof(setup_info
);
1784 error
= aha_cmd(aha
, AOP_INQUIRE_SETUP_INFO
, ¶m
, /*paramlen*/1,
1785 (u_int8_t
*)&setup_info
, sizeof(setup_info
),
1786 DEFAULT_CMD_TIMEOUT
);
1789 device_printf(aha
->dev
,
1790 "ahafetchtransinfo - Inquire Setup Info Failed %d\n",
1795 sync_info
= setup_info
.syncinfo
[targ_offset
];
1797 if (sync_info
.sync
== 0)
1798 spi
->sync_offset
= 0;
1800 spi
->sync_offset
= sync_info
.offset
;
1802 spi
->bus_width
= MSG_EXT_WDTR_BUS_8_BIT
;
1804 if (aha
->boardid
>= BOARD_1542CF
)
1808 sync_period
+= 500 * sync_info
.period
;
1810 /* Convert ns value to standard SCSI sync rate */
1811 if (spi
->sync_offset
!= 0)
1812 spi
->sync_period
= scsi_calc_syncparam(sync_period
);
1814 spi
->sync_period
= 0;
1816 spi
->valid
= CTS_SPI_VALID_SYNC_RATE
1817 | CTS_SPI_VALID_SYNC_OFFSET
1818 | CTS_SPI_VALID_BUS_WIDTH
;
1819 xpt_async(AC_TRANSFER_NEG
, cts
->ccb_h
.path
, cts
);
1823 ahamapmboxes(void *arg
, bus_dma_segment_t
*segs
, int nseg
, int error
)
1825 struct aha_softc
* aha
;
1827 aha
= (struct aha_softc
*)arg
;
1828 aha
->mailbox_physbase
= segs
->ds_addr
;
1832 ahamapccbs(void *arg
, bus_dma_segment_t
*segs
, int nseg
, int error
)
1834 struct aha_softc
* aha
;
1836 aha
= (struct aha_softc
*)arg
;
1837 aha
->aha_ccb_physbase
= segs
->ds_addr
;
1841 ahamapsgs(void *arg
, bus_dma_segment_t
*segs
, int nseg
, int error
)
1844 struct aha_softc
* aha
;
1846 aha
= (struct aha_softc
*)arg
;
1847 SLIST_FIRST(&aha
->sg_maps
)->sg_physaddr
= segs
->ds_addr
;
1851 ahapoll(struct cam_sim
*sim
)
1853 aha_intr(cam_sim_softc(sim
));
1857 ahatimeout(void *arg
)
1859 struct aha_ccb
*accb
;
1861 struct aha_softc
*aha
;
1864 accb
= (struct aha_ccb
*)arg
;
1866 aha
= (struct aha_softc
*)ccb
->ccb_h
.ccb_aha_ptr
;
1867 xpt_print_path(ccb
->ccb_h
.path
);
1868 kprintf("CCB %p - timed out\n", (void *)accb
);
1872 if ((accb
->flags
& ACCB_ACTIVE
) == 0) {
1873 xpt_print_path(ccb
->ccb_h
.path
);
1874 kprintf("CCB %p - timed out CCB already completed\n",
1881 * In order to simplify the recovery process, we ask the XPT
1882 * layer to halt the queue of new transactions and we traverse
1883 * the list of pending CCBs and remove their timeouts. This
1884 * means that the driver attempts to clear only one error
1885 * condition at a time. In general, timeouts that occur
1886 * close together are related anyway, so there is no benefit
1887 * in attempting to handle errors in parrallel. Timeouts will
1888 * be reinstated when the recovery process ends.
1890 if ((accb
->flags
& ACCB_DEVICE_RESET
) == 0) {
1891 struct ccb_hdr
*ccb_h
;
1893 if ((accb
->flags
& ACCB_RELEASE_SIMQ
) == 0) {
1894 xpt_freeze_simq(aha
->sim
, /*count*/1);
1895 accb
->flags
|= ACCB_RELEASE_SIMQ
;
1898 ccb_h
= LIST_FIRST(&aha
->pending_ccbs
);
1899 while (ccb_h
!= NULL
) {
1900 struct aha_ccb
*pending_accb
;
1902 pending_accb
= (struct aha_ccb
*)ccb_h
->ccb_accb_ptr
;
1903 callout_stop(&ccb_h
->timeout_ch
);
1904 ccb_h
= LIST_NEXT(ccb_h
, sim_links
.le
);
1908 if ((accb
->flags
& ACCB_DEVICE_RESET
) != 0
1909 || aha
->cur_outbox
->action_code
!= AMBO_FREE
) {
1911 * Try a full host adapter/SCSI bus reset.
1912 * We do this only if we have already attempted
1913 * to clear the condition with a BDR, or we cannot
1914 * attempt a BDR for lack of mailbox resources.
1916 ccb
->ccb_h
.status
= CAM_CMD_TIMEOUT
;
1917 ahareset(aha
, /*hardreset*/TRUE
);
1918 device_printf(aha
->dev
, "No longer in timeout\n");
1921 * Send a Bus Device Reset message:
1922 * The target that is holding up the bus may not
1923 * be the same as the one that triggered this timeout
1924 * (different commands have different timeout lengths),
1925 * but we have no way of determining this from our
1926 * timeout handler. Our strategy here is to queue a
1927 * BDR message to the target of the timed out command.
1928 * If this fails, we'll get another timeout 2 seconds
1929 * later which will attempt a bus reset.
1931 accb
->flags
|= ACCB_DEVICE_RESET
;
1932 callout_reset(&ccb
->ccb_h
.timeout_ch
, 2 * hz
, ahatimeout
, accb
);
1933 aha
->recovery_accb
->hccb
.opcode
= INITIATOR_BUS_DEV_RESET
;
1935 /* No Data Transfer */
1936 aha
->recovery_accb
->hccb
.datain
= TRUE
;
1937 aha
->recovery_accb
->hccb
.dataout
= TRUE
;
1938 aha
->recovery_accb
->hccb
.ahastat
= 0;
1939 aha
->recovery_accb
->hccb
.sdstat
= 0;
1940 aha
->recovery_accb
->hccb
.target
= ccb
->ccb_h
.target_id
;
1942 /* Tell the adapter about this command */
1943 paddr
= ahaccbvtop(aha
, aha
->recovery_accb
);
1944 ahautoa24(paddr
, aha
->cur_outbox
->ccb_addr
);
1945 aha
->cur_outbox
->action_code
= AMBO_START
;
1946 aha_outb(aha
, COMMAND_REG
, AOP_START_MBOX
);
1954 aha_detach(struct aha_softc
*aha
)
1956 xpt_async(AC_LOST_DEVICE
, aha
->path
, NULL
);
1957 xpt_free_path(aha
->path
);
1958 xpt_bus_deregister(cam_sim_path(aha
->sim
));
1959 cam_sim_free(aha
->sim
);