xref: /dflybsd-src/sys/dev/raid/twe/twe_freebsd.c (revision b5b0912b1891e95ccc48cad83f09239ccb7ffc16)
1 /*-
2  * Copyright (c) 2000 Michael Smith
3  * Copyright (c) 2000 BSDi
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  *
27  * $FreeBSD: src/sys/dev/twe/twe_freebsd.c,v 1.2.2.5 2002/03/07 09:57:02 msmith Exp $
28  * $DragonFly: src/sys/dev/raid/twe/twe_freebsd.c,v 1.13 2005/05/24 20:59:04 dillon Exp $
29  */
30 
31 /*
32  * FreeBSD-specific code.
33  */
34 
35 #include <sys/param.h>
36 #include <sys/cons.h>
37 #include <machine/bus.h>
38 #include <machine/clock.h>
39 #include <machine/md_var.h>
40 #include <vm/vm.h>
41 #include <vm/pmap.h>
42 #include "twe_compat.h"
43 #include "twereg.h"
44 #include "tweio.h"
45 #include "twevar.h"
46 #include "twe_tables.h"
47 
48 #include <sys/devicestat.h>
49 
50 static devclass_t	twe_devclass;
51 
52 #ifdef TWE_DEBUG
53 static u_int32_t	twed_bio_in;
54 #define TWED_BIO_IN	twed_bio_in++
55 static u_int32_t	twed_bio_out;
56 #define TWED_BIO_OUT	twed_bio_out++
57 #else
58 #define TWED_BIO_IN
59 #define TWED_BIO_OUT
60 #endif
61 
62 /********************************************************************************
63  ********************************************************************************
64                                                          Control device interface
65  ********************************************************************************
66  ********************************************************************************/
67 
68 static	d_open_t		twe_open;
69 static	d_close_t		twe_close;
70 static	d_ioctl_t		twe_ioctl_wrapper;
71 
72 #define TWE_CDEV_MAJOR  146
73 
74 static struct cdevsw twe_cdevsw = {
75     /* name */	"twe",
76     /* cmaj */	TWE_CDEV_MAJOR,
77     /* flags */	0,
78     /* port */	NULL,
79     /* clone */	NULL,
80 
81     twe_open,
82     twe_close,
83     noread,
84     nowrite,
85     twe_ioctl_wrapper,
86     nopoll,
87     nommap,
88     nostrategy,
89     nodump,
90     nopsize,
91 };
92 
93 /********************************************************************************
94  * Accept an open operation on the control device.
95  */
96 static int
97 twe_open(dev_t dev, int flags, int fmt, d_thread_t *td)
98 {
99     int			unit = minor(dev);
100     struct twe_softc	*sc = devclass_get_softc(twe_devclass, unit);
101 
102     sc->twe_state |= TWE_STATE_OPEN;
103     return(0);
104 }
105 
106 /********************************************************************************
107  * Accept the last close on the control device.
108  */
109 static int
110 twe_close(dev_t dev, int flags, int fmt, d_thread_t *td)
111 {
112     int			unit = minor(dev);
113     struct twe_softc	*sc = devclass_get_softc(twe_devclass, unit);
114 
115     sc->twe_state &= ~TWE_STATE_OPEN;
116     return (0);
117 }
118 
119 /********************************************************************************
120  * Handle controller-specific control operations.
121  */
122 static int
123 twe_ioctl_wrapper(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, d_thread_t *td)
124 {
125     struct twe_softc		*sc = (struct twe_softc *)dev->si_drv1;
126 
127     return(twe_ioctl(sc, cmd, addr));
128 }
129 
130 /********************************************************************************
131  ********************************************************************************
132                                                              PCI device interface
133  ********************************************************************************
134  ********************************************************************************/
135 
136 static int	twe_probe(device_t dev);
137 static int	twe_attach(device_t dev);
138 static void	twe_free(struct twe_softc *sc);
139 static int	twe_detach(device_t dev);
140 static void	twe_shutdown(device_t dev);
141 static int	twe_suspend(device_t dev);
142 static int	twe_resume(device_t dev);
143 static void	twe_pci_intr(void *arg);
144 static void	twe_intrhook(void *arg);
145 
146 static device_method_t twe_methods[] = {
147     /* Device interface */
148     DEVMETHOD(device_probe,	twe_probe),
149     DEVMETHOD(device_attach,	twe_attach),
150     DEVMETHOD(device_detach,	twe_detach),
151     DEVMETHOD(device_shutdown,	twe_shutdown),
152     DEVMETHOD(device_suspend,	twe_suspend),
153     DEVMETHOD(device_resume,	twe_resume),
154 
155     DEVMETHOD(bus_print_child,	bus_generic_print_child),
156     DEVMETHOD(bus_driver_added,	bus_generic_driver_added),
157     { 0, 0 }
158 };
159 
160 static driver_t twe_pci_driver = {
161 	"twe",
162 	twe_methods,
163 	sizeof(struct twe_softc)
164 };
165 
166 #ifdef TWE_OVERRIDE
167 DRIVER_MODULE(Xtwe, pci, twe_pci_driver, twe_devclass, 0, 0);
168 #else
169 DRIVER_MODULE(twe, pci, twe_pci_driver, twe_devclass, 0, 0);
170 #endif
171 
172 /********************************************************************************
173  * Match a 3ware Escalade ATA RAID controller.
174  */
175 static int
176 twe_probe(device_t dev)
177 {
178 
179     debug_called(4);
180 
181     if ((pci_get_vendor(dev) == TWE_VENDOR_ID) &&
182 	((pci_get_device(dev) == TWE_DEVICE_ID) ||
183 	 (pci_get_device(dev) == TWE_DEVICE_ID_ASIC))) {
184 	device_set_desc(dev, TWE_DEVICE_NAME);
185 #ifdef TWE_OVERRIDE
186 	return(0);
187 #else
188 	return(-10);
189 #endif
190     }
191     return(ENXIO);
192 }
193 
194 /********************************************************************************
195  * Allocate resources, initialise the controller.
196  */
197 static int
198 twe_attach(device_t dev)
199 {
200     struct twe_softc	*sc;
201     int			rid, error;
202     u_int32_t		command;
203     dev_t		xdev;
204 
205     debug_called(4);
206 
207     /*
208      * Initialise the softc structure.
209      */
210     sc = device_get_softc(dev);
211     sc->twe_dev = dev;
212 
213     sysctl_ctx_init(&sc->sysctl_ctx);
214     sc->sysctl_tree = SYSCTL_ADD_NODE(&sc->sysctl_ctx,
215 	SYSCTL_STATIC_CHILDREN(_hw), OID_AUTO,
216 	device_get_nameunit(dev), CTLFLAG_RD, 0, "");
217     if (sc->sysctl_tree == NULL) {
218 	twe_printf(sc, "cannot add sysctl tree node\n");
219 	return (ENXIO);
220     }
221     SYSCTL_ADD_STRING(&sc->sysctl_ctx, SYSCTL_CHILDREN(sc->sysctl_tree),
222 	OID_AUTO, "driver_version", CTLFLAG_RD, "$Revision$", 0,
223 	"TWE driver version");
224 
225     /*
226      * Make sure we are going to be able to talk to this board.
227      */
228     command = pci_read_config(dev, PCIR_COMMAND, 2);
229     if ((command & PCIM_CMD_PORTEN) == 0) {
230 	twe_printf(sc, "register window not available\n");
231 	return(ENXIO);
232     }
233     /*
234      * Force the busmaster enable bit on, in case the BIOS forgot.
235      */
236     command |= PCIM_CMD_BUSMASTEREN;
237     pci_write_config(dev, PCIR_COMMAND, command, 2);
238 
239     /*
240      * Allocate the PCI register window.
241      */
242     rid = TWE_IO_CONFIG_REG;
243     if ((sc->twe_io = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 1, RF_ACTIVE)) == NULL) {
244 	twe_printf(sc, "can't allocate register window\n");
245 	twe_free(sc);
246 	return(ENXIO);
247     }
248     sc->twe_btag = rman_get_bustag(sc->twe_io);
249     sc->twe_bhandle = rman_get_bushandle(sc->twe_io);
250 
251     /*
252      * Allocate the parent bus DMA tag appropriate for PCI.
253      */
254     if (bus_dma_tag_create(NULL, 				/* parent */
255 			   1, 0, 				/* alignment, boundary */
256 			   BUS_SPACE_MAXADDR_32BIT, 		/* lowaddr */
257 			   BUS_SPACE_MAXADDR, 			/* highaddr */
258 			   NULL, NULL, 				/* filter, filterarg */
259 			   MAXBSIZE, TWE_MAX_SGL_LENGTH,	/* maxsize, nsegments */
260 			   BUS_SPACE_MAXSIZE_32BIT,		/* maxsegsize */
261 			   BUS_DMA_ALLOCNOW,			/* flags */
262 			   &sc->twe_parent_dmat)) {
263 	twe_printf(sc, "can't allocate parent DMA tag\n");
264 	twe_free(sc);
265 	return(ENOMEM);
266     }
267 
268     /*
269      * Allocate and connect our interrupt.
270      */
271     rid = 0;
272     if ((sc->twe_irq = bus_alloc_resource(sc->twe_dev, SYS_RES_IRQ, &rid, 0, ~0, 1, RF_SHAREABLE | RF_ACTIVE)) == NULL) {
273 	twe_printf(sc, "can't allocate interrupt\n");
274 	twe_free(sc);
275 	return(ENXIO);
276     }
277     error = bus_setup_intr(sc->twe_dev, sc->twe_irq,
278 			   INTR_TYPE_BIO | INTR_ENTROPY, twe_pci_intr, sc,
279 			   &sc->twe_intr, NULL);
280     if (error) {
281 	twe_printf(sc, "can't set up interrupt\n");
282 	twe_free(sc);
283 	return(ENXIO);
284     }
285 
286     /*
287      * Create DMA tag for mapping objects into controller-addressable space.
288      */
289     if (bus_dma_tag_create(sc->twe_parent_dmat, 	/* parent */
290 			   1, 0, 			/* alignment, boundary */
291 			   BUS_SPACE_MAXADDR,		/* lowaddr */
292 			   BUS_SPACE_MAXADDR, 		/* highaddr */
293 			   NULL, NULL, 			/* filter, filterarg */
294 			   MAXBSIZE, TWE_MAX_SGL_LENGTH,/* maxsize, nsegments */
295 			   BUS_SPACE_MAXSIZE_32BIT,	/* maxsegsize */
296 			   0,				/* flags */
297 			   &sc->twe_buffer_dmat)) {
298 	twe_printf(sc, "can't allocate data buffer DMA tag\n");
299 	twe_free(sc);
300 	return(ENOMEM);
301     }
302 
303     /*
304      * Initialise the controller and driver core.
305      */
306     if ((error = twe_setup(sc)))
307 	return(error);
308 
309     /*
310      * Print some information about the controller and configuration.
311      */
312     twe_describe_controller(sc);
313 
314     /*
315      * Create the control device.
316      */
317     cdevsw_add(&twe_cdevsw, -1, device_get_unit(sc->twe_dev));
318     xdev = make_dev(&twe_cdevsw, device_get_unit(sc->twe_dev),
319 			    UID_ROOT, GID_OPERATOR, S_IRUSR | S_IWUSR,
320 			    "twe%d", device_get_unit(sc->twe_dev));
321     xdev->si_drv1 = sc;
322 
323     /*
324      * Schedule ourselves to bring the controller up once interrupts are available.
325      * This isn't strictly necessary, since we disable interrupts while probing the
326      * controller, but it is more in keeping with common practice for other disk
327      * devices.
328      */
329     sc->twe_ich.ich_func = twe_intrhook;
330     sc->twe_ich.ich_arg = sc;
331     sc->twe_ich.ich_desc = "twe";
332     if (config_intrhook_establish(&sc->twe_ich) != 0) {
333 	twe_printf(sc, "can't establish configuration hook\n");
334 	twe_free(sc);
335 	return(ENXIO);
336     }
337 
338     return(0);
339 }
340 
341 /********************************************************************************
342  * Free all of the resources associated with (sc).
343  *
344  * Should not be called if the controller is active.
345  */
346 static void
347 twe_free(struct twe_softc *sc)
348 {
349     struct twe_request	*tr;
350 
351     debug_called(4);
352 
353     /* throw away any command buffers */
354     while ((tr = twe_dequeue_free(sc)) != NULL)
355 	twe_free_request(tr);
356 
357     /* destroy the data-transfer DMA tag */
358     if (sc->twe_buffer_dmat)
359 	bus_dma_tag_destroy(sc->twe_buffer_dmat);
360 
361     /* disconnect the interrupt handler */
362     if (sc->twe_intr)
363 	bus_teardown_intr(sc->twe_dev, sc->twe_irq, sc->twe_intr);
364     if (sc->twe_irq != NULL)
365 	bus_release_resource(sc->twe_dev, SYS_RES_IRQ, 0, sc->twe_irq);
366 
367     /* destroy the parent DMA tag */
368     if (sc->twe_parent_dmat)
369 	bus_dma_tag_destroy(sc->twe_parent_dmat);
370 
371     /* release the register window mapping */
372     if (sc->twe_io != NULL)
373 	bus_release_resource(sc->twe_dev, SYS_RES_IOPORT, TWE_IO_CONFIG_REG, sc->twe_io);
374 
375     cdevsw_remove(&twe_cdevsw, -1, device_get_unit(sc->twe_dev));
376 
377     sysctl_ctx_free(&sc->sysctl_ctx);
378 }
379 
380 /********************************************************************************
381  * Disconnect from the controller completely, in preparation for unload.
382  */
383 static int
384 twe_detach(device_t dev)
385 {
386     struct twe_softc	*sc = device_get_softc(dev);
387     int			s, error;
388 
389     debug_called(4);
390 
391     error = EBUSY;
392     s = splbio();
393     if (sc->twe_state & TWE_STATE_OPEN)
394 	goto out;
395 
396     /*
397      * Shut the controller down.
398      */
399     twe_shutdown(dev);
400 
401     twe_free(sc);
402 
403     error = 0;
404  out:
405     splx(s);
406     return(error);
407 }
408 
409 /********************************************************************************
410  * Bring the controller down to a dormant state and detach all child devices.
411  *
412  * Note that we can assume that the bioq on the controller is empty, as we won't
413  * allow shutdown if any device is open.
414  */
415 static void
416 twe_shutdown(device_t dev)
417 {
418     struct twe_softc	*sc = device_get_softc(dev);
419     int			i, s;
420 
421     debug_called(4);
422 
423     s = splbio();
424 
425     /*
426      * Delete all our child devices.
427      */
428     for (i = 0; i < TWE_MAX_UNITS; i++) {
429 	twe_detach_drive(sc, i);
430     }
431 
432     /*
433      * Bring the controller down.
434      */
435     twe_deinit(sc);
436 
437     splx(s);
438 }
439 
440 /********************************************************************************
441  * Bring the controller to a quiescent state, ready for system suspend.
442  */
443 static int
444 twe_suspend(device_t dev)
445 {
446     struct twe_softc	*sc = device_get_softc(dev);
447     int			s;
448 
449     debug_called(4);
450 
451     s = splbio();
452     sc->twe_state |= TWE_STATE_SUSPEND;
453 
454     twe_disable_interrupts(sc);
455     splx(s);
456 
457     return(0);
458 }
459 
460 /********************************************************************************
461  * Bring the controller back to a state ready for operation.
462  */
463 static int
464 twe_resume(device_t dev)
465 {
466     struct twe_softc	*sc = device_get_softc(dev);
467 
468     debug_called(4);
469 
470     sc->twe_state &= ~TWE_STATE_SUSPEND;
471     twe_enable_interrupts(sc);
472 
473     return(0);
474 }
475 
476 /*******************************************************************************
477  * Take an interrupt, or be poked by other code to look for interrupt-worthy
478  * status.
479  */
480 static void
481 twe_pci_intr(void *arg)
482 {
483     twe_intr((struct twe_softc *)arg);
484 }
485 
486 /********************************************************************************
487  * Delayed-startup hook
488  */
489 static void
490 twe_intrhook(void *arg)
491 {
492     struct twe_softc		*sc = (struct twe_softc *)arg;
493 
494     /* pull ourselves off the intrhook chain */
495     config_intrhook_disestablish(&sc->twe_ich);
496 
497     /* call core startup routine */
498     twe_init(sc);
499 }
500 
501 /********************************************************************************
502  * Given a detected drive, attach it to the bio interface.
503  *
504  * This is called from twe_add_unit.
505  */
506 void
507 twe_attach_drive(struct twe_softc *sc, struct twe_drive *dr)
508 {
509     char	buf[80];
510     int		error;
511 
512     dr->td_disk =  device_add_child(sc->twe_dev, NULL, -1);
513     if (dr->td_disk == NULL) {
514 	twe_printf(sc, "device_add_child failed\n");
515 	return;
516     }
517     device_set_ivars(dr->td_disk, dr);
518 
519     /*
520      * XXX It would make sense to test the online/initialising bits, but they seem to be
521      * always set...
522      */
523     sprintf(buf, "Unit %d, %s, %s",
524 	    dr->td_unit,
525 	    twe_describe_code(twe_table_unittype, dr->td_type),
526 	    twe_describe_code(twe_table_unitstate, dr->td_state & TWE_PARAM_UNITSTATUS_MASK));
527     device_set_desc_copy(dr->td_disk, buf);
528 
529     if ((error = bus_generic_attach(sc->twe_dev)) != 0)
530 	twe_printf(sc, "bus_generic_attach returned %d\n", error);
531 }
532 
533 /********************************************************************************
534  * Detach the specified unit if it exsists
535  *
536  * This is called from twe_del_unit.
537  */
538 void
539 twe_detach_drive(struct twe_softc *sc, int unit)
540 {
541 
542     if (sc->twe_drive[unit].td_disk != 0) {
543 	if (device_delete_child(sc->twe_dev, sc->twe_drive[unit].td_disk) != 0)
544 	    twe_printf(sc, "failed to delete unit %d\n", unit);
545 	sc->twe_drive[unit].td_disk = 0;
546     }
547 }
548 
549 /********************************************************************************
550  * Clear a PCI parity error.
551  */
552 void
553 twe_clear_pci_parity_error(struct twe_softc *sc)
554 {
555     TWE_CONTROL(sc, TWE_CONTROL_CLEAR_PARITY_ERROR);
556     pci_write_config(sc->twe_dev, PCIR_STATUS, TWE_PCI_CLEAR_PARITY_ERROR, 2);
557 }
558 
559 /********************************************************************************
560  * Clear a PCI abort.
561  */
562 void
563 twe_clear_pci_abort(struct twe_softc *sc)
564 {
565     TWE_CONTROL(sc, TWE_CONTROL_CLEAR_PCI_ABORT);
566     pci_write_config(sc->twe_dev, PCIR_STATUS, TWE_PCI_CLEAR_PCI_ABORT, 2);
567 }
568 
569 /********************************************************************************
570  ********************************************************************************
571                                                                       Disk device
572  ********************************************************************************
573  ********************************************************************************/
574 
575 /*
576  * Disk device softc
577  */
578 struct twed_softc
579 {
580     device_t		twed_dev;
581     dev_t		twed_dev_t;
582     struct twe_softc	*twed_controller;	/* parent device softc */
583     struct twe_drive	*twed_drive;		/* drive data in parent softc */
584     struct disk		twed_disk;		/* generic disk handle */
585     struct devstat	twed_stats;		/* accounting */
586     struct disklabel	twed_label;		/* synthetic label */
587     int			twed_flags;
588 #define TWED_OPEN	(1<<0)			/* drive is open (can't shut down) */
589 };
590 
591 /*
592  * Disk device bus interface
593  */
594 static int twed_probe(device_t dev);
595 static int twed_attach(device_t dev);
596 static int twed_detach(device_t dev);
597 
598 static device_method_t twed_methods[] = {
599     DEVMETHOD(device_probe,	twed_probe),
600     DEVMETHOD(device_attach,	twed_attach),
601     DEVMETHOD(device_detach,	twed_detach),
602     { 0, 0 }
603 };
604 
605 static driver_t twed_driver = {
606     "twed",
607     twed_methods,
608     sizeof(struct twed_softc)
609 };
610 
611 static devclass_t	twed_devclass;
612 #ifdef TWE_OVERRIDE
613 DRIVER_MODULE(Xtwed, Xtwe, twed_driver, twed_devclass, 0, 0);
614 #else
615 DRIVER_MODULE(twed, twe, twed_driver, twed_devclass, 0, 0);
616 #endif
617 
618 /*
619  * Disk device control interface.
620  */
621 static	d_open_t	twed_open;
622 static	d_close_t	twed_close;
623 static	d_strategy_t	twed_strategy;
624 static	d_dump_t	twed_dump;
625 
626 #define TWED_CDEV_MAJOR	147
627 
628 static struct cdevsw twed_cdevsw = {
629     "twed",
630     TWED_CDEV_MAJOR,
631     D_DISK,
632     /* port */	NULL,
633     /* clone */ NULL,
634     twed_open,
635     twed_close,
636     physread,
637     physwrite,
638     noioctl,
639     nopoll,
640     nommap,
641     twed_strategy,
642     twed_dump,
643     nopsize,
644 };
645 
646 
647 /********************************************************************************
648  * Handle open from generic layer.
649  *
650  * Note that this is typically only called by the diskslice code, and not
651  * for opens on subdevices (eg. slices, partitions).
652  */
653 static int
654 twed_open(dev_t dev, int flags, int fmt, d_thread_t *td)
655 {
656     struct twed_softc	*sc = (struct twed_softc *)dev->si_drv1;
657     struct disklabel	*label;
658 
659     debug_called(4);
660 
661     if (sc == NULL)
662 	return (ENXIO);
663 
664     /* check that the controller is up and running */
665     if (sc->twed_controller->twe_state & TWE_STATE_SHUTDOWN)
666 	return(ENXIO);
667 
668     /* build synthetic label */
669     label = &sc->twed_disk.d_label;
670     bzero(label, sizeof(*label));
671     label->d_type = DTYPE_ESDI;
672     label->d_secsize    = TWE_BLOCK_SIZE;
673     label->d_nsectors   = sc->twed_drive->td_sectors;
674     label->d_ntracks    = sc->twed_drive->td_heads;
675     label->d_ncylinders = sc->twed_drive->td_cylinders;
676     label->d_secpercyl  = sc->twed_drive->td_sectors * sc->twed_drive->td_heads;
677     label->d_secperunit = sc->twed_drive->td_size;
678 
679     sc->twed_flags |= TWED_OPEN;
680     return (0);
681 }
682 
683 /********************************************************************************
684  * Handle last close of the disk device.
685  */
686 static int
687 twed_close(dev_t dev, int flags, int fmt, d_thread_t *td)
688 {
689     struct twed_softc	*sc = (struct twed_softc *)dev->si_drv1;
690 
691     debug_called(4);
692 
693     if (sc == NULL)
694 	return (ENXIO);
695 
696     sc->twed_flags &= ~TWED_OPEN;
697     return (0);
698 }
699 
700 /********************************************************************************
701  * Handle an I/O request.
702  */
703 static void
704 twed_strategy(twe_bio *bp)
705 {
706     struct twed_softc	*sc = (struct twed_softc *)TWE_BIO_SOFTC(bp);
707 
708     debug_called(4);
709 
710     TWED_BIO_IN;
711 
712     /* bogus disk? */
713     if (sc == NULL) {
714 	TWE_BIO_SET_ERROR(bp, EINVAL);
715 	printf("twe: bio for invalid disk!\n");
716 	TWE_BIO_DONE(bp);
717 	TWED_BIO_OUT;
718 	return;
719     }
720 
721     /* perform accounting */
722     TWE_BIO_STATS_START(bp);
723 
724     /* queue the bio on the controller */
725     twe_enqueue_bio(sc->twed_controller, bp);
726 
727     /* poke the controller to start I/O */
728     twe_startio(sc->twed_controller);
729     return;
730 }
731 
732 /********************************************************************************
733  * System crashdump support
734  */
735 int
736 twed_dump(dev_t dev, u_int count, u_int blkno, u_int secsize)
737 {
738     struct twed_softc	*twed_sc = (struct twed_softc *)dev->si_drv1;
739     struct twe_softc	*twe_sc  = (struct twe_softc *)twed_sc->twed_controller;
740     vm_paddr_t		addr = 0;
741     long		blkcnt;
742     int			dumppages = MAXDUMPPGS;
743     int			error;
744     int			i;
745 
746     if (!twed_sc || !twe_sc)
747 	return(ENXIO);
748 
749     blkcnt = howmany(PAGE_SIZE, secsize);
750 
751     while (count > 0) {
752 	caddr_t va = NULL;
753 
754 	if ((count / blkcnt) < dumppages)
755 	    dumppages = count / blkcnt;
756 
757 	for (i = 0; i < dumppages; ++i) {
758 	    vm_paddr_t a = addr + (i * PAGE_SIZE);
759 	    if (is_physical_memory(a))
760 		va = pmap_kenter_temporary(trunc_page(a), i);
761 	    else
762 		va = pmap_kenter_temporary(trunc_page(0), i);
763 	}
764 
765 	if ((error = twe_dump_blocks(twe_sc, twed_sc->twed_drive->td_unit, blkno, va,
766 				     (PAGE_SIZE * dumppages) / TWE_BLOCK_SIZE)) != 0)
767 	    return(error);
768 
769 
770 	if (dumpstatus(addr, (off_t)count * DEV_BSIZE) < 0)
771 	    return(EINTR);
772 
773 	blkno += blkcnt * dumppages;
774 	count -= blkcnt * dumppages;
775 	addr += PAGE_SIZE * dumppages;
776     }
777     return(0);
778 }
779 
780 /********************************************************************************
781  * Handle completion of an I/O request.
782  */
783 void
784 twed_intr(twe_bio *bp)
785 {
786     debug_called(4);
787 
788     /* if no error, transfer completed */
789     if (!TWE_BIO_HAS_ERROR(bp))
790 	TWE_BIO_RESID(bp) = 0;
791 
792     TWE_BIO_STATS_END(bp);
793     TWE_BIO_DONE(bp);
794     TWED_BIO_OUT;
795 }
796 
797 /********************************************************************************
798  * Default probe stub.
799  */
800 static int
801 twed_probe(device_t dev)
802 {
803     return (0);
804 }
805 
806 /********************************************************************************
807  * Attach a unit to the controller.
808  */
809 static int
810 twed_attach(device_t dev)
811 {
812     struct twed_softc	*sc;
813     device_t		parent;
814     dev_t		dsk;
815 
816     debug_called(4);
817 
818     /* initialise our softc */
819     sc = device_get_softc(dev);
820     parent = device_get_parent(dev);
821     sc->twed_controller = (struct twe_softc *)device_get_softc(parent);
822     sc->twed_drive = device_get_ivars(dev);
823     sc->twed_dev = dev;
824 
825     /* report the drive */
826     twed_printf(sc, "%uMB (%u sectors)\n",
827 		sc->twed_drive->td_size / ((1024 * 1024) / TWE_BLOCK_SIZE),
828 		sc->twed_drive->td_size);
829 
830     devstat_add_entry(&sc->twed_stats, "twed", device_get_unit(dev), TWE_BLOCK_SIZE,
831 		      DEVSTAT_NO_ORDERED_TAGS,
832 		      DEVSTAT_TYPE_STORARRAY | DEVSTAT_TYPE_IF_OTHER,
833 		      DEVSTAT_PRIORITY_ARRAY);
834 
835     /* attach a generic disk device to ourselves */
836     dsk = disk_create(device_get_unit(dev), &sc->twed_disk, 0, &twed_cdevsw);
837     dsk->si_drv1 = sc;
838     dsk->si_drv2 = &sc->twed_drive->td_unit;
839     sc->twed_dev_t = dsk;
840 
841     /* set the maximum I/O size to the theoretical maximum allowed by the S/G list size */
842     dsk->si_iosize_max = (TWE_MAX_SGL_LENGTH - 1) * PAGE_SIZE;
843 
844     return (0);
845 }
846 
847 /********************************************************************************
848  * Disconnect ourselves from the system.
849  */
850 static int
851 twed_detach(device_t dev)
852 {
853     struct twed_softc *sc = (struct twed_softc *)device_get_softc(dev);
854 
855     debug_called(4);
856 
857     if (sc->twed_flags & TWED_OPEN)
858 	return(EBUSY);
859 
860     devstat_remove_entry(&sc->twed_stats);
861     disk_destroy(&sc->twed_disk);
862 
863     return(0);
864 }
865 
866 /********************************************************************************
867  ********************************************************************************
868                                                                              Misc
869  ********************************************************************************
870  ********************************************************************************/
871 
872 static void	twe_setup_data_dmamap(void *arg, bus_dma_segment_t *segs, int nsegments, int error);
873 static void	twe_setup_request_dmamap(void *arg, bus_dma_segment_t *segs, int nsegments, int error);
874 
875 /********************************************************************************
876  * Malloc space for a command buffer.
877  */
878 MALLOC_DEFINE(TWE_MALLOC_CLASS, "twe commands", "twe commands");
879 
880 struct twe_request *
881 twe_allocate_request(struct twe_softc *sc)
882 {
883     struct twe_request	*tr;
884     int aligned_size;
885 
886     /*
887      * TWE requires requests to be 512-byte aligned.  Depend on malloc()
888      * guarenteeing alignment for power-of-2 requests.  Note that the old
889      * (FreeBSD-4.x) malloc code aligned all requests, but the new slab
890      * allocator only guarentees same-size alignment for power-of-2 requests.
891      */
892     aligned_size = (sizeof(struct twe_request) + TWE_ALIGNMASK) &
893 		    ~TWE_ALIGNMASK;
894     tr = malloc(aligned_size, TWE_MALLOC_CLASS, M_INTWAIT|M_ZERO);
895     tr->tr_sc = sc;
896     if (bus_dmamap_create(sc->twe_buffer_dmat, 0, &tr->tr_cmdmap)) {
897 	twe_free_request(tr);
898 	return(NULL);
899     }
900     if (bus_dmamap_create(sc->twe_buffer_dmat, 0, &tr->tr_dmamap)) {
901 	bus_dmamap_destroy(sc->twe_buffer_dmat, tr->tr_cmdmap);
902 	twe_free_request(tr);
903 	return(NULL);
904     }
905     return(tr);
906 }
907 
908 /********************************************************************************
909  * Permanently discard a command buffer.
910  */
911 void
912 twe_free_request(struct twe_request *tr)
913 {
914     struct twe_softc	*sc = tr->tr_sc;
915 
916     debug_called(4);
917 
918     bus_dmamap_destroy(sc->twe_buffer_dmat, tr->tr_cmdmap);
919     bus_dmamap_destroy(sc->twe_buffer_dmat, tr->tr_dmamap);
920     free(tr, TWE_MALLOC_CLASS);
921 }
922 
923 /********************************************************************************
924  * Map/unmap (tr)'s command and data in the controller's addressable space.
925  *
926  * These routines ensure that the data which the controller is going to try to
927  * access is actually visible to the controller, in a machine-independant
928  * fashion.  Due to a hardware limitation, I/O buffers must be 512-byte aligned
929  * and we take care of that here as well.
930  */
931 static void
932 twe_fillin_sgl(TWE_SG_Entry *sgl, bus_dma_segment_t *segs, int nsegments, int max_sgl)
933 {
934     int i;
935 
936     for (i = 0; i < nsegments; i++) {
937 	sgl[i].address = segs[i].ds_addr;
938 	sgl[i].length = segs[i].ds_len;
939     }
940     for (; i < max_sgl; i++) {				/* XXX necessary? */
941 	sgl[i].address = 0;
942 	sgl[i].length = 0;
943     }
944 }
945 
946 static void
947 twe_setup_data_dmamap(void *arg, bus_dma_segment_t *segs, int nsegments, int error)
948 {
949     struct twe_request	*tr = (struct twe_request *)arg;
950     TWE_Command		*cmd = &tr->tr_command;
951 
952     debug_called(4);
953 
954     /* save base of first segment in command (applicable if there only one segment) */
955     tr->tr_dataphys = segs[0].ds_addr;
956 
957     /* correct command size for s/g list size */
958     tr->tr_command.generic.size += 2 * nsegments;
959 
960     /*
961      * Due to the fact that parameter and I/O commands have the scatter/gather list in
962      * different places, we need to determine which sort of command this actually is
963      * before we can populate it correctly.
964      */
965     switch(cmd->generic.opcode) {
966     case TWE_OP_GET_PARAM:
967     case TWE_OP_SET_PARAM:
968 	cmd->generic.sgl_offset = 2;
969 	twe_fillin_sgl(&cmd->param.sgl[0], segs, nsegments, TWE_MAX_SGL_LENGTH);
970 	break;
971     case TWE_OP_READ:
972     case TWE_OP_WRITE:
973 	cmd->generic.sgl_offset = 3;
974 	twe_fillin_sgl(&cmd->io.sgl[0], segs, nsegments, TWE_MAX_SGL_LENGTH);
975 	break;
976     case TWE_OP_ATA_PASSTHROUGH:
977 	cmd->generic.sgl_offset = 5;
978 	twe_fillin_sgl(&cmd->ata.sgl[0], segs, nsegments, TWE_MAX_ATA_SGL_LENGTH);
979 	break;
980     default:
981 	/*
982 	 * Fall back to what the linux driver does.
983 	 * Do this because the API may send an opcode
984 	 * the driver knows nothing about and this will
985 	 * at least stop PCIABRT's from hosing us.
986 	 */
987 	switch (cmd->generic.sgl_offset) {
988 	case 2:
989 	    twe_fillin_sgl(&cmd->param.sgl[0], segs, nsegments, TWE_MAX_SGL_LENGTH);
990 	    break;
991 	case 3:
992 	    twe_fillin_sgl(&cmd->io.sgl[0], segs, nsegments, TWE_MAX_SGL_LENGTH);
993 	    break;
994 	case 5:
995 	    twe_fillin_sgl(&cmd->ata.sgl[0], segs, nsegments, TWE_MAX_ATA_SGL_LENGTH);
996 	    break;
997 	}
998     }
999 }
1000 
1001 static void
1002 twe_setup_request_dmamap(void *arg, bus_dma_segment_t *segs, int nsegments, int error)
1003 {
1004     struct twe_request	*tr = (struct twe_request *)arg;
1005 
1006     debug_called(4);
1007 
1008     /* command can't cross a page boundary */
1009     tr->tr_cmdphys = segs[0].ds_addr;
1010 }
1011 
1012 void
1013 twe_map_request(struct twe_request *tr)
1014 {
1015     struct twe_softc	*sc = tr->tr_sc;
1016 
1017     debug_called(4);
1018 
1019 
1020     /*
1021      * Map the command into bus space.
1022      */
1023     bus_dmamap_load(sc->twe_buffer_dmat, tr->tr_cmdmap, &tr->tr_command, sizeof(tr->tr_command),
1024 		    twe_setup_request_dmamap, tr, 0);
1025     bus_dmamap_sync(sc->twe_buffer_dmat, tr->tr_cmdmap, BUS_DMASYNC_PREWRITE);
1026 
1027     /*
1028      * If the command involves data, map that too.
1029      */
1030     if (tr->tr_data != NULL) {
1031 
1032 	/*
1033 	 * Data must be 512-byte aligned; allocate a fixup buffer if it's not.
1034 	 */
1035 	if (((vm_offset_t)tr->tr_data % TWE_ALIGNMENT) != 0) {
1036 	    int aligned_size;
1037 
1038 	    aligned_size = (tr->tr_length + TWE_ALIGNMASK) & ~TWE_ALIGNMASK;
1039 	    /* save pointer to 'real' data */
1040 	    tr->tr_realdata = tr->tr_data;
1041 	    tr->tr_flags |= TWE_CMD_ALIGNBUF;
1042 	    tr->tr_data = malloc(aligned_size, TWE_MALLOC_CLASS, M_INTWAIT);
1043 	}
1044 
1045 	/*
1046 	 * Map the data buffer into bus space and build the s/g list.
1047 	 */
1048 	bus_dmamap_load(sc->twe_buffer_dmat, tr->tr_dmamap, tr->tr_data, tr->tr_length,
1049 			twe_setup_data_dmamap, tr, 0);
1050 	if (tr->tr_flags & TWE_CMD_DATAIN)
1051 	    bus_dmamap_sync(sc->twe_buffer_dmat, tr->tr_dmamap, BUS_DMASYNC_PREREAD);
1052 	if (tr->tr_flags & TWE_CMD_DATAOUT) {
1053 	    /* if we're using an alignment buffer, and we're writing data, copy the real data out */
1054 	    if (tr->tr_flags & TWE_CMD_ALIGNBUF)
1055 		bcopy(tr->tr_realdata, tr->tr_data, tr->tr_length);
1056 	    bus_dmamap_sync(sc->twe_buffer_dmat, tr->tr_dmamap, BUS_DMASYNC_PREWRITE);
1057 	}
1058     }
1059 }
1060 
1061 void
1062 twe_unmap_request(struct twe_request *tr)
1063 {
1064     struct twe_softc	*sc = tr->tr_sc;
1065 
1066     debug_called(4);
1067 
1068     /*
1069      * Unmap the command from bus space.
1070      */
1071     bus_dmamap_sync(sc->twe_buffer_dmat, tr->tr_cmdmap, BUS_DMASYNC_POSTWRITE);
1072     bus_dmamap_unload(sc->twe_buffer_dmat, tr->tr_cmdmap);
1073 
1074     /*
1075      * If the command involved data, unmap that too.
1076      */
1077     if (tr->tr_data != NULL) {
1078 
1079 	if (tr->tr_flags & TWE_CMD_DATAIN) {
1080 	    bus_dmamap_sync(sc->twe_buffer_dmat, tr->tr_dmamap, BUS_DMASYNC_POSTREAD);
1081 	    /* if we're using an alignment buffer, and we're reading data, copy the real data in */
1082 	    if (tr->tr_flags & TWE_CMD_ALIGNBUF)
1083 		bcopy(tr->tr_data, tr->tr_realdata, tr->tr_length);
1084 	}
1085 	if (tr->tr_flags & TWE_CMD_DATAOUT)
1086 	    bus_dmamap_sync(sc->twe_buffer_dmat, tr->tr_dmamap, BUS_DMASYNC_POSTWRITE);
1087 
1088 	bus_dmamap_unload(sc->twe_buffer_dmat, tr->tr_dmamap);
1089     }
1090 
1091     /* free alignment buffer if it was used */
1092     if (tr->tr_flags & TWE_CMD_ALIGNBUF) {
1093 	free(tr->tr_data, TWE_MALLOC_CLASS);
1094 	tr->tr_data = tr->tr_realdata;		/* restore 'real' data pointer */
1095     }
1096 }
1097 
1098 #ifdef TWE_DEBUG
1099 /********************************************************************************
1100  * Print current controller status, call from DDB.
1101  */
1102 void
1103 twe_report(void)
1104 {
1105     struct twe_softc	*sc;
1106     int			i, s;
1107 
1108     s = splbio();
1109     for (i = 0; (sc = devclass_get_softc(twe_devclass, i)) != NULL; i++)
1110 	twe_print_controller(sc);
1111     printf("twed: total bio count in %u  out %u\n", twed_bio_in, twed_bio_out);
1112     splx(s);
1113 }
1114 #endif
1115