2 * CAM SCSI device driver for the Adaptec 174X SCSI Host adapter
4 * Copyright (c) 1998 Justin T. Gibbs
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice immediately at the beginning of the file, without modification,
12 * this list of conditions, and the following disclaimer.
13 * 2. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
20 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * $FreeBSD: src/sys/dev/ahb/ahb.c,v 1.18.2.3 2001/03/05 13:08:55 obrien Exp $
29 * $DragonFly: src/sys/dev/disk/ahb/ahb.c,v 1.16 2007/12/02 03:54:16 pavalos Exp $
32 #include <sys/param.h>
33 #include <sys/systm.h>
34 #include <sys/kernel.h>
35 #include <sys/malloc.h>
36 #include <sys/module.h>
39 #include <sys/thread2.h>
41 #include <machine/clock.h>
43 #include <bus/cam/cam.h>
44 #include <bus/cam/cam_ccb.h>
45 #include <bus/cam/cam_sim.h>
46 #include <bus/cam/cam_xpt_sim.h>
47 #include <bus/cam/cam_debug.h>
49 #include <bus/cam/scsi/scsi_message.h>
51 #include <bus/eisa/eisaconf.h>
55 #define ccb_ecb_ptr spriv_ptr0
56 #define ccb_ahb_ptr spriv_ptr1
58 #define ahb_inb(ahb, port) \
59 bus_space_read_1((ahb)->tag, (ahb)->bsh, port)
61 #define ahb_inl(ahb, port) \
62 bus_space_read_4((ahb)->tag, (ahb)->bsh, port)
64 #define ahb_outb(ahb, port, value) \
65 bus_space_write_1((ahb)->tag, (ahb)->bsh, port, value)
67 #define ahb_outl(ahb, port, value) \
68 bus_space_write_4((ahb)->tag, (ahb)->bsh, port, value)
70 static const char *ahbmatch(eisa_id_t type
);
71 static struct ahb_softc
*ahballoc(u_long unit
, struct resource
*res
);
72 static void ahbfree(struct ahb_softc
*ahb
);
73 static int ahbreset(struct ahb_softc
*ahb
);
74 static void ahbmapecbs(void *arg
, bus_dma_segment_t
*segs
,
76 static int ahbxptattach(struct ahb_softc
*ahb
);
77 static void ahbhandleimmed(struct ahb_softc
*ahb
,
78 u_int32_t mbox
, u_int intstat
);
79 static void ahbcalcresid(struct ahb_softc
*ahb
,
80 struct ecb
*ecb
, union ccb
*ccb
);
81 static __inline
void ahbdone(struct ahb_softc
*ahb
, u_int32_t mbox
,
83 static void ahbintr(void *arg
);
84 static bus_dmamap_callback_t ahbexecuteecb
;
85 static void ahbaction(struct cam_sim
*sim
, union ccb
*ccb
);
86 static void ahbpoll(struct cam_sim
*sim
);
88 /* Our timeout handler */
89 static timeout_t ahbtimeout
;
91 static __inline
struct ecb
* ahbecbget(struct ahb_softc
*ahb
);
92 static __inline
void ahbecbfree(struct ahb_softc
* ahb
,
94 static __inline u_int32_t
ahbecbvtop(struct ahb_softc
*ahb
,
96 static __inline
struct ecb
* ahbecbptov(struct ahb_softc
*ahb
,
98 static __inline u_int32_t
ahbstatuspaddr(u_int32_t ecb_paddr
);
99 static __inline u_int32_t
ahbsensepaddr(u_int32_t ecb_paddr
);
100 static __inline u_int32_t
ahbsgpaddr(u_int32_t ecb_paddr
);
101 static __inline
void ahbqueuembox(struct ahb_softc
*ahb
,
105 static __inline
struct ecb
*
106 ahbecbget(struct ahb_softc
*ahb
)
111 if ((ecb
= SLIST_FIRST(&ahb
->free_ecbs
)) != NULL
)
112 SLIST_REMOVE_HEAD(&ahb
->free_ecbs
, links
);
119 ahbecbfree(struct ahb_softc
* ahb
, struct ecb
* ecb
)
122 ecb
->state
= ECB_FREE
;
123 SLIST_INSERT_HEAD(&ahb
->free_ecbs
, ecb
, links
);
127 static __inline u_int32_t
128 ahbecbvtop(struct ahb_softc
*ahb
, struct ecb
*ecb
)
130 return (ahb
->ecb_physbase
131 + (u_int32_t
)((caddr_t
)ecb
- (caddr_t
)ahb
->ecb_array
));
134 static __inline
struct ecb
*
135 ahbecbptov(struct ahb_softc
*ahb
, u_int32_t ecb_addr
)
137 return (ahb
->ecb_array
138 + ((struct ecb
*)ecb_addr
- (struct ecb
*)ahb
->ecb_physbase
));
141 static __inline u_int32_t
142 ahbstatuspaddr(u_int32_t ecb_paddr
)
144 return (ecb_paddr
+ offsetof(struct ecb
, status
));
147 static __inline u_int32_t
148 ahbsensepaddr(u_int32_t ecb_paddr
)
150 return (ecb_paddr
+ offsetof(struct ecb
, sense
));
153 static __inline u_int32_t
154 ahbsgpaddr(u_int32_t ecb_paddr
)
156 return (ecb_paddr
+ offsetof(struct ecb
, sg_list
));
160 ahbqueuembox(struct ahb_softc
*ahb
, u_int32_t mboxval
, u_int attn_code
)
166 status
= ahb_inb(ahb
, HOSTSTAT
);
167 if ((status
& (HOSTSTAT_MBOX_EMPTY
|HOSTSTAT_BUSY
))
168 == HOSTSTAT_MBOX_EMPTY
)
173 panic("ahb%ld: adapter not taking commands\n", ahb
->unit
);
175 ahb_outl(ahb
, MBOXOUT0
, mboxval
);
176 ahb_outb(ahb
, ATTN
, attn_code
);
180 ahbmatch(eisa_id_t type
)
182 switch(type
& 0xfffffe00) {
183 case EISA_DEVICE_ID_ADAPTEC_1740
:
184 return ("Adaptec 174x SCSI host adapter");
193 ahbprobe(device_t dev
)
201 desc
= ahbmatch(eisa_get_id(dev
));
204 device_set_desc(dev
, desc
);
206 iobase
= (eisa_get_slot(dev
) * EISA_SLOT_SIZE
) +
207 AHB_EISA_SLOT_OFFSET
;
209 eisa_add_iospace(dev
, iobase
, AHB_EISA_IOSIZE
, RESVADDR_NONE
);
211 intdef
= inb(INTDEF
+ iobase
);
212 switch (intdef
& 0x7) {
232 kprintf("Adaptec 174X at slot %d: illegal "
233 "irq setting %d\n", eisa_get_slot(dev
),
241 shared
= (inb(INTDEF
+ iobase
) & INTLEVEL
) ?
242 EISA_TRIGGER_LEVEL
: EISA_TRIGGER_EDGE
;
244 eisa_add_intr(dev
, irq
, shared
);
250 ahbattach(device_t dev
)
253 * find unit and check we have that many defined
255 struct ahb_softc
*ahb
;
256 struct ecb
* next_ecb
;
257 struct resource
*io
= 0;
258 struct resource
*irq
= 0;
263 io
= bus_alloc_resource(dev
, SYS_RES_IOPORT
, &rid
,
264 0, ~0, 1, RF_ACTIVE
);
266 device_printf(dev
, "No I/O space?!\n");
270 if ((ahb
= ahballoc(device_get_unit(dev
), io
)) == NULL
) {
274 if (ahbreset(ahb
) != 0)
278 irq
= bus_alloc_resource(dev
, SYS_RES_IRQ
, &rid
,
279 0, ~0, 1, RF_ACTIVE
);
281 device_printf(dev
, "Can't allocate interrupt\n");
286 * Create our DMA tags. These tags define the kinds of device
287 * accessible memory allocations and memory mappings we will
288 * need to perform during normal operation.
290 /* DMA tag for mapping buffers into device visible space. */
291 /* XXX Should be a child of the EISA bus dma tag */
292 if (bus_dma_tag_create(/*parent*/NULL
, /*alignment*/1, /*boundary*/0,
293 /*lowaddr*/BUS_SPACE_MAXADDR_32BIT
,
294 /*highaddr*/BUS_SPACE_MAXADDR
,
295 /*filter*/NULL
, /*filterarg*/NULL
,
296 /*maxsize*/MAXBSIZE
, /*nsegments*/AHB_NSEG
,
297 /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT
,
298 /*flags*/BUS_DMA_ALLOCNOW
,
299 &ahb
->buffer_dmat
) != 0)
304 /* DMA tag for our ccb structures and ha inquiry data */
305 if (bus_dma_tag_create(/*parent*/NULL
, /*alignment*/1, /*boundary*/0,
306 /*lowaddr*/BUS_SPACE_MAXADDR_32BIT
,
307 /*highaddr*/BUS_SPACE_MAXADDR
,
308 /*filter*/NULL
, /*filterarg*/NULL
,
309 (AHB_NECB
* sizeof(struct ecb
))
310 + sizeof(*ahb
->ha_inq_data
),
312 /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT
,
313 /*flags*/0, &ahb
->ecb_dmat
) != 0)
318 /* Allocation for our ccbs */
319 if (bus_dmamem_alloc(ahb
->ecb_dmat
, (void **)&ahb
->ecb_array
,
320 BUS_DMA_NOWAIT
, &ahb
->ecb_dmamap
) != 0)
323 ahb
->ha_inq_data
= (struct ha_inquiry_data
*)&ahb
->ecb_array
[AHB_NECB
];
327 /* And permanently map them */
328 bus_dmamap_load(ahb
->ecb_dmat
, ahb
->ecb_dmamap
,
329 ahb
->ecb_array
, AHB_NSEG
* sizeof(struct ecb
),
330 ahbmapecbs
, ahb
, /*flags*/0);
334 /* Allocate the buffer dmamaps for each of our ECBs */
335 bzero(ahb
->ecb_array
, (AHB_NECB
* sizeof(struct ecb
))
336 + sizeof(*ahb
->ha_inq_data
));
337 next_ecb
= ahb
->ecb_array
;
338 while (ahb
->num_ecbs
< AHB_NECB
) {
341 if (bus_dmamap_create(ahb
->buffer_dmat
, /*flags*/0,
344 ecb_paddr
= ahbecbvtop(ahb
, next_ecb
);
345 next_ecb
->hecb
.status_ptr
= ahbstatuspaddr(ecb_paddr
);
346 next_ecb
->hecb
.sense_ptr
= ahbsensepaddr(ecb_paddr
);
348 ahbecbfree(ahb
, next_ecb
);
352 if (ahb
->num_ecbs
== 0)
358 * Now that we know we own the resources we need, register
359 * our bus with the XPT.
361 if (ahbxptattach(ahb
))
364 /* Enable our interrupt */
365 bus_setup_intr(dev
, irq
, 0, ahbintr
, ahb
, &ih
, NULL
);
370 * The board's IRQ line will not be left enabled
371 * if we can't intialize correctly, so its safe
372 * to release the irq.
377 bus_release_resource(dev
, SYS_RES_IOPORT
, 0, io
);
379 bus_release_resource(dev
, SYS_RES_IRQ
, 0, irq
);
383 static struct ahb_softc
*
384 ahballoc(u_long unit
, struct resource
*res
)
386 struct ahb_softc
*ahb
;
389 * Allocate a storage area for us
391 ahb
= kmalloc(sizeof(struct ahb_softc
), M_DEVBUF
, M_INTWAIT
| M_ZERO
);
392 SLIST_INIT(&ahb
->free_ecbs
);
393 LIST_INIT(&ahb
->pending_ccbs
);
395 ahb
->tag
= rman_get_bustag(res
);
396 ahb
->bsh
= rman_get_bushandle(res
);
397 ahb
->disc_permitted
= ~0;
398 ahb
->tags_permitted
= ~0;
404 ahbfree(struct ahb_softc
*ahb
)
406 switch (ahb
->init_level
) {
409 bus_dmamap_unload(ahb
->ecb_dmat
, ahb
->ecb_dmamap
);
412 bus_dmamem_free(ahb
->ecb_dmat
, ahb
->ecb_array
,
414 bus_dmamap_destroy(ahb
->ecb_dmat
, ahb
->ecb_dmamap
);
417 bus_dma_tag_destroy(ahb
->ecb_dmat
);
420 bus_dma_tag_destroy(ahb
->buffer_dmat
);
425 kfree(ahb
, M_DEVBUF
);
429 * reset board, If it doesn't respond, return failure
432 ahbreset(struct ahb_softc
*ahb
)
434 int wait
= 1000; /* 1 sec enough? */
437 if ((ahb_inb(ahb
, PORTADDR
) & PORTADDR_ENHANCED
) == 0) {
438 kprintf("ahb_reset: Controller not in enhanced mode\n");
442 ahb_outb(ahb
, CONTROL
, CNTRL_HARD_RST
);
444 ahb_outb(ahb
, CONTROL
, 0);
447 if ((ahb_inb(ahb
, HOSTSTAT
) & HOSTSTAT_BUSY
) == 0)
452 kprintf("ahbreset: No answer from aha1742 board\n");
455 if ((test
= ahb_inb(ahb
, MBOXIN0
)) != 0) {
456 kprintf("ahb_reset: self test failed, val = 0x%x\n", test
);
459 while (ahb_inb(ahb
, HOSTSTAT
) & HOSTSTAT_INTPEND
) {
460 ahb_outb(ahb
, CONTROL
, CNTRL_CLRINT
);
467 ahbmapecbs(void *arg
, bus_dma_segment_t
*segs
, int nseg
, int error
)
469 struct ahb_softc
* ahb
;
471 ahb
= (struct ahb_softc
*)arg
;
472 ahb
->ecb_physbase
= segs
->ds_addr
;
474 * Space for adapter inquiry information is on the
475 * tail of the ecb array.
477 ahb
->ha_inq_physbase
= ahbecbvtop(ahb
, &ahb
->ecb_array
[AHB_NECB
]);
481 ahbxptattach(struct ahb_softc
*ahb
)
486 /* Remeber who are we on the scsi bus */
487 ahb
->scsi_id
= ahb_inb(ahb
, SCSIDEF
) & HSCSIID
;
489 /* Use extended translation?? */
490 ahb
->extended_trans
= ahb_inb(ahb
, RESV1
) & EXTENDED_TRANS
;
492 /* Fetch adapter inquiry data */
493 ecb
= ahbecbget(ahb
); /* Always succeeds - no outstanding commands */
494 ecb
->hecb
.opcode
= ECBOP_READ_HA_INQDATA
;
495 ecb
->hecb
.flag_word1
= FW1_SUPPRESS_URUN_ERR
|FW1_ERR_STATUS_BLK_ONLY
;
496 ecb
->hecb
.data_ptr
= ahb
->ha_inq_physbase
;
497 ecb
->hecb
.data_len
= sizeof(struct ha_inquiry_data
);
498 ecb
->hecb
.sense_ptr
= 0;
499 ecb
->state
= ECB_ACTIVE
;
501 /* Tell the adapter about this command */
502 ahbqueuembox(ahb
, ahbecbvtop(ahb
, ecb
),
503 ATTN_STARTECB
|ahb
->scsi_id
);
505 /* Poll for interrupt completion */
506 for (i
= 1000; ecb
->state
!= ECB_FREE
&& i
!= 0; i
--) {
511 ahb
->num_ecbs
= MIN(ahb
->num_ecbs
,
512 ahb
->ha_inq_data
->scsi_data
.spc2_flags
);
513 kprintf("ahb%ld: %.8s %s SCSI Adapter, FW Rev. %.4s, ID=%d, %d ECBs\n",
514 ahb
->unit
, ahb
->ha_inq_data
->scsi_data
.product
,
515 (ahb
->ha_inq_data
->scsi_data
.flags
& 0x4) ? "Differential"
517 ahb
->ha_inq_data
->scsi_data
.revision
,
518 ahb
->scsi_id
, ahb
->num_ecbs
);
520 /* Restore sense paddr for future CCB clients */
521 ecb
->hecb
.sense_ptr
= ahbsensepaddr(ahbecbvtop(ahb
, ecb
));
523 ahbecbfree(ahb
, ecb
);
526 * Construct our SIM entry
528 ahb
->sim
= cam_sim_alloc(ahbaction
, ahbpoll
, "ahb", ahb
, ahb
->unit
,
529 2, ahb
->num_ecbs
, NULL
);
530 if (ahb
->sim
== NULL
)
533 if (xpt_bus_register(ahb
->sim
, 0) != CAM_SUCCESS
) {
534 cam_sim_free(ahb
->sim
);
538 if (xpt_create_path(&ahb
->path
, /*periph*/NULL
,
539 cam_sim_path(ahb
->sim
), CAM_TARGET_WILDCARD
,
540 CAM_LUN_WILDCARD
) != CAM_REQ_CMP
) {
541 xpt_bus_deregister(cam_sim_path(ahb
->sim
));
542 cam_sim_free(ahb
->sim
);
547 * Allow the board to generate interrupts.
549 ahb_outb(ahb
, INTDEF
, ahb_inb(ahb
, INTDEF
) | INTEN
);
555 ahbhandleimmed(struct ahb_softc
*ahb
, u_int32_t mbox
, u_int intstat
)
557 struct ccb_hdr
*ccb_h
;
560 if (ahb
->immed_cmd
== 0) {
561 kprintf("ahb%ld: Immediate Command complete with no "
562 " pending command\n", ahb
->unit
);
566 target_id
= intstat
& INTSTAT_TARGET_MASK
;
568 ccb_h
= LIST_FIRST(&ahb
->pending_ccbs
);
569 while (ccb_h
!= NULL
) {
570 struct ecb
*pending_ecb
;
573 pending_ecb
= (struct ecb
*)ccb_h
->ccb_ecb_ptr
;
574 ccb
= pending_ecb
->ccb
;
575 ccb_h
= LIST_NEXT(ccb_h
, sim_links
.le
);
576 if (ccb
->ccb_h
.target_id
== target_id
577 || target_id
== ahb
->scsi_id
) {
578 callout_stop(&ccb
->ccb_h
.timeout_ch
);
579 LIST_REMOVE(&ccb
->ccb_h
, sim_links
.le
);
580 if ((ccb
->ccb_h
.flags
& CAM_DIR_MASK
) != CAM_DIR_NONE
)
581 bus_dmamap_unload(ahb
->buffer_dmat
,
582 pending_ecb
->dmamap
);
583 if (pending_ecb
== ahb
->immed_ecb
)
585 CAM_CMD_TIMEOUT
|CAM_RELEASE_SIMQ
;
586 else if (target_id
== ahb
->scsi_id
)
587 ccb
->ccb_h
.status
= CAM_SCSI_BUS_RESET
;
589 ccb
->ccb_h
.status
= CAM_BDR_SENT
;
590 ahbecbfree(ahb
, pending_ecb
);
592 } else if (ahb
->immed_ecb
!= NULL
) {
593 /* Re-instate timeout */
594 callout_reset(&ccb
->ccb_h
.timeout_ch
,
595 (ccb
->ccb_h
.timeout
* hz
) / 1000,
596 ahbtimeout
, pending_ecb
);
600 if (ahb
->immed_ecb
!= NULL
) {
601 ahb
->immed_ecb
= NULL
;
602 kprintf("ahb%ld: No longer in timeout\n", ahb
->unit
);
603 } else if (target_id
== ahb
->scsi_id
)
604 kprintf("ahb%ld: SCSI Bus Reset Delivered\n", ahb
->unit
);
606 kprintf("ahb%ld: Bus Device Reset Delivered to target %d\n",
607 ahb
->unit
, target_id
);
613 ahbcalcresid(struct ahb_softc
*ahb
, struct ecb
*ecb
, union ccb
*ccb
)
615 if (ecb
->status
.data_overrun
!= 0) {
617 * Overrun Condition. The hardware doesn't
618 * provide a meaningful byte count in this case
619 * (the residual is always 0). Tell the XPT
620 * layer about the error.
622 ccb
->ccb_h
.status
= CAM_DATA_RUN_ERR
;
624 ccb
->csio
.resid
= ecb
->status
.resid_count
;
626 if ((ecb
->hecb
.flag_word1
& FW1_SG_ECB
) != 0) {
628 * For S/G transfers, the adapter provides a pointer
629 * to the address in the last S/G element used and a
630 * residual for that element. So, we need to sum up
631 * the elements that follow it in order to get a real
632 * residual number. If we have an overrun, the residual
633 * reported will be 0 and we already know that all S/G
634 * segments have been exhausted, so we can skip this
640 num_sg
= ecb
->hecb
.data_len
/ sizeof(ahb_sg_t
);
642 /* Find the S/G the adapter was working on */
643 for (sg
= ecb
->sg_list
;
644 num_sg
!= 0 && sg
->addr
!= ecb
->status
.resid_addr
;
653 for (; num_sg
!= 0; num_sg
--, sg
++)
654 ccb
->csio
.resid
+= sg
->len
;
656 /* Underruns are not errors */
657 ccb
->ccb_h
.status
= CAM_REQ_CMP
;
662 ahbprocesserror(struct ahb_softc
*ahb
, struct ecb
*ecb
, union ccb
*ccb
)
664 struct hardware_ecb
*hecb
;
665 struct ecb_status
*status
;
668 status
= &ecb
->status
;
669 switch (status
->ha_status
) {
671 ccb
->csio
.scsi_status
= status
->scsi_status
;
672 if (status
->scsi_status
!= 0) {
673 ccb
->ccb_h
.status
= CAM_SCSI_STATUS_ERROR
;
674 if (status
->sense_stored
) {
675 ccb
->ccb_h
.status
|= CAM_AUTOSNS_VALID
;
676 ccb
->csio
.sense_resid
=
677 ccb
->csio
.sense_len
- status
->sense_len
;
678 bcopy(&ecb
->sense
, &ccb
->csio
.sense_data
,
683 case HS_TARGET_NOT_ASSIGNED
:
684 ccb
->ccb_h
.status
= CAM_PATH_INVALID
;
687 ccb
->ccb_h
.status
= CAM_SEL_TIMEOUT
;
689 case HS_DATA_RUN_ERR
:
690 ahbcalcresid(ahb
, ecb
, ccb
);
692 case HS_UNEXPECTED_BUSFREE
:
693 ccb
->ccb_h
.status
= CAM_UNEXP_BUSFREE
;
695 case HS_INVALID_PHASE
:
696 ccb
->ccb_h
.status
= CAM_SEQUENCE_FAIL
;
698 case HS_REQUEST_SENSE_FAILED
:
699 ccb
->ccb_h
.status
= CAM_AUTOSENSE_FAIL
;
701 case HS_TAG_MSG_REJECTED
:
703 struct ccb_trans_settings neg
;
705 xpt_print_path(ccb
->ccb_h
.path
);
706 kprintf("refuses tagged commands. Performing "
709 neg
.valid
= CCB_TRANS_TQ_VALID
;
710 xpt_setup_ccb(&neg
.ccb_h
, ccb
->ccb_h
.path
, /*priority*/1);
711 xpt_async(AC_TRANSFER_NEG
, ccb
->ccb_h
.path
, &neg
);
712 ahb
->tags_permitted
&= ~(0x01 << ccb
->ccb_h
.target_id
);
713 ccb
->ccb_h
.status
= CAM_MSG_REJECT_REC
;
716 case HS_FIRMWARE_LOAD_REQ
:
717 case HS_HARDWARE_ERR
:
719 * Tell the system that the Adapter
720 * is no longer functional.
722 ccb
->ccb_h
.status
= CAM_NO_HBA
;
724 case HS_CMD_ABORTED_HOST
:
725 case HS_CMD_ABORTED_ADAPTER
:
726 case HS_ATN_TARGET_FAILED
:
727 case HS_SCSI_RESET_ADAPTER
:
728 case HS_SCSI_RESET_INCOMING
:
729 ccb
->ccb_h
.status
= CAM_SCSI_BUS_RESET
;
731 case HS_INVALID_ECB_PARAM
:
732 kprintf("ahb%ld: opcode 0x%02x, flag_word1 0x%02x, flag_word2 0x%02x\n",
733 ahb
->unit
, hecb
->opcode
, hecb
->flag_word1
, hecb
->flag_word2
);
734 ccb
->ccb_h
.status
= CAM_SCSI_BUS_RESET
;
736 case HS_DUP_TCB_RECEIVED
:
737 case HS_INVALID_OPCODE
:
738 case HS_INVALID_CMD_LINK
:
739 case HS_PROGRAM_CKSUM_ERROR
:
740 panic("ahb%ld: Can't happen host status %x occurred",
741 ahb
->unit
, status
->ha_status
);
744 if (ccb
->ccb_h
.status
!= CAM_REQ_CMP
) {
745 xpt_freeze_devq(ccb
->ccb_h
.path
, /*count*/1);
746 ccb
->ccb_h
.status
|= CAM_DEV_QFRZN
;
751 ahbdone(struct ahb_softc
*ahb
, u_int32_t mbox
, u_int intstat
)
756 ecb
= ahbecbptov(ahb
, mbox
);
758 if ((ecb
->state
& ECB_ACTIVE
) == 0)
759 panic("ecb not active");
764 callout_stop(&ccb
->ccb_h
.timeout_ch
);
765 LIST_REMOVE(&ccb
->ccb_h
, sim_links
.le
);
767 if ((ccb
->ccb_h
.flags
& CAM_DIR_MASK
) != CAM_DIR_NONE
) {
770 if ((ccb
->ccb_h
.flags
& CAM_DIR_MASK
) == CAM_DIR_IN
)
771 op
= BUS_DMASYNC_POSTREAD
;
773 op
= BUS_DMASYNC_POSTWRITE
;
774 bus_dmamap_sync(ahb
->buffer_dmat
, ecb
->dmamap
, op
);
775 bus_dmamap_unload(ahb
->buffer_dmat
, ecb
->dmamap
);
778 if ((intstat
& INTSTAT_MASK
) == INTSTAT_ECB_OK
) {
779 ccb
->ccb_h
.status
= CAM_REQ_CMP
;
782 ahbprocesserror(ahb
, ecb
, ccb
);
784 ahbecbfree(ahb
, ecb
);
787 /* Non CCB Command */
788 if ((intstat
& INTSTAT_MASK
) != INTSTAT_ECB_OK
) {
789 kprintf("ahb%ld: Command 0%x Failed %x:%x:%x\n",
790 ahb
->unit
, ecb
->hecb
.opcode
,
791 *((u_int16_t
*)&ecb
->status
),
792 ecb
->status
.ha_status
, ecb
->status
.resid_count
);
794 /* Client owns this ECB and will release it. */
799 * Catch an interrupt from the adaptor
804 struct ahb_softc
*ahb
;
808 ahb
= (struct ahb_softc
*)arg
;
810 while (ahb_inb(ahb
, HOSTSTAT
) & HOSTSTAT_INTPEND
) {
812 * Fetch information about this interrupt.
814 intstat
= ahb_inb(ahb
, INTSTAT
);
815 mbox
= ahb_inl(ahb
, MBOXIN0
);
818 * Reset interrupt latch.
820 ahb_outb(ahb
, CONTROL
, CNTRL_CLRINT
);
823 * Process the completed operation
825 switch (intstat
& INTSTAT_MASK
) {
827 case INTSTAT_ECB_CMPWRETRY
:
828 case INTSTAT_ECB_CMPWERR
:
829 ahbdone(ahb
, mbox
, intstat
);
831 case INTSTAT_AEN_OCCURED
:
832 if ((intstat
& INTSTAT_TARGET_MASK
) == ahb
->scsi_id
) {
834 xpt_print_path(ahb
->path
);
836 case HS_SCSI_RESET_ADAPTER
:
837 kprintf("Host Adapter Initiated "
838 "Bus Reset occurred\n");
840 case HS_SCSI_RESET_INCOMING
:
841 kprintf("Bus Reset Initiated "
842 "by another device occurred\n");
846 xpt_async(AC_BUS_RESET
, ahb
->path
, NULL
);
849 kprintf("Unsupported initiator selection AEN occurred\n");
851 case INTSTAT_IMMED_OK
:
852 case INTSTAT_IMMED_ERR
:
853 ahbhandleimmed(ahb
, mbox
, intstat
);
856 panic("Unrecoverable hardware Error Occurred\n");
862 ahbexecuteecb(void *arg
, bus_dma_segment_t
*dm_segs
, int nseg
, int error
)
866 struct ahb_softc
*ahb
;
869 ecb
= (struct ecb
*)arg
;
871 ahb
= (struct ahb_softc
*)ccb
->ccb_h
.ccb_ahb_ptr
;
875 kprintf("ahb%ld: Unexpected error 0x%x returned from "
876 "bus_dmamap_load\n", ahb
->unit
, error
);
877 if (ccb
->ccb_h
.status
== CAM_REQ_INPROG
) {
878 xpt_freeze_devq(ccb
->ccb_h
.path
, /*count*/1);
879 ccb
->ccb_h
.status
= CAM_REQ_TOO_BIG
|CAM_DEV_QFRZN
;
881 ahbecbfree(ahb
, ecb
);
886 ecb_paddr
= ahbecbvtop(ahb
, ecb
);
890 bus_dma_segment_t
*end_seg
;
893 end_seg
= dm_segs
+ nseg
;
895 /* Copy the segments into our SG list */
897 while (dm_segs
< end_seg
) {
898 sg
->addr
= dm_segs
->ds_addr
;
899 sg
->len
= dm_segs
->ds_len
;
905 ecb
->hecb
.flag_word1
|= FW1_SG_ECB
;
906 ecb
->hecb
.data_ptr
= ahbsgpaddr(ecb_paddr
);
907 ecb
->hecb
.data_len
= sizeof(ahb_sg_t
) * nseg
;
909 ecb
->hecb
.data_ptr
= ecb
->sg_list
->addr
;
910 ecb
->hecb
.data_len
= ecb
->sg_list
->len
;
913 if ((ccb
->ccb_h
.flags
& CAM_DIR_MASK
) == CAM_DIR_IN
) {
914 /* ecb->hecb.flag_word2 |= FW2_DATA_DIR_IN; */
915 op
= BUS_DMASYNC_PREREAD
;
917 op
= BUS_DMASYNC_PREWRITE
;
919 /* ecb->hecb.flag_word2 |= FW2_CHECK_DATA_DIR; */
921 bus_dmamap_sync(ahb
->buffer_dmat
, ecb
->dmamap
, op
);
924 ecb
->hecb
.data_ptr
= 0;
925 ecb
->hecb
.data_len
= 0;
931 * Last time we need to check if this CCB needs to
934 if (ccb
->ccb_h
.status
!= CAM_REQ_INPROG
) {
936 bus_dmamap_unload(ahb
->buffer_dmat
, ecb
->dmamap
);
937 ahbecbfree(ahb
, ecb
);
943 ecb
->state
= ECB_ACTIVE
;
944 ccb
->ccb_h
.status
|= CAM_SIM_QUEUED
;
945 LIST_INSERT_HEAD(&ahb
->pending_ccbs
, &ccb
->ccb_h
, sim_links
.le
);
947 /* Tell the adapter about this command */
948 ahbqueuembox(ahb
, ecb_paddr
, ATTN_STARTECB
|ccb
->ccb_h
.target_id
);
950 callout_reset(&ccb
->ccb_h
.timeout_ch
, (ccb
->ccb_h
.timeout
* hz
) / 1000,
956 ahbaction(struct cam_sim
*sim
, union ccb
*ccb
)
958 struct ahb_softc
*ahb
;
960 CAM_DEBUG(ccb
->ccb_h
.path
, CAM_DEBUG_TRACE
, ("ahbaction\n"));
962 ahb
= (struct ahb_softc
*)cam_sim_softc(sim
);
964 switch (ccb
->ccb_h
.func_code
) {
965 /* Common cases first */
966 case XPT_SCSI_IO
: /* Execute the requested I/O operation */
969 struct hardware_ecb
*hecb
;
974 if ((ecb
= ahbecbget(ahb
)) == NULL
) {
975 /* Should never occur */
976 panic("Failed to get an ecb");
980 * So we can find the ECB when an abort is requested
983 ccb
->ccb_h
.ccb_ecb_ptr
= ecb
;
984 ccb
->ccb_h
.ccb_ahb_ptr
= ahb
;
987 * Put all the arguments for the xfer in the ecb
990 hecb
->opcode
= ECBOP_INITIATOR_SCSI_CMD
;
991 hecb
->flag_word1
= FW1_AUTO_REQUEST_SENSE
992 | FW1_ERR_STATUS_BLK_ONLY
;
993 hecb
->flag_word2
= ccb
->ccb_h
.target_lun
994 | FW2_NO_RETRY_ON_BUSY
;
995 if ((ccb
->ccb_h
.flags
& CAM_TAG_ACTION_VALID
) != 0) {
996 hecb
->flag_word2
|= FW2_TAG_ENB
997 | ((ccb
->csio
.tag_action
& 0x3)
998 << FW2_TAG_TYPE_SHIFT
);
1000 if ((ccb
->ccb_h
.flags
& CAM_DIS_DISCONNECT
) != 0)
1001 hecb
->flag_word2
|= FW2_DISABLE_DISC
;
1002 hecb
->sense_len
= ccb
->csio
.sense_len
;
1003 hecb
->cdb_len
= ccb
->csio
.cdb_len
;
1004 if ((ccb
->ccb_h
.flags
& CAM_CDB_POINTER
) != 0) {
1005 if ((ccb
->ccb_h
.flags
& CAM_CDB_PHYS
) == 0) {
1006 bcopy(ccb
->csio
.cdb_io
.cdb_ptr
,
1007 hecb
->cdb
, hecb
->cdb_len
);
1009 /* I guess I could map it in... */
1010 ccb
->ccb_h
.status
= CAM_REQ_INVALID
;
1011 ahbecbfree(ahb
, ecb
);
1016 bcopy(ccb
->csio
.cdb_io
.cdb_bytes
,
1017 hecb
->cdb
, hecb
->cdb_len
);
1021 * If we have any data to send with this command,
1022 * map it into bus space.
1024 if ((ccb
->ccb_h
.flags
& CAM_DIR_MASK
) != CAM_DIR_NONE
) {
1025 if ((ccb
->ccb_h
.flags
& CAM_SCATTER_VALID
) == 0) {
1027 * We've been given a pointer
1028 * to a single buffer.
1030 if ((ccb
->ccb_h
.flags
& CAM_DATA_PHYS
)==0) {
1034 error
= bus_dmamap_load(
1038 ccb
->csio
.dxfer_len
,
1041 if (error
== EINPROGRESS
) {
1043 * So as to maintain ordering,
1044 * freeze the controller queue
1045 * until our mapping is
1048 xpt_freeze_simq(ahb
->sim
, 1);
1049 ccb
->ccb_h
.status
|=
1054 struct bus_dma_segment seg
;
1056 /* Pointer to physical buffer */
1058 (bus_addr_t
)ccb
->csio
.data_ptr
;
1059 seg
.ds_len
= ccb
->csio
.dxfer_len
;
1060 ahbexecuteecb(ecb
, &seg
, 1, 0);
1063 struct bus_dma_segment
*segs
;
1065 if ((ccb
->ccb_h
.flags
& CAM_DATA_PHYS
) != 0)
1066 panic("ahbaction - Physical segment "
1067 "pointers unsupported");
1069 if ((ccb
->ccb_h
.flags
& CAM_SG_LIST_PHYS
) == 0)
1070 panic("btaction - Virtual segment "
1071 "addresses unsupported");
1073 /* Just use the segments provided */
1074 segs
= (struct bus_dma_segment
*)
1076 ahbexecuteecb(ecb
, segs
, ccb
->csio
.sglist_cnt
,
1080 ahbexecuteecb(ecb
, NULL
, 0, 0);
1084 case XPT_EN_LUN
: /* Enable LUN as a target */
1085 case XPT_TARGET_IO
: /* Execute target I/O request */
1086 case XPT_ACCEPT_TARGET_IO
: /* Accept Host Target Mode CDB */
1087 case XPT_CONT_TARGET_IO
: /* Continue Host Target I/O Connection*/
1088 case XPT_ABORT
: /* Abort the specified CCB */
1090 ccb
->ccb_h
.status
= CAM_REQ_INVALID
;
1093 case XPT_SET_TRAN_SETTINGS
:
1095 ccb
->ccb_h
.status
= CAM_FUNC_NOTAVAIL
;
1099 case XPT_GET_TRAN_SETTINGS
:
1100 /* Get default/user set transfer settings for the target */
1102 struct ccb_trans_settings
*cts
;
1106 target_mask
= 0x01 << ccb
->ccb_h
.target_id
;
1107 if ((cts
->flags
& CCB_TRANS_USER_SETTINGS
) != 0) {
1109 if ((ahb
->disc_permitted
& target_mask
) != 0)
1110 cts
->flags
|= CCB_TRANS_DISC_ENB
;
1111 if ((ahb
->tags_permitted
& target_mask
) != 0)
1112 cts
->flags
|= CCB_TRANS_TAG_ENB
;
1113 cts
->bus_width
= MSG_EXT_WDTR_BUS_8_BIT
;
1114 cts
->sync_period
= 25; /* 10MHz */
1116 if (cts
->sync_period
!= 0)
1117 cts
->sync_offset
= 15;
1119 cts
->valid
= CCB_TRANS_SYNC_RATE_VALID
1120 | CCB_TRANS_SYNC_OFFSET_VALID
1121 | CCB_TRANS_BUS_WIDTH_VALID
1122 | CCB_TRANS_DISC_VALID
1123 | CCB_TRANS_TQ_VALID
;
1124 ccb
->ccb_h
.status
= CAM_REQ_CMP
;
1126 ccb
->ccb_h
.status
= CAM_FUNC_NOTAVAIL
;
1131 case XPT_RESET_DEV
: /* Bus Device Reset the specified SCSI device */
1136 ahb
->immed_cmd
= IMMED_RESET
;
1137 ahbqueuembox(ahb
, IMMED_RESET
, ATTN_IMMED
|ccb
->ccb_h
.target_id
);
1138 /* Poll for interrupt completion */
1139 for (i
= 1000; ahb
->immed_cmd
!= 0 && i
!= 0; i
--) {
1141 ahbintr(cam_sim_softc(sim
));
1146 case XPT_CALC_GEOMETRY
:
1148 struct ccb_calc_geometry
*ccg
;
1150 u_int32_t secs_per_cylinder
;
1153 size_mb
= ccg
->volume_size
1154 / ((1024L * 1024L) / ccg
->block_size
);
1156 if (size_mb
> 1024 && (ahb
->extended_trans
!= 0)) {
1158 ccg
->secs_per_track
= 63;
1161 ccg
->secs_per_track
= 32;
1163 secs_per_cylinder
= ccg
->heads
* ccg
->secs_per_track
;
1164 ccg
->cylinders
= ccg
->volume_size
/ secs_per_cylinder
;
1165 ccb
->ccb_h
.status
= CAM_REQ_CMP
;
1169 case XPT_RESET_BUS
: /* Reset the specified SCSI bus */
1173 ahb
->immed_cmd
= IMMED_RESET
;
1174 ahbqueuembox(ahb
, IMMED_RESET
, ATTN_IMMED
|ahb
->scsi_id
);
1175 /* Poll for interrupt completion */
1176 for (i
= 1000; ahb
->immed_cmd
!= 0 && i
!= 0; i
--)
1178 ccb
->ccb_h
.status
= CAM_REQ_CMP
;
1182 case XPT_TERM_IO
: /* Terminate the I/O process */
1184 ccb
->ccb_h
.status
= CAM_REQ_INVALID
;
1187 case XPT_PATH_INQ
: /* Path routing inquiry */
1189 struct ccb_pathinq
*cpi
= &ccb
->cpi
;
1191 cpi
->version_num
= 1; /* XXX??? */
1192 cpi
->hba_inquiry
= PI_SDTR_ABLE
|PI_TAG_ABLE
;
1193 cpi
->target_sprt
= 0;
1195 cpi
->hba_eng_cnt
= 0;
1196 cpi
->max_target
= 7;
1198 cpi
->initiator_id
= ahb
->scsi_id
;
1199 cpi
->bus_id
= cam_sim_bus(sim
);
1200 cpi
->base_transfer_speed
= 3300;
1201 strncpy(cpi
->sim_vid
, "FreeBSD", SIM_IDLEN
);
1202 strncpy(cpi
->hba_vid
, "Adaptec", HBA_IDLEN
);
1203 strncpy(cpi
->dev_name
, cam_sim_name(sim
), DEV_IDLEN
);
1204 cpi
->unit_number
= cam_sim_unit(sim
);
1205 cpi
->ccb_h
.status
= CAM_REQ_CMP
;
1211 case XPT_IMMED_NOTIFY
: /* Notify Host Target driver of event */
1212 case XPT_NOTIFY_ACK
: /* Acknowledgement of event */
1215 ccb
->ccb_h
.status
= CAM_REQ_INVALID
;
1222 ahbpoll(struct cam_sim
*sim
)
1224 ahbintr(cam_sim_softc(sim
));
1228 ahbtimeout(void *arg
)
1232 struct ahb_softc
*ahb
;
1234 ecb
= (struct ecb
*)arg
;
1236 ahb
= (struct ahb_softc
*)ccb
->ccb_h
.ccb_ahb_ptr
;
1237 xpt_print_path(ccb
->ccb_h
.path
);
1238 kprintf("ECB %p - timed out\n", (void *)ecb
);
1242 if ((ecb
->state
& ECB_ACTIVE
) == 0) {
1243 xpt_print_path(ccb
->ccb_h
.path
);
1244 kprintf("ECB %p - timed out ECB already completed\n",
1250 * In order to simplify the recovery process, we ask the XPT
1251 * layer to halt the queue of new transactions and we traverse
1252 * the list of pending CCBs and remove their timeouts. This
1253 * means that the driver attempts to clear only one error
1254 * condition at a time. In general, timeouts that occur
1255 * close together are related anyway, so there is no benefit
1256 * in attempting to handle errors in parrallel. Timeouts will
1257 * be reinstated when the recovery process ends.
1259 if ((ecb
->state
& ECB_DEVICE_RESET
) == 0) {
1260 struct ccb_hdr
*ccb_h
;
1262 if ((ecb
->state
& ECB_RELEASE_SIMQ
) == 0) {
1263 xpt_freeze_simq(ahb
->sim
, /*count*/1);
1264 ecb
->state
|= ECB_RELEASE_SIMQ
;
1267 ccb_h
= LIST_FIRST(&ahb
->pending_ccbs
);
1268 while (ccb_h
!= NULL
) {
1269 struct ecb
*pending_ecb
;
1271 pending_ecb
= (struct ecb
*)ccb_h
->ccb_ecb_ptr
;
1272 callout_stop(&ccb_h
->timeout_ch
);
1273 ccb_h
= LIST_NEXT(ccb_h
, sim_links
.le
);
1276 /* Store for our interrupt handler */
1277 ahb
->immed_ecb
= ecb
;
1280 * Send a Bus Device Reset message:
1281 * The target that is holding up the bus may not
1282 * be the same as the one that triggered this timeout
1283 * (different commands have different timeout lengths),
1284 * but we have no way of determining this from our
1285 * timeout handler. Our strategy here is to queue a
1286 * BDR message to the target of the timed out command.
1287 * If this fails, we'll get another timeout 2 seconds
1288 * later which will attempt a bus reset.
1290 xpt_print_path(ccb
->ccb_h
.path
);
1291 kprintf("Queuing BDR\n");
1292 ecb
->state
|= ECB_DEVICE_RESET
;
1293 callout_reset(&ccb
->ccb_h
.timeout_ch
, 2 * hz
, ahbtimeout
, ecb
);
1295 ahb
->immed_cmd
= IMMED_RESET
;
1296 ahbqueuembox(ahb
, IMMED_RESET
, ATTN_IMMED
|ccb
->ccb_h
.target_id
);
1297 } else if ((ecb
->state
& ECB_SCSIBUS_RESET
) != 0) {
1299 * Try a SCSI bus reset. We do this only if we
1300 * have already attempted to clear the condition with a BDR.
1302 xpt_print_path(ccb
->ccb_h
.path
);
1303 kprintf("Attempting SCSI Bus reset\n");
1304 ecb
->state
|= ECB_SCSIBUS_RESET
;
1305 callout_reset(&ccb
->ccb_h
.timeout_ch
, 2 * hz
, ahbtimeout
, ecb
);
1306 ahb
->immed_cmd
= IMMED_RESET
;
1307 ahbqueuembox(ahb
, IMMED_RESET
, ATTN_IMMED
|ahb
->scsi_id
);
1309 /* Bring out the hammer... */
1312 /* Simulate the reset complete interrupt */
1313 ahbhandleimmed(ahb
, 0, ahb
->scsi_id
|INTSTAT_IMMED_OK
);
1319 static device_method_t ahb_eisa_methods
[] = {
1320 /* Device interface */
1321 DEVMETHOD(device_probe
, ahbprobe
),
1322 DEVMETHOD(device_attach
, ahbattach
),
1327 static driver_t ahb_eisa_driver
= {
1333 static devclass_t ahb_devclass
;
1335 DRIVER_MODULE(ahb
, eisa
, ahb_eisa_driver
, ahb_devclass
, 0, 0);