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.19 2008/05/18 20:30:21 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 &sim_mplock
, 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
;
704 struct ccb_trans_settings_scsi
*scsi
= &neg
.proto_specific
.scsi
;
706 xpt_print_path(ccb
->ccb_h
.path
);
707 kprintf("refuses tagged commands. Performing "
709 memset(&neg
, 0, sizeof (neg
));
710 neg
.protocol
= PROTO_SCSI
;
711 neg
.protocol_version
= SCSI_REV_2
;
712 neg
.transport
= XPORT_SPI
;
713 neg
.transport_version
= 2;
714 scsi
->flags
= CTS_SCSI_VALID_TQ
;
715 xpt_setup_ccb(&neg
.ccb_h
, ccb
->ccb_h
.path
, /*priority*/1);
716 xpt_async(AC_TRANSFER_NEG
, ccb
->ccb_h
.path
, &neg
);
717 ahb
->tags_permitted
&= ~(0x01 << ccb
->ccb_h
.target_id
);
718 ccb
->ccb_h
.status
= CAM_MSG_REJECT_REC
;
721 case HS_FIRMWARE_LOAD_REQ
:
722 case HS_HARDWARE_ERR
:
724 * Tell the system that the Adapter
725 * is no longer functional.
727 ccb
->ccb_h
.status
= CAM_NO_HBA
;
729 case HS_CMD_ABORTED_HOST
:
730 case HS_CMD_ABORTED_ADAPTER
:
731 case HS_ATN_TARGET_FAILED
:
732 case HS_SCSI_RESET_ADAPTER
:
733 case HS_SCSI_RESET_INCOMING
:
734 ccb
->ccb_h
.status
= CAM_SCSI_BUS_RESET
;
736 case HS_INVALID_ECB_PARAM
:
737 kprintf("ahb%ld: opcode 0x%02x, flag_word1 0x%02x, flag_word2 0x%02x\n",
738 ahb
->unit
, hecb
->opcode
, hecb
->flag_word1
, hecb
->flag_word2
);
739 ccb
->ccb_h
.status
= CAM_SCSI_BUS_RESET
;
741 case HS_DUP_TCB_RECEIVED
:
742 case HS_INVALID_OPCODE
:
743 case HS_INVALID_CMD_LINK
:
744 case HS_PROGRAM_CKSUM_ERROR
:
745 panic("ahb%ld: Can't happen host status %x occurred",
746 ahb
->unit
, status
->ha_status
);
749 if (ccb
->ccb_h
.status
!= CAM_REQ_CMP
) {
750 xpt_freeze_devq(ccb
->ccb_h
.path
, /*count*/1);
751 ccb
->ccb_h
.status
|= CAM_DEV_QFRZN
;
756 ahbdone(struct ahb_softc
*ahb
, u_int32_t mbox
, u_int intstat
)
761 ecb
= ahbecbptov(ahb
, mbox
);
763 if ((ecb
->state
& ECB_ACTIVE
) == 0)
764 panic("ecb not active");
769 callout_stop(&ccb
->ccb_h
.timeout_ch
);
770 LIST_REMOVE(&ccb
->ccb_h
, sim_links
.le
);
772 if ((ccb
->ccb_h
.flags
& CAM_DIR_MASK
) != CAM_DIR_NONE
) {
775 if ((ccb
->ccb_h
.flags
& CAM_DIR_MASK
) == CAM_DIR_IN
)
776 op
= BUS_DMASYNC_POSTREAD
;
778 op
= BUS_DMASYNC_POSTWRITE
;
779 bus_dmamap_sync(ahb
->buffer_dmat
, ecb
->dmamap
, op
);
780 bus_dmamap_unload(ahb
->buffer_dmat
, ecb
->dmamap
);
783 if ((intstat
& INTSTAT_MASK
) == INTSTAT_ECB_OK
) {
784 ccb
->ccb_h
.status
= CAM_REQ_CMP
;
787 ahbprocesserror(ahb
, ecb
, ccb
);
789 ahbecbfree(ahb
, ecb
);
792 /* Non CCB Command */
793 if ((intstat
& INTSTAT_MASK
) != INTSTAT_ECB_OK
) {
794 kprintf("ahb%ld: Command 0%x Failed %x:%x:%x\n",
795 ahb
->unit
, ecb
->hecb
.opcode
,
796 *((u_int16_t
*)&ecb
->status
),
797 ecb
->status
.ha_status
, ecb
->status
.resid_count
);
799 /* Client owns this ECB and will release it. */
804 * Catch an interrupt from the adaptor
809 struct ahb_softc
*ahb
;
813 ahb
= (struct ahb_softc
*)arg
;
815 while (ahb_inb(ahb
, HOSTSTAT
) & HOSTSTAT_INTPEND
) {
817 * Fetch information about this interrupt.
819 intstat
= ahb_inb(ahb
, INTSTAT
);
820 mbox
= ahb_inl(ahb
, MBOXIN0
);
823 * Reset interrupt latch.
825 ahb_outb(ahb
, CONTROL
, CNTRL_CLRINT
);
828 * Process the completed operation
830 switch (intstat
& INTSTAT_MASK
) {
832 case INTSTAT_ECB_CMPWRETRY
:
833 case INTSTAT_ECB_CMPWERR
:
834 ahbdone(ahb
, mbox
, intstat
);
836 case INTSTAT_AEN_OCCURED
:
837 if ((intstat
& INTSTAT_TARGET_MASK
) == ahb
->scsi_id
) {
839 xpt_print_path(ahb
->path
);
841 case HS_SCSI_RESET_ADAPTER
:
842 kprintf("Host Adapter Initiated "
843 "Bus Reset occurred\n");
845 case HS_SCSI_RESET_INCOMING
:
846 kprintf("Bus Reset Initiated "
847 "by another device occurred\n");
851 xpt_async(AC_BUS_RESET
, ahb
->path
, NULL
);
854 kprintf("Unsupported initiator selection AEN occurred\n");
856 case INTSTAT_IMMED_OK
:
857 case INTSTAT_IMMED_ERR
:
858 ahbhandleimmed(ahb
, mbox
, intstat
);
861 panic("Unrecoverable hardware Error Occurred\n");
867 ahbexecuteecb(void *arg
, bus_dma_segment_t
*dm_segs
, int nseg
, int error
)
871 struct ahb_softc
*ahb
;
874 ecb
= (struct ecb
*)arg
;
876 ahb
= (struct ahb_softc
*)ccb
->ccb_h
.ccb_ahb_ptr
;
880 kprintf("ahb%ld: Unexpected error 0x%x returned from "
881 "bus_dmamap_load\n", ahb
->unit
, error
);
882 if (ccb
->ccb_h
.status
== CAM_REQ_INPROG
) {
883 xpt_freeze_devq(ccb
->ccb_h
.path
, /*count*/1);
884 ccb
->ccb_h
.status
= CAM_REQ_TOO_BIG
|CAM_DEV_QFRZN
;
886 ahbecbfree(ahb
, ecb
);
891 ecb_paddr
= ahbecbvtop(ahb
, ecb
);
895 bus_dma_segment_t
*end_seg
;
898 end_seg
= dm_segs
+ nseg
;
900 /* Copy the segments into our SG list */
902 while (dm_segs
< end_seg
) {
903 sg
->addr
= dm_segs
->ds_addr
;
904 sg
->len
= dm_segs
->ds_len
;
910 ecb
->hecb
.flag_word1
|= FW1_SG_ECB
;
911 ecb
->hecb
.data_ptr
= ahbsgpaddr(ecb_paddr
);
912 ecb
->hecb
.data_len
= sizeof(ahb_sg_t
) * nseg
;
914 ecb
->hecb
.data_ptr
= ecb
->sg_list
->addr
;
915 ecb
->hecb
.data_len
= ecb
->sg_list
->len
;
918 if ((ccb
->ccb_h
.flags
& CAM_DIR_MASK
) == CAM_DIR_IN
) {
919 /* ecb->hecb.flag_word2 |= FW2_DATA_DIR_IN; */
920 op
= BUS_DMASYNC_PREREAD
;
922 op
= BUS_DMASYNC_PREWRITE
;
924 /* ecb->hecb.flag_word2 |= FW2_CHECK_DATA_DIR; */
926 bus_dmamap_sync(ahb
->buffer_dmat
, ecb
->dmamap
, op
);
929 ecb
->hecb
.data_ptr
= 0;
930 ecb
->hecb
.data_len
= 0;
936 * Last time we need to check if this CCB needs to
939 if (ccb
->ccb_h
.status
!= CAM_REQ_INPROG
) {
941 bus_dmamap_unload(ahb
->buffer_dmat
, ecb
->dmamap
);
942 ahbecbfree(ahb
, ecb
);
948 ecb
->state
= ECB_ACTIVE
;
949 ccb
->ccb_h
.status
|= CAM_SIM_QUEUED
;
950 LIST_INSERT_HEAD(&ahb
->pending_ccbs
, &ccb
->ccb_h
, sim_links
.le
);
952 /* Tell the adapter about this command */
953 ahbqueuembox(ahb
, ecb_paddr
, ATTN_STARTECB
|ccb
->ccb_h
.target_id
);
955 callout_reset(&ccb
->ccb_h
.timeout_ch
, (ccb
->ccb_h
.timeout
* hz
) / 1000,
961 ahbaction(struct cam_sim
*sim
, union ccb
*ccb
)
963 struct ahb_softc
*ahb
;
965 CAM_DEBUG(ccb
->ccb_h
.path
, CAM_DEBUG_TRACE
, ("ahbaction\n"));
967 ahb
= (struct ahb_softc
*)cam_sim_softc(sim
);
969 switch (ccb
->ccb_h
.func_code
) {
970 /* Common cases first */
971 case XPT_SCSI_IO
: /* Execute the requested I/O operation */
974 struct hardware_ecb
*hecb
;
979 if ((ecb
= ahbecbget(ahb
)) == NULL
) {
980 /* Should never occur */
981 panic("Failed to get an ecb");
985 * So we can find the ECB when an abort is requested
988 ccb
->ccb_h
.ccb_ecb_ptr
= ecb
;
989 ccb
->ccb_h
.ccb_ahb_ptr
= ahb
;
992 * Put all the arguments for the xfer in the ecb
995 hecb
->opcode
= ECBOP_INITIATOR_SCSI_CMD
;
996 hecb
->flag_word1
= FW1_AUTO_REQUEST_SENSE
997 | FW1_ERR_STATUS_BLK_ONLY
;
998 hecb
->flag_word2
= ccb
->ccb_h
.target_lun
999 | FW2_NO_RETRY_ON_BUSY
;
1000 if ((ccb
->ccb_h
.flags
& CAM_TAG_ACTION_VALID
) != 0) {
1001 hecb
->flag_word2
|= FW2_TAG_ENB
1002 | ((ccb
->csio
.tag_action
& 0x3)
1003 << FW2_TAG_TYPE_SHIFT
);
1005 if ((ccb
->ccb_h
.flags
& CAM_DIS_DISCONNECT
) != 0)
1006 hecb
->flag_word2
|= FW2_DISABLE_DISC
;
1007 hecb
->sense_len
= ccb
->csio
.sense_len
;
1008 hecb
->cdb_len
= ccb
->csio
.cdb_len
;
1009 if ((ccb
->ccb_h
.flags
& CAM_CDB_POINTER
) != 0) {
1010 if ((ccb
->ccb_h
.flags
& CAM_CDB_PHYS
) == 0) {
1011 bcopy(ccb
->csio
.cdb_io
.cdb_ptr
,
1012 hecb
->cdb
, hecb
->cdb_len
);
1014 /* I guess I could map it in... */
1015 ccb
->ccb_h
.status
= CAM_REQ_INVALID
;
1016 ahbecbfree(ahb
, ecb
);
1021 bcopy(ccb
->csio
.cdb_io
.cdb_bytes
,
1022 hecb
->cdb
, hecb
->cdb_len
);
1026 * If we have any data to send with this command,
1027 * map it into bus space.
1029 if ((ccb
->ccb_h
.flags
& CAM_DIR_MASK
) != CAM_DIR_NONE
) {
1030 if ((ccb
->ccb_h
.flags
& CAM_SCATTER_VALID
) == 0) {
1032 * We've been given a pointer
1033 * to a single buffer.
1035 if ((ccb
->ccb_h
.flags
& CAM_DATA_PHYS
)==0) {
1039 error
= bus_dmamap_load(
1043 ccb
->csio
.dxfer_len
,
1046 if (error
== EINPROGRESS
) {
1048 * So as to maintain ordering,
1049 * freeze the controller queue
1050 * until our mapping is
1053 xpt_freeze_simq(ahb
->sim
, 1);
1054 ccb
->ccb_h
.status
|=
1059 struct bus_dma_segment seg
;
1061 /* Pointer to physical buffer */
1063 (bus_addr_t
)ccb
->csio
.data_ptr
;
1064 seg
.ds_len
= ccb
->csio
.dxfer_len
;
1065 ahbexecuteecb(ecb
, &seg
, 1, 0);
1068 struct bus_dma_segment
*segs
;
1070 if ((ccb
->ccb_h
.flags
& CAM_DATA_PHYS
) != 0)
1071 panic("ahbaction - Physical segment "
1072 "pointers unsupported");
1074 if ((ccb
->ccb_h
.flags
& CAM_SG_LIST_PHYS
) == 0)
1075 panic("btaction - Virtual segment "
1076 "addresses unsupported");
1078 /* Just use the segments provided */
1079 segs
= (struct bus_dma_segment
*)
1081 ahbexecuteecb(ecb
, segs
, ccb
->csio
.sglist_cnt
,
1085 ahbexecuteecb(ecb
, NULL
, 0, 0);
1089 case XPT_EN_LUN
: /* Enable LUN as a target */
1090 case XPT_TARGET_IO
: /* Execute target I/O request */
1091 case XPT_ACCEPT_TARGET_IO
: /* Accept Host Target Mode CDB */
1092 case XPT_CONT_TARGET_IO
: /* Continue Host Target I/O Connection*/
1093 case XPT_ABORT
: /* Abort the specified CCB */
1095 ccb
->ccb_h
.status
= CAM_REQ_INVALID
;
1098 case XPT_SET_TRAN_SETTINGS
:
1100 ccb
->ccb_h
.status
= CAM_FUNC_NOTAVAIL
;
1104 case XPT_GET_TRAN_SETTINGS
:
1105 /* Get default/user set transfer settings for the target */
1107 struct ccb_trans_settings
*cts
= &ccb
->cts
;
1108 u_int target_mask
= 0x01 << ccb
->ccb_h
.target_id
;
1109 struct ccb_trans_settings_scsi
*scsi
=
1110 &cts
->proto_specific
.scsi
;
1111 struct ccb_trans_settings_spi
*spi
=
1112 &cts
->xport_specific
.spi
;
1114 if (cts
->type
== CTS_TYPE_USER_SETTINGS
) {
1115 cts
->protocol
= PROTO_SCSI
;
1116 cts
->protocol_version
= SCSI_REV_2
;
1117 cts
->transport
= XPORT_SPI
;
1118 cts
->transport_version
= 2;
1120 scsi
->flags
&= ~CTS_SCSI_FLAGS_TAG_ENB
;
1121 spi
->flags
&= ~CTS_SPI_FLAGS_DISC_ENB
;
1122 if ((ahb
->disc_permitted
& target_mask
) != 0)
1123 spi
->flags
|= CTS_SPI_FLAGS_DISC_ENB
;
1124 if ((ahb
->tags_permitted
& target_mask
) != 0)
1125 scsi
->flags
|= CTS_SCSI_FLAGS_TAG_ENB
;
1126 spi
->bus_width
= MSG_EXT_WDTR_BUS_8_BIT
;
1127 spi
->sync_period
= 25; /* 10MHz */
1129 if (spi
->sync_period
!= 0)
1130 spi
->sync_offset
= 15;
1132 spi
->valid
= CTS_SPI_VALID_SYNC_RATE
1133 | CTS_SPI_VALID_SYNC_OFFSET
1134 | CTS_SPI_VALID_BUS_WIDTH
1135 | CTS_SPI_VALID_DISC
;
1136 scsi
->valid
= CTS_SCSI_VALID_TQ
;
1137 ccb
->ccb_h
.status
= CAM_REQ_CMP
;
1139 ccb
->ccb_h
.status
= CAM_FUNC_NOTAVAIL
;
1144 case XPT_RESET_DEV
: /* Bus Device Reset the specified SCSI device */
1149 ahb
->immed_cmd
= IMMED_RESET
;
1150 ahbqueuembox(ahb
, IMMED_RESET
, ATTN_IMMED
|ccb
->ccb_h
.target_id
);
1151 /* Poll for interrupt completion */
1152 for (i
= 1000; ahb
->immed_cmd
!= 0 && i
!= 0; i
--) {
1154 ahbintr(cam_sim_softc(sim
));
1159 case XPT_CALC_GEOMETRY
:
1161 struct ccb_calc_geometry
*ccg
;
1163 u_int32_t secs_per_cylinder
;
1166 size_mb
= ccg
->volume_size
1167 / ((1024L * 1024L) / ccg
->block_size
);
1169 if (size_mb
> 1024 && (ahb
->extended_trans
!= 0)) {
1171 ccg
->secs_per_track
= 63;
1174 ccg
->secs_per_track
= 32;
1176 secs_per_cylinder
= ccg
->heads
* ccg
->secs_per_track
;
1177 ccg
->cylinders
= ccg
->volume_size
/ secs_per_cylinder
;
1178 ccb
->ccb_h
.status
= CAM_REQ_CMP
;
1182 case XPT_RESET_BUS
: /* Reset the specified SCSI bus */
1186 ahb
->immed_cmd
= IMMED_RESET
;
1187 ahbqueuembox(ahb
, IMMED_RESET
, ATTN_IMMED
|ahb
->scsi_id
);
1188 /* Poll for interrupt completion */
1189 for (i
= 1000; ahb
->immed_cmd
!= 0 && i
!= 0; i
--)
1191 ccb
->ccb_h
.status
= CAM_REQ_CMP
;
1195 case XPT_TERM_IO
: /* Terminate the I/O process */
1197 ccb
->ccb_h
.status
= CAM_REQ_INVALID
;
1200 case XPT_PATH_INQ
: /* Path routing inquiry */
1202 struct ccb_pathinq
*cpi
= &ccb
->cpi
;
1204 cpi
->version_num
= 1; /* XXX??? */
1205 cpi
->hba_inquiry
= PI_SDTR_ABLE
|PI_TAG_ABLE
;
1206 cpi
->target_sprt
= 0;
1208 cpi
->hba_eng_cnt
= 0;
1209 cpi
->max_target
= 7;
1211 cpi
->initiator_id
= ahb
->scsi_id
;
1212 cpi
->bus_id
= cam_sim_bus(sim
);
1213 cpi
->base_transfer_speed
= 3300;
1214 strncpy(cpi
->sim_vid
, "FreeBSD", SIM_IDLEN
);
1215 strncpy(cpi
->hba_vid
, "Adaptec", HBA_IDLEN
);
1216 strncpy(cpi
->dev_name
, cam_sim_name(sim
), DEV_IDLEN
);
1217 cpi
->unit_number
= cam_sim_unit(sim
);
1218 cpi
->transport
= XPORT_SPI
;
1219 cpi
->transport_version
= 2;
1220 cpi
->protocol
= PROTO_SCSI
;
1221 cpi
->protocol_version
= SCSI_REV_2
;
1222 cpi
->ccb_h
.status
= CAM_REQ_CMP
;
1228 case XPT_IMMED_NOTIFY
: /* Notify Host Target driver of event */
1229 case XPT_NOTIFY_ACK
: /* Acknowledgement of event */
1232 ccb
->ccb_h
.status
= CAM_REQ_INVALID
;
1239 ahbpoll(struct cam_sim
*sim
)
1241 ahbintr(cam_sim_softc(sim
));
1245 ahbtimeout(void *arg
)
1249 struct ahb_softc
*ahb
;
1251 ecb
= (struct ecb
*)arg
;
1253 ahb
= (struct ahb_softc
*)ccb
->ccb_h
.ccb_ahb_ptr
;
1254 xpt_print_path(ccb
->ccb_h
.path
);
1255 kprintf("ECB %p - timed out\n", (void *)ecb
);
1259 if ((ecb
->state
& ECB_ACTIVE
) == 0) {
1260 xpt_print_path(ccb
->ccb_h
.path
);
1261 kprintf("ECB %p - timed out ECB already completed\n",
1267 * In order to simplify the recovery process, we ask the XPT
1268 * layer to halt the queue of new transactions and we traverse
1269 * the list of pending CCBs and remove their timeouts. This
1270 * means that the driver attempts to clear only one error
1271 * condition at a time. In general, timeouts that occur
1272 * close together are related anyway, so there is no benefit
1273 * in attempting to handle errors in parrallel. Timeouts will
1274 * be reinstated when the recovery process ends.
1276 if ((ecb
->state
& ECB_DEVICE_RESET
) == 0) {
1277 struct ccb_hdr
*ccb_h
;
1279 if ((ecb
->state
& ECB_RELEASE_SIMQ
) == 0) {
1280 xpt_freeze_simq(ahb
->sim
, /*count*/1);
1281 ecb
->state
|= ECB_RELEASE_SIMQ
;
1284 ccb_h
= LIST_FIRST(&ahb
->pending_ccbs
);
1285 while (ccb_h
!= NULL
) {
1286 struct ecb
*pending_ecb
;
1288 pending_ecb
= (struct ecb
*)ccb_h
->ccb_ecb_ptr
;
1289 callout_stop(&ccb_h
->timeout_ch
);
1290 ccb_h
= LIST_NEXT(ccb_h
, sim_links
.le
);
1293 /* Store for our interrupt handler */
1294 ahb
->immed_ecb
= ecb
;
1297 * Send a Bus Device Reset message:
1298 * The target that is holding up the bus may not
1299 * be the same as the one that triggered this timeout
1300 * (different commands have different timeout lengths),
1301 * but we have no way of determining this from our
1302 * timeout handler. Our strategy here is to queue a
1303 * BDR message to the target of the timed out command.
1304 * If this fails, we'll get another timeout 2 seconds
1305 * later which will attempt a bus reset.
1307 xpt_print_path(ccb
->ccb_h
.path
);
1308 kprintf("Queuing BDR\n");
1309 ecb
->state
|= ECB_DEVICE_RESET
;
1310 callout_reset(&ccb
->ccb_h
.timeout_ch
, 2 * hz
, ahbtimeout
, ecb
);
1312 ahb
->immed_cmd
= IMMED_RESET
;
1313 ahbqueuembox(ahb
, IMMED_RESET
, ATTN_IMMED
|ccb
->ccb_h
.target_id
);
1314 } else if ((ecb
->state
& ECB_SCSIBUS_RESET
) != 0) {
1316 * Try a SCSI bus reset. We do this only if we
1317 * have already attempted to clear the condition with a BDR.
1319 xpt_print_path(ccb
->ccb_h
.path
);
1320 kprintf("Attempting SCSI Bus reset\n");
1321 ecb
->state
|= ECB_SCSIBUS_RESET
;
1322 callout_reset(&ccb
->ccb_h
.timeout_ch
, 2 * hz
, ahbtimeout
, ecb
);
1323 ahb
->immed_cmd
= IMMED_RESET
;
1324 ahbqueuembox(ahb
, IMMED_RESET
, ATTN_IMMED
|ahb
->scsi_id
);
1326 /* Bring out the hammer... */
1329 /* Simulate the reset complete interrupt */
1330 ahbhandleimmed(ahb
, 0, ahb
->scsi_id
|INTSTAT_IMMED_OK
);
1336 static device_method_t ahb_eisa_methods
[] = {
1337 /* Device interface */
1338 DEVMETHOD(device_probe
, ahbprobe
),
1339 DEVMETHOD(device_attach
, ahbattach
),
1344 static driver_t ahb_eisa_driver
= {
1350 static devclass_t ahb_devclass
;
1352 DRIVER_MODULE(ahb
, eisa
, ahb_eisa_driver
, ahb_devclass
, 0, 0);