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