1 /*-
2 * Copyright (c) 2003-04 3ware, Inc.
3 * Copyright (c) 2000 Michael Smith
4 * Copyright (c) 2000 BSDi
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
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.
15 *
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
26 * SUCH DAMAGE.
27 *
28 * $FreeBSD$
29 */
30
31 /*
32 * 3ware driver for 9000 series storage controllers.
33 *
34 * Author: Vinod Kashyap
35 */
36
37
38 #include <dev/twa/twa_includes.h>
39
40 static void twa_setup_data_dmamap(void *arg, bus_dma_segment_t *segs,
41 int nsegments, int error);
42 static void twa_setup_request_dmamap(void *arg, bus_dma_segment_t *segs,
43 int nsegments, int error);
44
45 MALLOC_DEFINE(TWA_MALLOC_CLASS, "twa commands", "twa commands");
46
47
48 static d_open_t twa_open;
49 static d_close_t twa_close;
50 static d_ioctl_t twa_ioctl_wrapper;
51
52 static struct cdevsw twa_cdevsw = {
53 twa_open,
54 twa_close,
55 noread,
56 nowrite,
57 twa_ioctl_wrapper,
58 nopoll,
59 nommap,
60 nostrategy,
61 "twa",
62 TWA_CDEV_MAJOR,
63 nodump,
64 nopsize,
65 0
66 };
67
68 static devclass_t twa_devclass;
69
70
71 /*
72 * Function name: twa_open
73 * Description: Called when the controller is opened.
74 * Simply marks the controller as open.
75 *
76 * Input: dev -- control device corresponding to the ctlr
77 * flags -- mode of open
78 * fmt -- device type (character/block etc.)
79 * proc -- current process
80 * Output: None
81 * Return value: 0 -- success
82 * non-zero-- failure
83 */
84 static int
85 twa_open(dev_t dev, int flags, int fmt, d_thread_t *proc)
86 {
87 int unit = minor(dev);
88 struct twa_softc *sc = devclass_get_softc(twa_devclass, unit);
89
90 sc->twa_state |= TWA_STATE_OPEN;
91 return(0);
92 }
93
94
95
96 /*
97 * Function name: twa_close
98 * Description: Called when the controller is closed.
99 * Simply marks the controller as not open.
100 *
101 * Input: dev -- control device corresponding to the ctlr
102 * flags -- mode of corresponding open
103 * fmt -- device type (character/block etc.)
104 * proc -- current process
105 * Output: None
106 * Return value: 0 -- success
107 * non-zero-- failure
108 */
109 static int
110 twa_close(dev_t dev, int flags, int fmt, d_thread_t *proc)
111 {
112 int unit = minor(dev);
113 struct twa_softc *sc = devclass_get_softc(twa_devclass, unit);
114
115 sc->twa_state &= ~TWA_STATE_OPEN;
116 return(0);
117 }
118
119
120
121 /*
122 * Function name: twa_ioctl_wrapper
123 * Description: Called when an ioctl is posted to the controller.
124 * Simply calls the ioctl handler.
125 *
126 * Input: dev -- control device corresponding to the ctlr
127 * cmd -- ioctl cmd
128 * buf -- ptr to buffer in kernel memory, which is
129 * a copy of the input buffer in user-space
130 * flags -- mode of corresponding open
131 * proc -- current process
132 * Output: buf -- ptr to buffer in kernel memory, which will
133 * be copied to the output buffer in user-space
134 * Return value: 0 -- success
135 * non-zero-- failure
136 */
137 static int
138 twa_ioctl_wrapper(dev_t dev, u_long cmd, caddr_t buf,
139 int flags, d_thread_t *proc)
140 {
141 struct twa_softc *sc = (struct twa_softc *)(dev->si_drv1);
142
143 return(twa_ioctl(sc, cmd, buf));
144 }
145
146
147
148 static int twa_probe (device_t dev);
149 static int twa_attach (device_t dev);
150 static void twa_free (struct twa_softc *sc);
151 static int twa_detach (device_t dev);
152 static int twa_shutdown (device_t dev);
153 static int twa_suspend (device_t dev);
154 static int twa_resume (device_t dev);
155 static void twa_pci_intr(void *arg);
156
157 static device_method_t twa_methods[] = {
158 /* Device interface */
159 DEVMETHOD(device_probe, twa_probe),
160 DEVMETHOD(device_attach, twa_attach),
161 DEVMETHOD(device_detach, twa_detach),
162 DEVMETHOD(device_shutdown, twa_shutdown),
163 DEVMETHOD(device_suspend, twa_suspend),
164 DEVMETHOD(device_resume, twa_resume),
165
166 DEVMETHOD(bus_print_child, bus_generic_print_child),
167 DEVMETHOD(bus_driver_added, bus_generic_driver_added),
168 {0, 0}
169 };
170
171 static driver_t twa_pci_driver = {
172 "twa",
173 twa_methods,
174 sizeof(struct twa_softc)
175 };
176
177 DRIVER_MODULE(twa, pci, twa_pci_driver, twa_devclass, 0, 0);
178
179
180
181 /*
182 * Function name: twa_probe
183 * Description: Called at driver load time. Claims 9000 ctlrs.
184 *
185 * Input: dev -- bus device corresponding to the ctlr
186 * Output: None
187 * Return value: <= 0 -- success
188 * > 0 -- failure
189 */
190 static int
191 twa_probe(device_t dev)
192 {
193 static u_int8_t first_ctlr = 1;
194
195 twa_dbg_print(3, "entered");
196
197 if ((pci_get_vendor(dev) == TWA_VENDOR_ID) &&
198 (pci_get_device(dev) == TWA_DEVICE_ID_9K)) {
199 device_set_desc(dev, TWA_DEVICE_NAME);
200 /* Print the driver version only once. */
201 if (first_ctlr) {
202 printf("3ware device driver for 9000 series storage controllers, version: %s\n",
203 TWA_DRIVER_VERSION_STRING);
204 first_ctlr = 0;
205 }
206 return(0);
207 }
208 return(ENXIO);
209 }
210
211
212
213 /*
214 * Function name: twa_attach
215 * Description: Allocates pci resources; updates sc; adds a node to the
216 * sysctl tree to expose the driver version; makes calls
217 * to initialize ctlr, and to attach to CAM.
218 *
219 * Input: dev -- bus device corresponding to the ctlr
220 * Output: None
221 * Return value: 0 -- success
222 * non-zero-- failure
223 */
224 static int
225 twa_attach(device_t dev)
226 {
227 struct twa_softc *sc = device_get_softc(dev);
228 u_int32_t command;
229 int res_id;
230 int error;
231
232 twa_dbg_dprint_enter(3, sc);
233
234 /* Initialize the softc structure. */
235 sc->twa_bus_dev = dev;
236
237 sysctl_ctx_init(&sc->twa_sysctl_ctx);
238 sc->twa_sysctl_tree = SYSCTL_ADD_NODE(&sc->twa_sysctl_ctx,
239 SYSCTL_STATIC_CHILDREN(_hw), OID_AUTO,
240 device_get_nameunit(dev), CTLFLAG_RD, 0, "");
241 if (sc->twa_sysctl_tree == NULL) {
242 twa_printf(sc, "Cannot add sysctl tree node.\n");
243 return(ENXIO);
244 }
245 SYSCTL_ADD_STRING(&sc->twa_sysctl_ctx, SYSCTL_CHILDREN(sc->twa_sysctl_tree),
246 OID_AUTO, "driver_version", CTLFLAG_RD,
247 TWA_DRIVER_VERSION_STRING, 0, "TWA driver version");
248
249 /* Make sure we are going to be able to talk to this board. */
250 command = pci_read_config(dev, PCIR_COMMAND, 2);
251 if ((command & PCIM_CMD_PORTEN) == 0) {
252 twa_printf(sc, "Register window not available.\n");
253 return(ENXIO);
254 }
255
256 /* Force the busmaster enable bit on, in case the BIOS forgot. */
257 command |= PCIM_CMD_BUSMASTEREN;
258 pci_write_config(dev, PCIR_COMMAND, command, 2);
259
260 /* Allocate the PCI register window. */
261 res_id = TWA_IO_CONFIG_REG;
262 if ((sc->twa_io_res = bus_alloc_resource(dev, SYS_RES_IOPORT, &res_id,
263 0, ~0, 1, RF_ACTIVE)) == NULL) {
264 twa_printf(sc, "can't allocate register window.\n");
265 twa_free(sc);
266 return(ENXIO);
267 }
268 sc->twa_bus_tag = rman_get_bustag(sc->twa_io_res);
269 sc->twa_bus_handle = rman_get_bushandle(sc->twa_io_res);
270
271 /* Allocate and connect our interrupt. */
272 res_id = 0;
273 if ((sc->twa_irq_res = bus_alloc_resource(sc->twa_bus_dev, SYS_RES_IRQ,
274 &res_id, 0, ~0, 1,
275 RF_SHAREABLE | RF_ACTIVE)) == NULL) {
276 twa_printf(sc, "Can't allocate interrupt.\n");
277 twa_free(sc);
278 return(ENXIO);
279 }
280 if (bus_setup_intr(sc->twa_bus_dev, sc->twa_irq_res, INTR_TYPE_CAM,
281 twa_pci_intr, sc, &sc->twa_intr_handle)) {
282 twa_printf(sc, "Can't set up interrupt.\n");
283 twa_free(sc);
284 return(ENXIO);
285 }
286
287 /* Initialize the driver for this controller. */
288 if ((error = twa_setup(sc))) {
289 twa_free(sc);
290 return(error);
291 }
292
293 /* Print some information about the controller and configuration. */
294 twa_describe_controller(sc);
295
296 /* Create the control device. */
297 sc->twa_ctrl_dev = make_dev(&twa_cdevsw, device_get_unit(sc->twa_bus_dev),
298 UID_ROOT, GID_OPERATOR, S_IRUSR | S_IWUSR,
299 "twa%d", device_get_unit(sc->twa_bus_dev));
300 sc->twa_ctrl_dev->si_drv1 = sc;
301
302 if ((error = twa_cam_setup(sc))) {
303 twa_free(sc);
304 return(error);
305 }
306 return(0);
307 }
308
309
310
311 /*
312 * Function name: twa_free
313 * Description: Performs clean-up at the time of going down.
314 *
315 * Input: sc -- ptr to per ctlr structure
316 * Output: None
317 * Return value: None
318 */
319 static void
320 twa_free(struct twa_softc *sc)
321 {
322 struct twa_request *tr;
323
324 twa_dbg_dprint_enter(3, sc);
325
326 /* Detach from CAM */
327 twa_cam_detach(sc);
328
329 /* Destroy dma handles. */
330
331 bus_dmamap_unload(sc->twa_cmd_tag, sc->twa_cmd_map);
332 while ((tr = twa_dequeue_free(sc)) != NULL)
333 bus_dmamap_destroy(sc->twa_buf_tag, tr->tr_buf_map);
334
335 /* Free all memory allocated so far. */
336 if (sc->twa_req_buf)
337 free(sc->twa_req_buf, TWA_MALLOC_CLASS);
338 if (sc->twa_cmd_pkt_buf)
339 bus_dmamem_free(sc->twa_cmd_tag, sc->twa_cmd_pkt_buf,
340 sc->twa_cmd_map);
341 if (sc->twa_aen_queue[0])
342 free(sc->twa_aen_queue[0], M_DEVBUF);
343
344 /* Destroy the data-transfer DMA tag. */
345 if (sc->twa_buf_tag)
346 bus_dma_tag_destroy(sc->twa_buf_tag);
347
348 /* Destroy the cmd DMA tag. */
349 if (sc->twa_cmd_tag)
350 bus_dma_tag_destroy(sc->twa_cmd_tag);
351
352 /* Destroy the parent DMA tag. */
353 if (sc->twa_parent_tag)
354 bus_dma_tag_destroy(sc->twa_parent_tag);
355
356 /* Disconnect the interrupt handler. */
357 if (sc->twa_intr_handle)
358 bus_teardown_intr(sc->twa_bus_dev, sc->twa_irq_res,
359 sc->twa_intr_handle);
360 if (sc->twa_irq_res != NULL)
361 bus_release_resource(sc->twa_bus_dev, SYS_RES_IRQ,
362 0, sc->twa_irq_res);
363
364 /* Release the register window mapping. */
365 if (sc->twa_io_res != NULL)
366 bus_release_resource(sc->twa_bus_dev, SYS_RES_IOPORT,
367 TWA_IO_CONFIG_REG, sc->twa_io_res);
368
369 /* Destroy the control device. */
370 if (sc->twa_ctrl_dev != (dev_t)NULL)
371 destroy_dev(sc->twa_ctrl_dev);
372
373 sysctl_ctx_free(&sc->twa_sysctl_ctx);
374 }
375
376
377
378 /*
379 * Function name: twa_detach
380 * Description: Called when the controller is being detached from
381 * the pci bus.
382 *
383 * Input: dev -- bus device corresponding to the ctlr
384 * Output: None
385 * Return value: 0 -- success
386 * non-zero-- failure
387 */
388 static int
389 twa_detach(device_t dev)
390 {
391 struct twa_softc *sc = device_get_softc(dev);
392 int s;
393 int error;
394
395 twa_dbg_dprint_enter(3, sc);
396
397 error = EBUSY;
398 s = splcam();
399 if (sc->twa_state & TWA_STATE_OPEN)
400 goto out;
401
402 /* Shut the controller down. */
403 if ((error = twa_shutdown(dev)))
404 goto out;
405
406 /* Free all resources associated with this controller. */
407 twa_free(sc);
408 error = 0;
409
410 out:
411 splx(s);
412 return(error);
413 }
414
415
416
417 /*
418 * Function name: twa_shutdown
419 * Description: Called at unload/shutdown time. Lets the controller
420 * know that we are going down.
421 *
422 * Input: dev -- bus device corresponding to the ctlr
423 * Output: None
424 * Return value: 0 -- success
425 * non-zero-- failure
426 */
427 static int
428 twa_shutdown(device_t dev)
429 {
430 struct twa_softc *sc = device_get_softc(dev);
431 int s;
432 int error = 0;
433
434 twa_dbg_dprint_enter(3, sc);
435
436 s = splcam();
437
438 /* Disconnect from the controller. */
439 error = twa_deinit_ctlr(sc);
440
441 splx(s);
442 return(error);
443 }
444
445
446
447 /*
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.
451 *
452 * Input: dev -- bus device corresponding to the ctlr
453 * Output: None
454 * Return value: 0 -- success
455 * non-zero-- failure
456 */
457 static int
458 twa_suspend(device_t dev)
459 {
460 struct twa_softc *sc = device_get_softc(dev);
461 int s;
462
463 twa_dbg_dprint_enter(3, sc);
464
465 s = splcam();
466 sc->twa_state |= TWA_STATE_SUSPEND;
467
468 twa_disable_interrupts(sc);
469 splx(s);
470
471 return(1);
472 }
473
474
475
476 /*
477 * Function name: twa_resume
478 * Description: Called to resume I/O after hot-swapping PCI ctlrs.
479 * Doesn't do much as of now.
480 *
481 * Input: dev -- bus device corresponding to the ctlr
482 * Output: None
483 * Return value: 0 -- success
484 * non-zero-- failure
485 */
486 static int
487 twa_resume(device_t dev)
488 {
489 struct twa_softc *sc = device_get_softc(dev);
490
491 twa_dbg_dprint_enter(3, sc);
492
493 sc->twa_state &= ~TWA_STATE_SUSPEND;
494 twa_enable_interrupts(sc);
495
496 return(1);
497 }
498
499
500
501 /*
502 * Function name: twa_pci_intr
503 * Description: Interrupt handler. Wrapper for twa_interrupt.
504 *
505 * Input: arg -- ptr to per ctlr structure
506 * Output: None
507 * Return value: None
508 */
509 static void
510 twa_pci_intr(void *arg)
511 {
512 struct twa_softc *sc = (struct twa_softc *)arg;
513
514 twa_interrupt(sc);
515 }
516
517
518
519 /*
520 * Function name: twa_write_pci_config
521 * Description: Writes to the PCI config space.
522 *
523 * Input: sc -- ptr to per ctlr structure
524 * value -- value to be written
525 * size -- # of bytes to be written
526 * Output: None
527 * Return value: None
528 */
529 void
530 twa_write_pci_config(struct twa_softc *sc, u_int32_t value, int size)
531 {
532 pci_write_config(sc->twa_bus_dev, PCIR_STATUS, value, size);
533 }
534
535
536
537 /*
538 * Function name: twa_alloc_req_pkts
539 * Description: Allocates memory for, and initializes request pkts,
540 * and queues them in the free queue.
541 *
542 * Input: sc -- ptr to per ctlr structure
543 * num_reqs-- # of request pkts to allocate and initialize.
544 * Output: None
545 * Return value: 0 -- success
546 * non-zero-- failure
547 */
548 int
549 twa_alloc_req_pkts(struct twa_softc *sc, int num_reqs)
550 {
551 struct twa_request *tr;
552 int i;
553
554 if ((sc->twa_req_buf = malloc(num_reqs * sizeof(struct twa_request),
555 TWA_MALLOC_CLASS, M_NOWAIT)) == NULL)
556 return(ENOMEM);
557
558 /* Create the parent dma tag. */
559 if (bus_dma_tag_create(NULL, /* parent */
560 TWA_ALIGNMENT, /* alignment */
561 0, /* boundary */
562 BUS_SPACE_MAXADDR, /* lowaddr */
563 BUS_SPACE_MAXADDR, /* highaddr */
564 NULL, NULL, /* filter, filterarg */
565 TWA_Q_LENGTH *
566 (sizeof(struct twa_command_packet)),/* maxsize */
567 TWA_MAX_SG_ELEMENTS, /* nsegments */
568 BUS_SPACE_MAXSIZE_32BIT,/* maxsegsize */
569 BUS_DMA_ALLOCNOW, /* flags */
570 &sc->twa_parent_tag /* tag */)) {
571 twa_printf(sc, "Can't allocate parent DMA tag.\n");
572 return(ENOMEM);
573 }
574
575 /* Create a bus dma tag for cmd pkts. */
576 if (bus_dma_tag_create(sc->twa_parent_tag, /* parent */
577 TWA_ALIGNMENT, /* alignment */
578 0, /* boundary */
579 BUS_SPACE_MAXADDR, /* lowaddr */
580 BUS_SPACE_MAXADDR, /* highaddr */
581 NULL, NULL, /* filter, filterarg */
582 TWA_Q_LENGTH *
583 (sizeof(struct twa_command_packet)),/* maxsize */
584 1, /* nsegments */
585 BUS_SPACE_MAXSIZE_32BIT,/* maxsegsize */
586 0, /* flags */
587 &sc->twa_cmd_tag /* tag */)) {
588 twa_printf(sc, "Can't allocate cmd DMA tag.\n");
589 return(ENOMEM);
590 }
591
592
593 /* Allocate memory for cmd pkts. */
594 if (bus_dmamem_alloc(sc->twa_cmd_tag,
595 (void *)(&(sc->twa_cmd_pkt_buf)),
596 BUS_DMA_WAITOK, &(sc->twa_cmd_map))) {
597 twa_printf(sc, "Can't allocate memory for cmd pkts.\n");
598 return(ENOMEM);
599 }
600
601 bus_dmamap_load(sc->twa_cmd_tag, sc->twa_cmd_map,
602 sc->twa_cmd_pkt_buf,
603 num_reqs * sizeof(struct twa_command_packet),
604 twa_setup_request_dmamap, sc, 0);
605 bzero(sc->twa_req_buf, num_reqs * sizeof(struct twa_request));
606 bzero(sc->twa_cmd_pkt_buf,
607 num_reqs * sizeof(struct twa_command_packet));
608
609 /* Create a bus dma tag for data buffers. */
610 if (bus_dma_tag_create(sc->twa_parent_tag, /* parent */
611 TWA_ALIGNMENT, /* alignment */
612 0, /* boundary */
613 BUS_SPACE_MAXADDR, /* lowaddr */
614 BUS_SPACE_MAXADDR, /* highaddr */
615 NULL, NULL, /* filter, filterarg */
616 TWA_MAX_IO_SIZE, /* maxsize */
617 TWA_MAX_SG_ELEMENTS, /* nsegments */
618 TWA_MAX_IO_SIZE, /* maxsegsize */
619 BUS_DMA_WAITOK, /* flags */
620 &sc->twa_buf_tag /* tag */)) {
621 twa_printf(sc, "Can't allocate buf DMA tag.\n");
622 return(ENOMEM);
623 }
624
625 for (i = 0; i < num_reqs; i++) {
626 tr = &(sc->twa_req_buf[i]);
627 tr->tr_command = &(sc->twa_cmd_pkt_buf[i]);
628 tr->tr_cmd_phys = sc->twa_cmd_pkt_phys +
629 (i * sizeof(struct twa_command_packet));
630 tr->tr_request_id = i;
631 tr->tr_sc = sc;
632 sc->twa_lookup[i] = tr;
633
634 /* Create maps for data buffers. */
635 if (bus_dmamap_create(sc->twa_buf_tag, 0,
636 &tr->tr_buf_map))
637 return(ENOMEM);
638
639 /* Insert request into the free queue. */
640 twa_release_request(tr);
641 }
642 return(0);
643 }
644
645
646
647 /*
648 * Function name: twa_fillin_sgl
649 * Description: Fills in the scatter/gather list.
650 *
651 * Input: sgl -- ptr to sg list
652 * segs -- ptr to fill the sg list from
653 * nsegments--# of segments
654 * Output: None
655 * Return value: None
656 */
657 static void
658 twa_fillin_sgl(struct twa_sg *sgl, bus_dma_segment_t *segs, int nsegments)
659 {
660 int i;
661
662 for (i = 0; i < nsegments; i++) {
663 sgl[i].address = segs[i].ds_addr;
664 sgl[i].length = (u_int32_t)(segs[i].ds_len);
665 }
666 }
667
668
669
670 /*
671 * Function name: twa_setup_data_dmamap
672 * Description: Callback of bus_dmamap_load for the buffer associated
673 * with data. Updates the cmd pkt (size/sgl_entries
674 * fields, as applicable) to reflect the number of sg
675 * elements.
676 *
677 * Input: arg -- ptr to request pkt
678 * segs -- ptr to a list of segment descriptors
679 * nsegments--# of segments
680 * error -- 0 if no errors encountered before callback,
681 * non-zero if errors were encountered
682 * Output: None
683 * Return value: None
684 */
685 static void
686 twa_setup_data_dmamap(void *arg, bus_dma_segment_t *segs,
687 int nsegments, int error)
688 {
689 struct twa_request *tr = (struct twa_request *)arg;
690 struct twa_command_packet *cmdpkt = tr->tr_command;
691 struct twa_command_9k *cmd9k;
692 union twa_command_7k *cmd7k;
693 u_int8_t sgl_offset;
694
695 twa_dbg_dprint_enter(10, tr->tr_sc);
696
697 tr->tr_flags |= TWA_CMD_MAPPED;
698 if ((tr->tr_flags & TWA_CMD_IN_PROGRESS) &&
699 (tr->tr_cmd_pkt_type & TWA_CMD_PKT_TYPE_EXTERNAL))
700 twa_allow_new_requests(tr->tr_sc, (void *)(tr->tr_private));
701
702 if (error == EFBIG) {
703 tr->tr_error = error;
704 goto out;
705 }
706
707 if (tr->tr_cmd_pkt_type & TWA_CMD_PKT_TYPE_9K) {
708 cmd9k = &(cmdpkt->command.cmd_pkt_9k);
709 twa_fillin_sgl(&(cmd9k->sg_list[0]), segs, nsegments);
710 cmd9k->sgl_entries += nsegments - 1;
711 } else {
712 /* It's a 7000 command packet. */
713 cmd7k = &(cmdpkt->command.cmd_pkt_7k);
714 if ((sgl_offset = cmdpkt->command.cmd_pkt_7k.generic.sgl_offset))
715 twa_fillin_sgl((struct twa_sg *)
716 (((u_int32_t *)cmd7k) + sgl_offset),
717 segs, nsegments);
718 /* Modify the size field, based on sg address size. */
719 cmd7k->generic.size +=
720 ((TWA_64BIT_ADDRESSES ? 3 : 2) * nsegments);
721 }
722
723 if (tr->tr_flags & TWA_CMD_DATA_IN)
724 bus_dmamap_sync(tr->tr_sc->twa_buf_tag, tr->tr_buf_map,
725 BUS_DMASYNC_PREREAD);
726 if (tr->tr_flags & TWA_CMD_DATA_OUT) {
727 /*
728 * If we're using an alignment buffer, and we're
729 * writing data, copy the real data out.
730 */
731 if (tr->tr_flags & TWA_CMD_DATA_COPY_NEEDED)
732 bcopy(tr->tr_real_data, tr->tr_data, tr->tr_real_length);
733 bus_dmamap_sync(tr->tr_sc->twa_buf_tag, tr->tr_buf_map,
734 BUS_DMASYNC_PREWRITE);
735 }
736 error = twa_submit_io(tr);
737
738 out:
739 if (error) {
740 twa_unmap_request(tr);
741 /*
742 * If the caller had been returned EINPROGRESS, and he has
743 * registered a callback for handling completion, the callback
744 * will never get called because we were unable to submit the
745 * request. So, free up the request right here.
746 */
747 if ((tr->tr_flags & TWA_CMD_IN_PROGRESS) && (tr->tr_callback))
748 twa_release_request(tr);
749 }
750 }
751
752
753
754 /*
755 * Function name: twa_setup_request_dmamap
756 * Description: Callback of bus_dmamap_load for the buffer associated
757 * with a cmd pkt.
758 *
759 * Input: arg -- ptr to request pkt
760 * segs -- ptr to a list of segment descriptors
761 * nsegments--# of segments
762 * error -- 0 if no errors encountered before callback,
763 * non-zero if errors were encountered
764 * Output: None
765 * Return value: None
766 */
767 static void
768 twa_setup_request_dmamap(void *arg, bus_dma_segment_t *segs,
769 int nsegments, int error)
770 {
771 struct twa_softc *sc = (struct twa_softc *)arg;
772
773 twa_dbg_dprint_enter(10, sc);
774
775 sc->twa_cmd_pkt_phys = segs[0].ds_addr;
776 }
777
778
779
780 /*
781 * Function name: twa_map_request
782 * Description: Maps a cmd pkt and data associated with it, into
783 * DMA'able memory.
784 *
785 * Input: tr -- ptr to request pkt
786 * Output: None
787 * Return value: 0 -- success
788 * non-zero-- failure
789 */
790 int
791 twa_map_request(struct twa_request *tr)
792 {
793 struct twa_softc *sc = tr->tr_sc;
794 int error = 0;
795
796 twa_dbg_dprint_enter(10, sc);
797
798 /* If the command involves data, map that too. */
799 if (tr->tr_data != NULL) {
800 /*
801 * It's sufficient for the data pointer to be 4-byte aligned
802 * to work with 9000. However, if 4-byte aligned addresses
803 * are passed to bus_dmamap_load, we can get back sg elements
804 * that are not 512-byte multiples in size. So, we will let
805 * only those buffers that are 512-byte aligned to pass
806 * through, and bounce the rest, so as to make sure that we
807 * always get back sg elements that are 512-byte multiples
808 * in size.
809 */
810 if (((vm_offset_t)tr->tr_data % 512) || (tr->tr_length % 512)) {
811 tr->tr_flags |= TWA_CMD_DATA_COPY_NEEDED;
812 tr->tr_real_data = tr->tr_data; /* save original data pointer */
813 tr->tr_real_length = tr->tr_length; /* save original data length */
814 tr->tr_length = (tr->tr_length + 511) & ~511;
815 tr->tr_data = malloc(tr->tr_length, TWA_MALLOC_CLASS, M_NOWAIT);
816 if (tr->tr_data == NULL) {
817 twa_printf(sc, "%s: malloc failed\n", __func__);
818 tr->tr_data = tr->tr_real_data; /* restore original data pointer */
819 tr->tr_length = tr->tr_real_length; /* restore original data length */
820 return(ENOMEM);
821 }
822 }
823
824 /*
825 * Map the data buffer into bus space and build the s/g list.
826 */
827 if ((error = bus_dmamap_load(sc->twa_buf_tag, tr->tr_buf_map,
828 tr->tr_data,
829 (bus_size_t)(tr->tr_length),
830 twa_setup_data_dmamap, tr,
831 BUS_DMA_WAITOK))) {
832 if (error == EINPROGRESS) {
833 int s;
834
835 s = splcam();
836 if (!(tr->tr_flags & TWA_CMD_MAPPED)) {
837 tr->tr_flags |= TWA_CMD_IN_PROGRESS;
838 if (tr->tr_cmd_pkt_type & TWA_CMD_PKT_TYPE_EXTERNAL)
839 twa_disallow_new_requests(sc);
840 }
841 splx(s);
842 error = 0;
843 } else {
844 /* Free alignment buffer if it was used. */
845 if (tr->tr_flags & TWA_CMD_DATA_COPY_NEEDED) {
846 free(tr->tr_data, TWA_MALLOC_CLASS);
847 tr->tr_data = tr->tr_real_data; /* restore 'real' data pointer */
848 tr->tr_length = tr->tr_real_length;/* restore 'real' data length */
849 }
850 }
851 } else
852 error = tr->tr_error;
853
854 } else
855 if ((error = twa_submit_io(tr)))
856 twa_unmap_request(tr);
857
858 return(error);
859 }
860
861
862
863 /*
864 * Function name: twa_unmap_request
865 * Description: Undoes the mapping done by twa_map_request.
866 *
867 * Input: tr -- ptr to request pkt
868 * Output: None
869 * Return value: None
870 */
871 void
872 twa_unmap_request(struct twa_request *tr)
873 {
874 struct twa_softc *sc = tr->tr_sc;
875 u_int8_t cmd_status;
876
877 twa_dbg_dprint_enter(10, sc);
878
879 /* If the command involved data, unmap that too. */
880 if (tr->tr_data != NULL) {
881 if (tr->tr_cmd_pkt_type & TWA_CMD_PKT_TYPE_9K)
882 cmd_status = tr->tr_command->command.cmd_pkt_9k.status;
883 else
884 cmd_status = tr->tr_command->command.cmd_pkt_7k.generic.status;
885
886 if (tr->tr_flags & TWA_CMD_DATA_IN) {
887 bus_dmamap_sync(sc->twa_buf_tag,
888 tr->tr_buf_map, BUS_DMASYNC_POSTREAD);
889
890 /*
891 * If we are using a bounce buffer, and we are reading
892 * data, copy the real data in.
893 */
894 if (tr->tr_flags & TWA_CMD_DATA_COPY_NEEDED)
895 if (cmd_status == 0)
896 bcopy(tr->tr_data, tr->tr_real_data,
897 tr->tr_real_length);
898 }
899 if (tr->tr_flags & TWA_CMD_DATA_OUT)
900 bus_dmamap_sync(sc->twa_buf_tag, tr->tr_buf_map,
901 BUS_DMASYNC_POSTWRITE);
902
903 bus_dmamap_unload(sc->twa_buf_tag, tr->tr_buf_map);
904 }
905
906 /* Free alignment buffer if it was used. */
907 if (tr->tr_flags & TWA_CMD_DATA_COPY_NEEDED) {
908 free(tr->tr_data, TWA_MALLOC_CLASS);
909 tr->tr_data = tr->tr_real_data; /* restore 'real' data pointer */
910 tr->tr_length = tr->tr_real_length;/* restore 'real' data length */
911 }
912 }
913
914
915
916 #ifdef TWA_DEBUG
917 void twa_report(void);
918 void twa_reset_stats(void);
919 void twa_print_request(struct twa_request *tr, int req_type);
920
921
922
923 /*
924 * Function name: twa_report
925 * Description: For being called from ddb. Prints controller stats,
926 * and requests, if any, that are in the wrong queue.
927 *
928 * Input: None
929 * Output: None
930 * Return value: None
931 */
932 void
933 twa_report(void)
934 {
935 struct twa_softc *sc;
936 struct twa_request *tr;
937 int s;
938 int i;
939
940 s = splcam();
941 for (i = 0; (sc = devclass_get_softc(twa_devclass, i)) != NULL; i++) {
942 twa_print_controller(sc);
943 TAILQ_FOREACH(tr, &sc->twa_busy, tr_link)
944 twa_print_request(tr, TWA_CMD_BUSY);
945 TAILQ_FOREACH(tr, &sc->twa_complete, tr_link)
946 twa_print_request(tr, TWA_CMD_COMPLETE);
947 }
948 splx(s);
949 }
950
951
952
953 /*
954 * Function name: twa_reset_stats
955 * Description: For being called from ddb.
956 * Resets some controller stats.
957 *
958 * Input: None
959 * Output: None
960 * Return value: None
961 */
962 void
963 twa_reset_stats(void)
964 {
965 struct twa_softc *sc;
966 int s;
967 int i;
968
969 s = splcam();
970 for (i = 0; (sc = devclass_get_softc(twa_devclass, i)) != NULL; i++) {
971 sc->twa_qstats[TWAQ_FREE].q_max = 0;
972 sc->twa_qstats[TWAQ_BUSY].q_max = 0;
973 sc->twa_qstats[TWAQ_PENDING].q_max = 0;
974 sc->twa_qstats[TWAQ_COMPLETE].q_max = 0;
975 }
976 splx(s);
977 }
978
979
980
981 /*
982 * Function name: twa_print_request
983 * Description: Prints a given request if it's in the wrong queue.
984 *
985 * Input: tr -- ptr to request pkt
986 * req_type-- expected status of the given request
987 * Output: None
988 * Return value: None
989 */
990 void
991 twa_print_request(struct twa_request *tr, int req_type)
992 {
993 struct twa_softc *sc = tr->tr_sc;
994 struct twa_command_packet *cmdpkt = tr->tr_command;
995 struct twa_command_9k *cmd9k;
996 union twa_command_7k *cmd7k;
997 u_int8_t *cdb;
998
999 if (tr->tr_status != req_type) {
1000 twa_printf(sc, "Invalid %s request %p in queue! req_type = %x, queue_type = %x\n",
1001 (tr->tr_cmd_pkt_type & TWA_CMD_PKT_TYPE_INTERNAL) ? "INTERNAL" : "EXTERNAL",
1002 tr, tr->tr_status, req_type);
1003
1004 if (tr->tr_cmd_pkt_type & TWA_CMD_PKT_TYPE_9K) {
1005 cmd9k = &(cmdpkt->command.cmd_pkt_9k);
1006 twa_printf(sc, "9K cmd = %x %x %x %x %x %x %x %llx %x\n",
1007 cmd9k->command.opcode,
1008 cmd9k->command.reserved,
1009 cmd9k->unit,
1010 cmd9k->request_id,
1011 cmd9k->status,
1012 cmd9k->sgl_offset,
1013 cmd9k->sgl_entries,
1014 (__uint64_t)(cmd9k->sg_list[0].address),
1015 cmd9k->sg_list[0].length);
1016 cdb = (u_int8_t *)(cmdpkt->command.cmd_pkt_9k.cdb);
1017 twa_printf(sc, "cdb = %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x\n",
1018 cdb[0], cdb[1], cdb[2], cdb[3], cdb[4], cdb[5], cdb[6], cdb[7],
1019 cdb[8], cdb[9], cdb[10], cdb[11], cdb[12], cdb[13], cdb[14], cdb[15]);
1020 } else {
1021 cmd7k = &(cmdpkt->command.cmd_pkt_7k);
1022 twa_printf(sc, "7K cmd = %x %x %x %x %x %x %x %x %x\n",
1023 cmd7k->generic.opcode,
1024 cmd7k->generic.sgl_offset,
1025 cmd7k->generic.size,
1026 cmd7k->generic.request_id,
1027 cmd7k->generic.unit,
1028 cmd7k->generic.host_id,
1029 cmd7k->generic.status,
1030 cmd7k->generic.flags,
1031 cmd7k->generic.count);
1032 }
1033
1034 twa_printf(sc, "cmd_phys=0x%llx data=%p length=0x%x\n",
1035 (__uint64_t)(tr->tr_cmd_phys), tr->tr_data,
1036 tr->tr_length);
1037 twa_printf(sc, "req_id=0x%x flags=0x%x callback=%p private=%p\n",
1038 tr->tr_request_id, tr->tr_flags,
1039 tr->tr_callback, tr->tr_private);
1040 }
1041 }
1042 #endif
Cache object: 05043a9bd33db0fbfea8a6de5be565b8
|