2 * Copyright (c) 2003-04 3ware, Inc.
3 * Copyright (c) 2000 Michael Smith
4 * Copyright (c) 2000 BSDi
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, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
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
20 * FOR 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
29 * $DragonFly: src/sys/dev/raid/twa/twa_freebsd.c,v 1.14 2006/12/22 23:26:24 swildner Exp $
33 * 3ware driver for 9000 series storage controllers.
35 * Author: Vinod Kashyap
39 #include "twa_includes.h"
41 static void twa_setup_data_dmamap(void *arg
, bus_dma_segment_t
*segs
,
42 int nsegments
, int error
);
43 static void twa_setup_request_dmamap(void *arg
, bus_dma_segment_t
*segs
,
44 int nsegments
, int error
);
46 MALLOC_DEFINE(TWA_MALLOC_CLASS
, "twa commands", "twa commands");
49 static d_open_t twa_open
;
50 static d_close_t twa_close
;
51 static d_ioctl_t twa_ioctl_wrapper
;
53 static struct dev_ops twa_ops
= {
54 { "twa", TWA_CDEV_MAJOR
, 0 },
57 .d_ioctl
= twa_ioctl_wrapper
,
60 static devclass_t twa_devclass
;
64 * Function name: twa_open
65 * Description: Called when the controller is opened.
66 * Simply marks the controller as open.
68 * Input: dev -- control device corresponding to the ctlr
69 * flags -- mode of open
70 * fmt -- device type (character/block etc.)
71 * proc -- current process
73 * Return value: 0 -- success
77 twa_open(struct dev_open_args
*ap
)
79 cdev_t dev
= ap
->a_head
.a_dev
;
80 int unit
= minor(dev
);
81 struct twa_softc
*sc
= devclass_get_softc(twa_devclass
, unit
);
83 sc
->twa_state
|= TWA_STATE_OPEN
;
90 * Function name: twa_close
91 * Description: Called when the controller is closed.
92 * Simply marks the controller as not open.
94 * Input: dev -- control device corresponding to the ctlr
95 * flags -- mode of corresponding open
96 * fmt -- device type (character/block etc.)
97 * proc -- current process
99 * Return value: 0 -- success
103 twa_close(struct dev_close_args
*ap
)
105 cdev_t dev
= ap
->a_head
.a_dev
;
106 int unit
= minor(dev
);
107 struct twa_softc
*sc
= devclass_get_softc(twa_devclass
, unit
);
109 sc
->twa_state
&= ~TWA_STATE_OPEN
;
116 * Function name: twa_ioctl_wrapper
117 * Description: Called when an ioctl is posted to the controller.
118 * Simply calls the ioctl handler.
120 * Input: dev -- control device corresponding to the ctlr
122 * buf -- ptr to buffer in kernel memory, which is
123 * a copy of the input buffer in user-space
124 * flags -- mode of corresponding open
125 * proc -- current process
126 * Output: buf -- ptr to buffer in kernel memory, which will
127 * be copied to the output buffer in user-space
128 * Return value: 0 -- success
132 twa_ioctl_wrapper(struct dev_ioctl_args
*ap
)
134 cdev_t dev
= ap
->a_head
.a_dev
;
135 struct twa_softc
*sc
= (struct twa_softc
*)(dev
->si_drv1
);
137 return(twa_ioctl(sc
, ap
->a_cmd
, ap
->a_data
));
142 static int twa_probe (device_t dev
);
143 static int twa_attach (device_t dev
);
144 static void twa_free (struct twa_softc
*sc
);
145 static int twa_detach (device_t dev
);
146 static int twa_shutdown (device_t dev
);
147 static int twa_suspend (device_t dev
);
148 static int twa_resume (device_t dev
);
149 static void twa_pci_intr(void *arg
);
150 static void twa_intrhook (void *arg
);
152 static device_method_t twa_methods
[] = {
153 /* Device interface */
154 DEVMETHOD(device_probe
, twa_probe
),
155 DEVMETHOD(device_attach
, twa_attach
),
156 DEVMETHOD(device_detach
, twa_detach
),
157 DEVMETHOD(device_shutdown
, twa_shutdown
),
158 DEVMETHOD(device_suspend
, twa_suspend
),
159 DEVMETHOD(device_resume
, twa_resume
),
161 DEVMETHOD(bus_print_child
, bus_generic_print_child
),
162 DEVMETHOD(bus_driver_added
, bus_generic_driver_added
),
166 static driver_t twa_pci_driver
= {
169 sizeof(struct twa_softc
)
172 DRIVER_MODULE(twa
, pci
, twa_pci_driver
, twa_devclass
, 0, 0);
177 * Function name: twa_probe
178 * Description: Called at driver load time. Claims 9000 ctlrs.
180 * Input: dev -- bus device corresponding to the ctlr
182 * Return value: <= 0 -- success
186 twa_probe(device_t dev
)
188 static u_int8_t first_ctlr
= 1;
190 twa_dbg_print(3, "entered");
192 if ((pci_get_vendor(dev
) == TWA_VENDOR_ID
) &&
193 (pci_get_device(dev
) == TWA_DEVICE_ID_9K
)) {
194 device_set_desc(dev
, TWA_DEVICE_NAME
);
195 /* Print the driver version only once. */
197 kprintf("3ware device driver for 9000 series storage controllers, version: %s\n",
198 TWA_DRIVER_VERSION_STRING
);
209 * Function name: twa_attach
210 * Description: Allocates pci resources; updates sc; adds a node to the
211 * sysctl tree to expose the driver version; makes calls
212 * to initialize ctlr, and to attach to CAM.
214 * Input: dev -- bus device corresponding to the ctlr
216 * Return value: 0 -- success
220 twa_attach(device_t dev
)
222 struct twa_softc
*sc
= device_get_softc(dev
);
228 twa_dbg_dprint_enter(3, sc
);
230 /* Initialize the softc structure. */
231 sc
->twa_bus_dev
= dev
;
233 sysctl_ctx_init(&sc
->twa_sysctl_ctx
);
234 sc
->twa_sysctl_tree
= SYSCTL_ADD_NODE(&sc
->twa_sysctl_ctx
,
235 SYSCTL_STATIC_CHILDREN(_hw
), OID_AUTO
,
236 device_get_nameunit(dev
), CTLFLAG_RD
, 0, "");
237 if (sc
->twa_sysctl_tree
== NULL
) {
238 twa_printf(sc
, "Cannot add sysctl tree node.\n");
241 SYSCTL_ADD_STRING(&sc
->twa_sysctl_ctx
, SYSCTL_CHILDREN(sc
->twa_sysctl_tree
),
242 OID_AUTO
, "driver_version", CTLFLAG_RD
,
243 TWA_DRIVER_VERSION_STRING
, 0, "TWA driver version");
245 /* Make sure we are going to be able to talk to this board. */
246 command
= pci_read_config(dev
, PCIR_COMMAND
, 2);
247 if ((command
& PCIM_CMD_PORTEN
) == 0) {
248 twa_printf(sc
, "Register window not available.\n");
252 /* Force the busmaster enable bit on, in case the BIOS forgot. */
253 command
|= PCIM_CMD_BUSMASTEREN
;
254 pci_write_config(dev
, PCIR_COMMAND
, command
, 2);
256 /* Allocate the PCI register window. */
257 res_id
= TWA_IO_CONFIG_REG
;
258 if ((sc
->twa_io_res
= bus_alloc_resource(dev
, SYS_RES_IOPORT
, &res_id
,
259 0, ~0, 1, RF_ACTIVE
)) == NULL
) {
260 twa_printf(sc
, "can't allocate register window.\n");
264 sc
->twa_bus_tag
= rman_get_bustag(sc
->twa_io_res
);
265 sc
->twa_bus_handle
= rman_get_bushandle(sc
->twa_io_res
);
267 /* Allocate and connect our interrupt. */
269 if ((sc
->twa_irq_res
= bus_alloc_resource(sc
->twa_bus_dev
, SYS_RES_IRQ
,
271 RF_SHAREABLE
| RF_ACTIVE
)) == NULL
) {
272 twa_printf(sc
, "Can't allocate interrupt.\n");
276 if (bus_setup_intr(sc
->twa_bus_dev
, sc
->twa_irq_res
, 0,
277 twa_pci_intr
, sc
, &sc
->twa_intr_handle
, NULL
)) {
278 twa_printf(sc
, "Can't set up interrupt.\n");
283 /* Initialize the driver for this controller. */
284 if ((error
= twa_setup(sc
))) {
289 /* Print some information about the controller and configuration. */
290 twa_describe_controller(sc
);
292 /* Create the control device. */
293 dev_ops_add(&twa_ops
, -1, device_get_unit(sc
->twa_bus_dev
));
294 xdev
= make_dev(&twa_ops
, device_get_unit(sc
->twa_bus_dev
),
295 UID_ROOT
, GID_OPERATOR
, S_IRUSR
| S_IWUSR
,
296 "twa%d", device_get_unit(sc
->twa_bus_dev
));
300 * Schedule ourselves to bring the controller up once interrupts are
301 * available. This isn't strictly necessary, since we disable
302 * interrupts while probing the controller, but it is more in keeping
303 * with common practice for other disk devices.
305 sc
->twa_ich
.ich_func
= twa_intrhook
;
306 sc
->twa_ich
.ich_arg
= sc
;
307 sc
->twa_ich
.ich_desc
= "twa";
308 if (config_intrhook_establish(&sc
->twa_ich
) != 0) {
309 twa_printf(sc
, "Can't establish configuration hook.\n");
314 if ((error
= twa_cam_setup(sc
))) {
324 * Function name: twa_free
325 * Description: Performs clean-up at the time of going down.
327 * Input: sc -- ptr to per ctlr structure
332 twa_free(struct twa_softc
*sc
)
334 struct twa_request
*tr
;
336 twa_dbg_dprint_enter(3, sc
);
338 /* Detach from CAM */
341 /* Destroy dma handles. */
343 bus_dmamap_unload(sc
->twa_dma_tag
, sc
->twa_cmd_map
);
344 while ((tr
= twa_dequeue_free(sc
)) != NULL
)
345 bus_dmamap_destroy(sc
->twa_dma_tag
, tr
->tr_dma_map
);
347 /* Free all memory allocated so far. */
349 kfree(sc
->twa_req_buf
, TWA_MALLOC_CLASS
);
350 if (sc
->twa_cmd_pkt_buf
)
351 bus_dmamem_free(sc
->twa_dma_tag
, sc
->twa_cmd_pkt_buf
,
353 if (sc
->twa_aen_queue
[0])
354 kfree (sc
->twa_aen_queue
[0], M_DEVBUF
);
356 /* Destroy the data-transfer DMA tag. */
358 bus_dma_tag_destroy(sc
->twa_dma_tag
);
360 /* Disconnect the interrupt handler. */
361 if (sc
->twa_intr_handle
)
362 bus_teardown_intr(sc
->twa_bus_dev
, sc
->twa_irq_res
,
363 sc
->twa_intr_handle
);
364 if (sc
->twa_irq_res
!= NULL
)
365 bus_release_resource(sc
->twa_bus_dev
, SYS_RES_IRQ
,
368 /* Release the register window mapping. */
369 if (sc
->twa_io_res
!= NULL
)
370 bus_release_resource(sc
->twa_bus_dev
, SYS_RES_IOPORT
,
371 TWA_IO_CONFIG_REG
, sc
->twa_io_res
);
373 dev_ops_remove(&twa_ops
, -1, device_get_unit(sc
->twa_bus_dev
));
375 sysctl_ctx_free(&sc
->twa_sysctl_ctx
);
381 * Function name: twa_detach
382 * Description: Called when the controller is being detached from
385 * Input: dev -- bus device corresponding to the ctlr
387 * Return value: 0 -- success
391 twa_detach(device_t dev
)
393 struct twa_softc
*sc
= device_get_softc(dev
);
396 twa_dbg_dprint_enter(3, sc
);
400 if (sc
->twa_state
& TWA_STATE_OPEN
)
403 /* Shut the controller down. */
404 if ((error
= twa_shutdown(dev
)))
407 /* Free all resources associated with this controller. */
419 * Function name: twa_shutdown
420 * Description: Called at unload/shutdown time. Lets the controller
421 * know that we are going down.
423 * Input: dev -- bus device corresponding to the ctlr
425 * Return value: 0 -- success
429 twa_shutdown(device_t dev
)
431 struct twa_softc
*sc
= device_get_softc(dev
);
434 twa_dbg_dprint_enter(3, sc
);
438 /* Disconnect from the controller. */
439 error
= twa_deinit_ctlr(sc
);
448 * Function name: twa_suspend
449 * Description: Called to suspend I/O before hot-swapping PCI ctlrs.
450 * Doesn't do much as of now.
452 * Input: dev -- bus device corresponding to the ctlr
454 * Return value: 0 -- success
458 twa_suspend(device_t dev
)
460 struct twa_softc
*sc
= device_get_softc(dev
);
462 twa_dbg_dprint_enter(3, sc
);
465 sc
->twa_state
|= TWA_STATE_SUSPEND
;
467 twa_disable_interrupts(sc
);
476 * Function name: twa_resume
477 * Description: Called to resume I/O after hot-swapping PCI ctlrs.
478 * Doesn't do much as of now.
480 * Input: dev -- bus device corresponding to the ctlr
482 * Return value: 0 -- success
486 twa_resume(device_t dev
)
488 struct twa_softc
*sc
= device_get_softc(dev
);
490 twa_dbg_dprint_enter(3, sc
);
492 sc
->twa_state
&= ~TWA_STATE_SUSPEND
;
493 twa_enable_interrupts(sc
);
501 * Function name: twa_pci_intr
502 * Description: Interrupt handler. Wrapper for twa_interrupt.
504 * Input: arg -- ptr to per ctlr structure
509 twa_pci_intr(void *arg
)
511 struct twa_softc
*sc
= (struct twa_softc
*)arg
;
519 * Function name: twa_intrhook
520 * Description: Callback for us to enable interrupts.
522 * Input: arg -- ptr to per ctlr structure
527 twa_intrhook(void *arg
)
529 struct twa_softc
*sc
= (struct twa_softc
*)arg
;
531 twa_dbg_dprint(4, sc
, "twa_intrhook Entered");
533 /* Pull ourselves off the intrhook chain. */
534 config_intrhook_disestablish(&sc
->twa_ich
);
536 /* Enable interrupts. */
537 twa_enable_interrupts(sc
);
543 * Function name: twa_write_pci_config
544 * Description: Writes to the PCI config space.
546 * Input: sc -- ptr to per ctlr structure
547 * value -- value to be written
548 * size -- # of bytes to be written
553 twa_write_pci_config(struct twa_softc
*sc
, u_int32_t value
, int size
)
555 pci_write_config(sc
->twa_bus_dev
, PCIR_STATUS
, value
, size
);
561 * Function name: twa_alloc_req_pkts
562 * Description: Allocates memory for, and initializes request pkts,
563 * and queues them in the free queue.
565 * Input: sc -- ptr to per ctlr structure
566 * num_reqs-- # of request pkts to allocate and initialize.
568 * Return value: 0 -- success
572 twa_alloc_req_pkts(struct twa_softc
*sc
, int num_reqs
)
574 struct twa_request
*tr
;
577 sc
->twa_req_buf
= kmalloc(num_reqs
* sizeof(struct twa_request
),
578 TWA_MALLOC_CLASS
, M_INTWAIT
);
580 /* Allocate the bus DMA tag appropriate for PCI. */
581 if (bus_dma_tag_create(NULL
, /* parent */
582 TWA_ALIGNMENT
, /* alignment */
584 BUS_SPACE_MAXADDR
, /* lowaddr */
585 BUS_SPACE_MAXADDR
, /* highaddr */
586 NULL
, NULL
, /* filter, filterarg */
588 (sizeof(struct twa_command_packet
)),/* maxsize */
589 TWA_MAX_SG_ELEMENTS
, /* nsegments */
590 BUS_SPACE_MAXSIZE_32BIT
,/* maxsegsize */
591 BUS_DMA_ALLOCNOW
, /* flags */
592 &sc
->twa_dma_tag
/* tag */)) {
593 twa_printf(sc
, "Can't allocate DMA tag.\n");
597 /* Allocate memory for cmd pkts. */
598 if (bus_dmamem_alloc(sc
->twa_dma_tag
,
599 (void *)(&(sc
->twa_cmd_pkt_buf
)),
600 BUS_DMA_WAITOK
, &(sc
->twa_cmd_map
)))
603 bus_dmamap_load(sc
->twa_dma_tag
, sc
->twa_cmd_map
,
605 num_reqs
* sizeof(struct twa_command_packet
),
606 twa_setup_request_dmamap
, sc
, 0);
607 bzero(sc
->twa_req_buf
, num_reqs
* sizeof(struct twa_request
));
608 bzero(sc
->twa_cmd_pkt_buf
,
609 num_reqs
* sizeof(struct twa_command_packet
));
611 for (i
= 0; i
< num_reqs
; i
++) {
612 tr
= &(sc
->twa_req_buf
[i
]);
613 tr
->tr_command
= &(sc
->twa_cmd_pkt_buf
[i
]);
614 tr
->tr_cmd_phys
= sc
->twa_cmd_pkt_phys
+
615 (i
* sizeof(struct twa_command_packet
));
616 tr
->tr_request_id
= i
;
618 sc
->twa_lookup
[i
] = tr
;
621 * Create a map for data buffers. maxsize (256 * 1024) used in
622 * bus_dma_tag_create above should suffice the bounce page needs
623 * for data buffers, since the max I/O size we support is 128KB.
624 * If we supported I/O's bigger than 256KB, we would have to
625 * create a second dma_tag, with the appropriate maxsize.
627 if (bus_dmamap_create(sc
->twa_dma_tag
, 0,
631 /* Insert request into the free queue. */
632 twa_release_request(tr
);
640 * Function name: twa_fillin_sgl
641 * Description: Fills in the scatter/gather list.
643 * Input: sgl -- ptr to sg list
644 * segs -- ptr to fill the sg list from
645 * nsegments--# of segments
650 twa_fillin_sgl(struct twa_sg
*sgl
, bus_dma_segment_t
*segs
, int nsegments
)
654 for (i
= 0; i
< nsegments
; i
++) {
655 sgl
[i
].address
= segs
[i
].ds_addr
;
656 sgl
[i
].length
= segs
[i
].ds_len
;
663 * Function name: twa_setup_data_dmamap
664 * Description: Callback of bus_dmamap_load for the buffer associated
665 * with data. Updates the cmd pkt (size/sgl_entries
666 * fields, as applicable) to reflect the number of sg
669 * Input: arg -- ptr to request pkt
670 * segs -- ptr to a list of segment descriptors
671 * nsegments--# of segments
672 * error -- 0 if no errors encountered before callback,
673 * non-zero if errors were encountered
678 twa_setup_data_dmamap(void *arg
, bus_dma_segment_t
*segs
,
679 int nsegments
, int error
)
681 struct twa_request
*tr
= (struct twa_request
*)arg
;
682 struct twa_command_packet
*cmdpkt
= tr
->tr_command
;
683 struct twa_command_9k
*cmd9k
;
684 union twa_command_7k
*cmd7k
;
687 twa_dbg_dprint_enter(10, tr
->tr_sc
);
689 if ((tr
->tr_flags
& TWA_CMD_IN_PROGRESS
) &&
690 (tr
->tr_cmd_pkt_type
& TWA_CMD_PKT_TYPE_EXTERNAL
))
691 twa_allow_new_requests(tr
->tr_sc
, (void *)(tr
->tr_private
));
693 if (error
== EFBIG
) {
694 tr
->tr_error
= error
;
698 if (tr
->tr_cmd_pkt_type
& TWA_CMD_PKT_TYPE_9K
) {
699 cmd9k
= &(cmdpkt
->command
.cmd_pkt_9k
);
700 twa_fillin_sgl(&(cmd9k
->sg_list
[0]), segs
, nsegments
);
701 cmd9k
->sgl_entries
+= nsegments
- 1;
703 /* It's a 7000 command packet. */
704 cmd7k
= &(cmdpkt
->command
.cmd_pkt_7k
);
705 if ((sgl_offset
= cmdpkt
->command
.cmd_pkt_7k
.generic
.sgl_offset
))
706 twa_fillin_sgl((struct twa_sg
*)
707 (((u_int32_t
*)cmd7k
) + sgl_offset
),
709 /* Modify the size field, based on sg address size. */
710 cmd7k
->generic
.size
+=
711 ((TWA_64BIT_ADDRESSES
? 3 : 2) * nsegments
);
714 if (tr
->tr_flags
& TWA_CMD_DATA_IN
)
715 bus_dmamap_sync(tr
->tr_sc
->twa_dma_tag
, tr
->tr_dma_map
,
716 BUS_DMASYNC_PREREAD
);
717 if (tr
->tr_flags
& TWA_CMD_DATA_OUT
) {
719 * If we're using an alignment buffer, and we're
720 * writing data, copy the real data out.
722 if (tr
->tr_flags
& TWA_CMD_DATA_COPY_NEEDED
)
723 bcopy(tr
->tr_real_data
, tr
->tr_data
, tr
->tr_real_length
);
724 bus_dmamap_sync(tr
->tr_sc
->twa_dma_tag
, tr
->tr_dma_map
,
725 BUS_DMASYNC_PREWRITE
);
727 error
= twa_submit_io(tr
);
731 twa_unmap_request(tr
);
733 * If the caller had been returned EINPROGRESS, and he has
734 * registered a callback for handling completion, the callback
735 * will never get called because we were unable to submit the
736 * request. So, free up the request right here.
738 if ((tr
->tr_flags
& TWA_CMD_IN_PROGRESS
) && (tr
->tr_callback
))
739 twa_release_request(tr
);
746 * Function name: twa_setup_request_dmamap
747 * Description: Callback of bus_dmamap_load for the buffer associated
750 * Input: arg -- ptr to request pkt
751 * segs -- ptr to a list of segment descriptors
752 * nsegments--# of segments
753 * error -- 0 if no errors encountered before callback,
754 * non-zero if errors were encountered
759 twa_setup_request_dmamap(void *arg
, bus_dma_segment_t
*segs
,
760 int nsegments
, int error
)
762 struct twa_softc
*sc
= (struct twa_softc
*)arg
;
764 twa_dbg_dprint_enter(10, sc
);
766 sc
->twa_cmd_pkt_phys
= segs
[0].ds_addr
;
772 * Function name: twa_map_request
773 * Description: Maps a cmd pkt and data associated with it, into
776 * Input: tr -- ptr to request pkt
778 * Return value: 0 -- success
782 twa_map_request(struct twa_request
*tr
)
784 struct twa_softc
*sc
= tr
->tr_sc
;
787 twa_dbg_dprint_enter(10, sc
);
789 /* If the command involves data, map that too. */
790 if (tr
->tr_data
!= NULL
) {
792 * It's sufficient for the data pointer to be 4-byte aligned
793 * to work with 9000. However, if 4-byte aligned addresses
794 * are passed to bus_dmamap_load, we can get back sg elements
795 * that are not 512-byte multiples in size. So, we will let
796 * only those buffers that are 512-byte aligned to pass
797 * through, and bounce the rest, so as to make sure that we
798 * always get back sg elements that are 512-byte multiples
801 * DragonFly's malloc only guarentees X alignment when X is
802 * a power of 2, otherwise we would have to use contigalloc,
803 * which is nasty. Use malloc.
805 if (((vm_offset_t
)tr
->tr_data
% 512) || (tr
->tr_length
% 512)) {
806 tr
->tr_flags
|= TWA_CMD_DATA_COPY_NEEDED
;
807 tr
->tr_real_data
= tr
->tr_data
; /* save original data pointer */
808 tr
->tr_real_length
= tr
->tr_length
; /* save original data length */
810 while (tr
->tr_length
< tr
->tr_real_length
)
812 tr
->tr_data
= kmalloc(tr
->tr_length
, TWA_MALLOC_CLASS
, M_INTWAIT
);
816 * Map the data buffer into bus space and build the s/g list.
818 if ((error
= bus_dmamap_load(sc
->twa_dma_tag
, tr
->tr_dma_map
,
819 tr
->tr_data
, tr
->tr_length
,
820 twa_setup_data_dmamap
, tr
,
822 if (error
== EINPROGRESS
) {
823 tr
->tr_flags
|= TWA_CMD_IN_PROGRESS
;
824 if (tr
->tr_cmd_pkt_type
& TWA_CMD_PKT_TYPE_EXTERNAL
)
825 twa_disallow_new_requests(sc
);
828 /* Free alignment buffer if it was used. */
829 if (tr
->tr_flags
& TWA_CMD_DATA_COPY_NEEDED
) {
830 kfree(tr
->tr_data
, TWA_MALLOC_CLASS
);
831 tr
->tr_data
= tr
->tr_real_data
; /* restore 'real' data pointer */
832 tr
->tr_length
= tr
->tr_real_length
;/* restore 'real' data length */
836 error
= tr
->tr_error
;
839 if ((error
= twa_submit_io(tr
)))
840 twa_unmap_request(tr
);
848 * Function name: twa_unmap_request
849 * Description: Undoes the mapping done by twa_map_request.
851 * Input: tr -- ptr to request pkt
856 twa_unmap_request(struct twa_request
*tr
)
858 struct twa_softc
*sc
= tr
->tr_sc
;
861 twa_dbg_dprint_enter(10, sc
);
863 /* If the command involved data, unmap that too. */
864 if (tr
->tr_data
!= NULL
) {
865 if (tr
->tr_cmd_pkt_type
& TWA_CMD_PKT_TYPE_9K
)
866 cmd_status
= tr
->tr_command
->command
.cmd_pkt_9k
.status
;
868 cmd_status
= tr
->tr_command
->command
.cmd_pkt_7k
.generic
.status
;
870 if (tr
->tr_flags
& TWA_CMD_DATA_IN
) {
871 bus_dmamap_sync(sc
->twa_dma_tag
,
872 tr
->tr_dma_map
, BUS_DMASYNC_POSTREAD
);
875 * If we are using a bounce buffer, and we are reading
876 * data, copy the real data in.
878 if (tr
->tr_flags
& TWA_CMD_DATA_COPY_NEEDED
)
880 bcopy(tr
->tr_data
, tr
->tr_real_data
,
883 if (tr
->tr_flags
& TWA_CMD_DATA_OUT
)
884 bus_dmamap_sync(sc
->twa_dma_tag
, tr
->tr_dma_map
,
885 BUS_DMASYNC_POSTWRITE
);
887 bus_dmamap_unload(sc
->twa_dma_tag
, tr
->tr_dma_map
);
890 /* Free alignment buffer if it was used. */
891 if (tr
->tr_flags
& TWA_CMD_DATA_COPY_NEEDED
) {
892 kfree(tr
->tr_data
, TWA_MALLOC_CLASS
);
893 tr
->tr_data
= tr
->tr_real_data
; /* restore 'real' data pointer */
894 tr
->tr_length
= tr
->tr_real_length
;/* restore 'real' data length */
901 void twa_report(void);
902 void twa_reset_stats(void);
903 void twa_print_request(struct twa_request
*tr
, int req_type
);
908 * Function name: twa_report
909 * Description: For being called from ddb. Prints controller stats,
910 * and requests, if any, that are in the wrong queue.
919 struct twa_softc
*sc
;
920 struct twa_request
*tr
;
924 for (i
= 0; (sc
= devclass_get_softc(twa_devclass
, i
)) != NULL
; i
++) {
925 twa_print_controller(sc
);
926 TAILQ_FOREACH(tr
, &sc
->twa_busy
, tr_link
)
927 twa_print_request(tr
, TWA_CMD_BUSY
);
928 TAILQ_FOREACH(tr
, &sc
->twa_complete
, tr_link
)
929 twa_print_request(tr
, TWA_CMD_COMPLETE
);
937 * Function name: twa_reset_stats
938 * Description: For being called from ddb.
939 * Resets some controller stats.
946 twa_reset_stats(void)
948 struct twa_softc
*sc
;
952 for (i
= 0; (sc
= devclass_get_softc(twa_devclass
, i
)) != NULL
; i
++) {
953 sc
->twa_qstats
[TWAQ_FREE
].q_max
= 0;
954 sc
->twa_qstats
[TWAQ_BUSY
].q_max
= 0;
955 sc
->twa_qstats
[TWAQ_PENDING
].q_max
= 0;
956 sc
->twa_qstats
[TWAQ_COMPLETE
].q_max
= 0;
964 * Function name: twa_print_request
965 * Description: Prints a given request if it's in the wrong queue.
967 * Input: tr -- ptr to request pkt
968 * req_type-- expected status of the given request
973 twa_print_request(struct twa_request
*tr
, int req_type
)
975 struct twa_softc
*sc
= tr
->tr_sc
;
976 struct twa_command_packet
*cmdpkt
= tr
->tr_command
;
977 struct twa_command_9k
*cmd9k
;
978 union twa_command_7k
*cmd7k
;
982 if (tr
->tr_status
!= req_type
) {
983 twa_printf(sc
, "Invalid %s request %p in queue! req_type = %x, queue_type = %x\n",
984 (tr
->tr_cmd_pkt_type
& TWA_CMD_PKT_TYPE_INTERNAL
) ? "INTERNAL" : "EXTERNAL",
985 tr
, tr
->tr_status
, req_type
);
987 if (tr
->tr_cmd_pkt_type
& TWA_CMD_PKT_TYPE_9K
) {
988 cmd9k
= &(cmdpkt
->command
.cmd_pkt_9k
);
989 cmd_phys_addr
= cmd9k
->sg_list
[0].address
;
990 twa_printf(sc
, "9K cmd = %x %x %x %x %x %x %x %x %x\n",
991 cmd9k
->command
.opcode
,
992 cmd9k
->command
.reserved
,
999 cmd9k
->sg_list
[0].length
);
1000 cdb
= (u_int8_t
*)(cmdpkt
->command
.cmd_pkt_9k
.cdb
);
1001 twa_printf(sc
, "cdb = %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x\n",
1002 cdb
[0], cdb
[1], cdb
[2], cdb
[3], cdb
[4], cdb
[5], cdb
[6], cdb
[7],
1003 cdb
[8], cdb
[9], cdb
[10], cdb
[11], cdb
[12], cdb
[13], cdb
[14], cdb
[15]);
1005 cmd7k
= &(cmdpkt
->command
.cmd_pkt_7k
);
1006 twa_printf(sc
, "7K cmd = %x %x %x %x %x %x %x %x %x\n",
1007 cmd7k
->generic
.opcode
,
1008 cmd7k
->generic
.sgl_offset
,
1009 cmd7k
->generic
.size
,
1010 cmd7k
->generic
.request_id
,
1011 cmd7k
->generic
.unit
,
1012 cmd7k
->generic
.host_id
,
1013 cmd7k
->generic
.status
,
1014 cmd7k
->generic
.flags
,
1015 cmd7k
->generic
.count
);
1018 cmd_phys_addr
= (int)(tr
->tr_cmd_phys
);
1019 twa_printf(sc
, "cmdphys=0x%x data=%p length=0x%x\n",
1020 cmd_phys_addr
, tr
->tr_data
, tr
->tr_length
);
1021 twa_printf(sc
, "req_id=0x%x flags=0x%x callback=%p private=%p\n",
1022 tr
->tr_request_id
, tr
->tr_flags
,
1023 tr
->tr_callback
, tr
->tr_private
);