xref: /freebsd-13-stable/sys/dev/mly/mly.c (revision f8167e0404dab9ffeaca95853dd237ab7c587f82)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright (c) 2000, 2001 Michael Smith
5  * Copyright (c) 2000 BSDi
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  */
29 
30 #include <sys/param.h>
31 #include <sys/systm.h>
32 #include <sys/malloc.h>
33 #include <sys/kernel.h>
34 #include <sys/bus.h>
35 #include <sys/conf.h>
36 #include <sys/ctype.h>
37 #include <sys/ioccom.h>
38 #include <sys/stat.h>
39 
40 #include <machine/bus.h>
41 #include <machine/resource.h>
42 #include <sys/rman.h>
43 
44 #include <cam/cam.h>
45 #include <cam/cam_ccb.h>
46 #include <cam/cam_periph.h>
47 #include <cam/cam_sim.h>
48 #include <cam/cam_xpt_sim.h>
49 #include <cam/scsi/scsi_all.h>
50 #include <cam/scsi/scsi_message.h>
51 
52 #include <dev/pci/pcireg.h>
53 #include <dev/pci/pcivar.h>
54 
55 #include <dev/mly/mlyreg.h>
56 #include <dev/mly/mlyio.h>
57 #include <dev/mly/mlyvar.h>
58 #include <dev/mly/mly_tables.h>
59 
60 static int	mly_probe(device_t dev);
61 static int	mly_attach(device_t dev);
62 static int	mly_pci_attach(struct mly_softc *sc);
63 static int	mly_detach(device_t dev);
64 static int	mly_shutdown(device_t dev);
65 static void	mly_intr(void *arg);
66 
67 static int	mly_sg_map(struct mly_softc *sc);
68 static void	mly_sg_map_helper(void *arg, bus_dma_segment_t *segs, int nseg, int error);
69 static int	mly_mmbox_map(struct mly_softc *sc);
70 static void	mly_mmbox_map_helper(void *arg, bus_dma_segment_t *segs, int nseg, int error);
71 static void	mly_free(struct mly_softc *sc);
72 
73 static int	mly_get_controllerinfo(struct mly_softc *sc);
74 static void	mly_scan_devices(struct mly_softc *sc);
75 static void	mly_rescan_btl(struct mly_softc *sc, int bus, int target);
76 static void	mly_complete_rescan(struct mly_command *mc);
77 static int	mly_get_eventstatus(struct mly_softc *sc);
78 static int	mly_enable_mmbox(struct mly_softc *sc);
79 static int	mly_flush(struct mly_softc *sc);
80 static int	mly_ioctl(struct mly_softc *sc, struct mly_command_ioctl *ioctl, void **data,
81 			  size_t datasize, u_int8_t *status, void *sense_buffer, size_t *sense_length);
82 static void	mly_check_event(struct mly_softc *sc);
83 static void	mly_fetch_event(struct mly_softc *sc);
84 static void	mly_complete_event(struct mly_command *mc);
85 static void	mly_process_event(struct mly_softc *sc, struct mly_event *me);
86 static void	mly_periodic(void *data);
87 
88 static int	mly_immediate_command(struct mly_command *mc);
89 static int	mly_start(struct mly_command *mc);
90 static void	mly_done(struct mly_softc *sc);
91 static void	mly_complete(struct mly_softc *sc);
92 static void	mly_complete_handler(void *context, int pending);
93 
94 static int	mly_alloc_command(struct mly_softc *sc, struct mly_command **mcp);
95 static void	mly_release_command(struct mly_command *mc);
96 static void	mly_alloc_commands_map(void *arg, bus_dma_segment_t *segs, int nseg, int error);
97 static int	mly_alloc_commands(struct mly_softc *sc);
98 static void	mly_release_commands(struct mly_softc *sc);
99 static void	mly_map_command(struct mly_command *mc);
100 static void	mly_unmap_command(struct mly_command *mc);
101 
102 static int	mly_cam_attach(struct mly_softc *sc);
103 static void	mly_cam_detach(struct mly_softc *sc);
104 static void	mly_cam_rescan_btl(struct mly_softc *sc, int bus, int target);
105 static void	mly_cam_action(struct cam_sim *sim, union ccb *ccb);
106 static int	mly_cam_action_io(struct cam_sim *sim, struct ccb_scsiio *csio);
107 static void	mly_cam_poll(struct cam_sim *sim);
108 static void	mly_cam_complete(struct mly_command *mc);
109 static struct cam_periph *mly_find_periph(struct mly_softc *sc, int bus, int target);
110 static int	mly_name_device(struct mly_softc *sc, int bus, int target);
111 
112 static int	mly_fwhandshake(struct mly_softc *sc);
113 
114 static void	mly_describe_controller(struct mly_softc *sc);
115 #ifdef MLY_DEBUG
116 static void	mly_printstate(struct mly_softc *sc);
117 static void	mly_print_command(struct mly_command *mc);
118 static void	mly_print_packet(struct mly_command *mc);
119 static void	mly_panic(struct mly_softc *sc, char *reason);
120 static void	mly_timeout(void *arg);
121 #endif
122 void		mly_print_controller(int controller);
123 
124 static d_open_t		mly_user_open;
125 static d_close_t	mly_user_close;
126 static d_ioctl_t	mly_user_ioctl;
127 static int	mly_user_command(struct mly_softc *sc, struct mly_user_command *uc);
128 static int	mly_user_health(struct mly_softc *sc, struct mly_user_health *uh);
129 
130 #define MLY_CMD_TIMEOUT		20
131 
132 static device_method_t mly_methods[] = {
133     /* Device interface */
134     DEVMETHOD(device_probe,	mly_probe),
135     DEVMETHOD(device_attach,	mly_attach),
136     DEVMETHOD(device_detach,	mly_detach),
137     DEVMETHOD(device_shutdown,	mly_shutdown),
138     { 0, 0 }
139 };
140 
141 static driver_t mly_pci_driver = {
142 	"mly",
143 	mly_methods,
144 	sizeof(struct mly_softc)
145 };
146 
147 static devclass_t	mly_devclass;
148 DRIVER_MODULE(mly, pci, mly_pci_driver, mly_devclass, 0, 0);
149 MODULE_DEPEND(mly, pci, 1, 1, 1);
150 MODULE_DEPEND(mly, cam, 1, 1, 1);
151 
152 static struct cdevsw mly_cdevsw = {
153 	.d_version =	D_VERSION,
154 	.d_open =	mly_user_open,
155 	.d_close =	mly_user_close,
156 	.d_ioctl =	mly_user_ioctl,
157 	.d_name =	"mly",
158 };
159 
160 /********************************************************************************
161  ********************************************************************************
162                                                                  Device Interface
163  ********************************************************************************
164  ********************************************************************************/
165 
166 static struct mly_ident
167 {
168     u_int16_t		vendor;
169     u_int16_t		device;
170     u_int16_t		subvendor;
171     u_int16_t		subdevice;
172     int			hwif;
173     char		*desc;
174 } mly_identifiers[] = {
175     {0x1069, 0xba56, 0x1069, 0x0040, MLY_HWIF_STRONGARM, "Mylex eXtremeRAID 2000"},
176     {0x1069, 0xba56, 0x1069, 0x0030, MLY_HWIF_STRONGARM, "Mylex eXtremeRAID 3000"},
177     {0x1069, 0x0050, 0x1069, 0x0050, MLY_HWIF_I960RX,    "Mylex AcceleRAID 352"},
178     {0x1069, 0x0050, 0x1069, 0x0052, MLY_HWIF_I960RX,    "Mylex AcceleRAID 170"},
179     {0x1069, 0x0050, 0x1069, 0x0054, MLY_HWIF_I960RX,    "Mylex AcceleRAID 160"},
180     {0, 0, 0, 0, 0, 0}
181 };
182 
183 /********************************************************************************
184  * Compare the provided PCI device with the list we support.
185  */
186 static int
mly_probe(device_t dev)187 mly_probe(device_t dev)
188 {
189     struct mly_ident	*m;
190 
191     debug_called(1);
192 
193     for (m = mly_identifiers; m->vendor != 0; m++) {
194 	if ((m->vendor == pci_get_vendor(dev)) &&
195 	    (m->device == pci_get_device(dev)) &&
196 	    ((m->subvendor == 0) || ((m->subvendor == pci_get_subvendor(dev)) &&
197 				     (m->subdevice == pci_get_subdevice(dev))))) {
198 
199 	    device_set_desc(dev, m->desc);
200 	    return(BUS_PROBE_DEFAULT);	/* allow room to be overridden */
201 	}
202     }
203     return(ENXIO);
204 }
205 
206 /********************************************************************************
207  * Initialise the controller and softc
208  */
209 static int
mly_attach(device_t dev)210 mly_attach(device_t dev)
211 {
212     struct mly_softc	*sc = device_get_softc(dev);
213     int			error;
214 
215     debug_called(1);
216 
217     sc->mly_dev = dev;
218     mtx_init(&sc->mly_lock, "mly", NULL, MTX_DEF);
219     callout_init_mtx(&sc->mly_periodic, &sc->mly_lock, 0);
220 
221 #ifdef MLY_DEBUG
222     callout_init_mtx(&sc->mly_timeout, &sc->mly_lock, 0);
223     if (device_get_unit(sc->mly_dev) == 0)
224 	mly_softc0 = sc;
225 #endif
226 
227     /*
228      * Do PCI-specific initialisation.
229      */
230     if ((error = mly_pci_attach(sc)) != 0)
231 	goto out;
232 
233     /*
234      * Initialise per-controller queues.
235      */
236     mly_initq_free(sc);
237     mly_initq_busy(sc);
238     mly_initq_complete(sc);
239 
240     /*
241      * Initialise command-completion task.
242      */
243     TASK_INIT(&sc->mly_task_complete, 0, mly_complete_handler, sc);
244 
245     /* disable interrupts before we start talking to the controller */
246     MLY_MASK_INTERRUPTS(sc);
247 
248     /*
249      * Wait for the controller to come ready, handshake with the firmware if required.
250      * This is typically only necessary on platforms where the controller BIOS does not
251      * run.
252      */
253     if ((error = mly_fwhandshake(sc)))
254 	goto out;
255 
256     /*
257      * Allocate initial command buffers.
258      */
259     if ((error = mly_alloc_commands(sc)))
260 	goto out;
261 
262     /*
263      * Obtain controller feature information
264      */
265     MLY_LOCK(sc);
266     error = mly_get_controllerinfo(sc);
267     MLY_UNLOCK(sc);
268     if (error)
269 	goto out;
270 
271     /*
272      * Reallocate command buffers now we know how many we want.
273      */
274     mly_release_commands(sc);
275     if ((error = mly_alloc_commands(sc)))
276 	goto out;
277 
278     /*
279      * Get the current event counter for health purposes, populate the initial
280      * health status buffer.
281      */
282     MLY_LOCK(sc);
283     error = mly_get_eventstatus(sc);
284 
285     /*
286      * Enable memory-mailbox mode.
287      */
288     if (error == 0)
289 	error = mly_enable_mmbox(sc);
290     MLY_UNLOCK(sc);
291     if (error)
292 	goto out;
293 
294     /*
295      * Attach to CAM.
296      */
297     if ((error = mly_cam_attach(sc)))
298 	goto out;
299 
300     /*
301      * Print a little information about the controller
302      */
303     mly_describe_controller(sc);
304 
305     /*
306      * Mark all attached devices for rescan.
307      */
308     MLY_LOCK(sc);
309     mly_scan_devices(sc);
310 
311     /*
312      * Instigate the first status poll immediately.  Rescan completions won't
313      * happen until interrupts are enabled, which should still be before
314      * the SCSI subsystem gets to us, courtesy of the "SCSI settling delay".
315      */
316     mly_periodic((void *)sc);
317     MLY_UNLOCK(sc);
318 
319     /*
320      * Create the control device.
321      */
322     sc->mly_dev_t = make_dev(&mly_cdevsw, 0, UID_ROOT, GID_OPERATOR,
323 			     S_IRUSR | S_IWUSR, "mly%d", device_get_unit(sc->mly_dev));
324     sc->mly_dev_t->si_drv1 = sc;
325 
326     /* enable interrupts now */
327     MLY_UNMASK_INTERRUPTS(sc);
328 
329 #ifdef MLY_DEBUG
330     callout_reset(&sc->mly_timeout, MLY_CMD_TIMEOUT * hz, mly_timeout, sc);
331 #endif
332 
333  out:
334     if (error != 0)
335 	mly_free(sc);
336     else
337 	gone_in_dev(dev, 14, "mly(4) removed");
338     return(error);
339 }
340 
341 /********************************************************************************
342  * Perform PCI-specific initialisation.
343  */
344 static int
mly_pci_attach(struct mly_softc * sc)345 mly_pci_attach(struct mly_softc *sc)
346 {
347     int			i, error;
348 
349     debug_called(1);
350 
351     /* assume failure is 'not configured' */
352     error = ENXIO;
353 
354     /*
355      * Verify that the adapter is correctly set up in PCI space.
356      */
357     pci_enable_busmaster(sc->mly_dev);
358 
359     /*
360      * Allocate the PCI register window.
361      */
362     sc->mly_regs_rid = PCIR_BAR(0);	/* first base address register */
363     if ((sc->mly_regs_resource = bus_alloc_resource_any(sc->mly_dev,
364 	    SYS_RES_MEMORY, &sc->mly_regs_rid, RF_ACTIVE)) == NULL) {
365 	mly_printf(sc, "can't allocate register window\n");
366 	goto fail;
367     }
368 
369     /*
370      * Allocate and connect our interrupt.
371      */
372     sc->mly_irq_rid = 0;
373     if ((sc->mly_irq = bus_alloc_resource_any(sc->mly_dev, SYS_RES_IRQ,
374 		    &sc->mly_irq_rid, RF_SHAREABLE | RF_ACTIVE)) == NULL) {
375 	mly_printf(sc, "can't allocate interrupt\n");
376 	goto fail;
377     }
378     if (bus_setup_intr(sc->mly_dev, sc->mly_irq, INTR_TYPE_CAM | INTR_ENTROPY | INTR_MPSAFE, NULL, mly_intr, sc, &sc->mly_intr)) {
379 	mly_printf(sc, "can't set up interrupt\n");
380 	goto fail;
381     }
382 
383     /* assume failure is 'out of memory' */
384     error = ENOMEM;
385 
386     /*
387      * Allocate the parent bus DMA tag appropriate for our PCI interface.
388      *
389      * Note that all of these controllers are 64-bit capable.
390      */
391     if (bus_dma_tag_create(bus_get_dma_tag(sc->mly_dev),/* PCI parent */
392 			   1, 0, 			/* alignment, boundary */
393 			   BUS_SPACE_MAXADDR_32BIT,	/* lowaddr */
394 			   BUS_SPACE_MAXADDR, 		/* highaddr */
395 			   NULL, NULL, 			/* filter, filterarg */
396 			   BUS_SPACE_MAXSIZE_32BIT,	/* maxsize */
397 			   BUS_SPACE_UNRESTRICTED,	/* nsegments */
398 			   BUS_SPACE_MAXSIZE_32BIT,	/* maxsegsize */
399 			   BUS_DMA_ALLOCNOW,		/* flags */
400 			   NULL,			/* lockfunc */
401 			   NULL,			/* lockarg */
402 			   &sc->mly_parent_dmat)) {
403 	mly_printf(sc, "can't allocate parent DMA tag\n");
404 	goto fail;
405     }
406 
407     /*
408      * Create DMA tag for mapping buffers into controller-addressable space.
409      */
410     if (bus_dma_tag_create(sc->mly_parent_dmat, 	/* parent */
411 			   1, 0, 			/* alignment, boundary */
412 			   BUS_SPACE_MAXADDR,		/* lowaddr */
413 			   BUS_SPACE_MAXADDR, 		/* highaddr */
414 			   NULL, NULL, 			/* filter, filterarg */
415 			   DFLTPHYS,			/* maxsize */
416 			   MLY_MAX_SGENTRIES,		/* nsegments */
417 			   BUS_SPACE_MAXSIZE_32BIT,	/* maxsegsize */
418 			   0,				/* flags */
419 			   busdma_lock_mutex,		/* lockfunc */
420 			   &sc->mly_lock,		/* lockarg */
421 			   &sc->mly_buffer_dmat)) {
422 	mly_printf(sc, "can't allocate buffer DMA tag\n");
423 	goto fail;
424     }
425 
426     /*
427      * Initialise the DMA tag for command packets.
428      */
429     if (bus_dma_tag_create(sc->mly_parent_dmat,		/* parent */
430 			   1, 0, 			/* alignment, boundary */
431 			   BUS_SPACE_MAXADDR,		/* lowaddr */
432 			   BUS_SPACE_MAXADDR, 		/* highaddr */
433 			   NULL, NULL, 			/* filter, filterarg */
434 			   sizeof(union mly_command_packet) * MLY_MAX_COMMANDS, 1,	/* maxsize, nsegments */
435 			   BUS_SPACE_MAXSIZE_32BIT,	/* maxsegsize */
436 			   BUS_DMA_ALLOCNOW,		/* flags */
437 			   NULL, NULL,			/* lockfunc, lockarg */
438 			   &sc->mly_packet_dmat)) {
439 	mly_printf(sc, "can't allocate command packet DMA tag\n");
440 	goto fail;
441     }
442 
443     /*
444      * Detect the hardware interface version
445      */
446     for (i = 0; mly_identifiers[i].vendor != 0; i++) {
447 	if ((mly_identifiers[i].vendor == pci_get_vendor(sc->mly_dev)) &&
448 	    (mly_identifiers[i].device == pci_get_device(sc->mly_dev))) {
449 	    sc->mly_hwif = mly_identifiers[i].hwif;
450 	    switch(sc->mly_hwif) {
451 	    case MLY_HWIF_I960RX:
452 		debug(1, "set hardware up for i960RX");
453 		sc->mly_doorbell_true = 0x00;
454 		sc->mly_command_mailbox =  MLY_I960RX_COMMAND_MAILBOX;
455 		sc->mly_status_mailbox =   MLY_I960RX_STATUS_MAILBOX;
456 		sc->mly_idbr =             MLY_I960RX_IDBR;
457 		sc->mly_odbr =             MLY_I960RX_ODBR;
458 		sc->mly_error_status =     MLY_I960RX_ERROR_STATUS;
459 		sc->mly_interrupt_status = MLY_I960RX_INTERRUPT_STATUS;
460 		sc->mly_interrupt_mask =   MLY_I960RX_INTERRUPT_MASK;
461 		break;
462 	    case MLY_HWIF_STRONGARM:
463 		debug(1, "set hardware up for StrongARM");
464 		sc->mly_doorbell_true = 0xff;		/* doorbell 'true' is 0 */
465 		sc->mly_command_mailbox =  MLY_STRONGARM_COMMAND_MAILBOX;
466 		sc->mly_status_mailbox =   MLY_STRONGARM_STATUS_MAILBOX;
467 		sc->mly_idbr =             MLY_STRONGARM_IDBR;
468 		sc->mly_odbr =             MLY_STRONGARM_ODBR;
469 		sc->mly_error_status =     MLY_STRONGARM_ERROR_STATUS;
470 		sc->mly_interrupt_status = MLY_STRONGARM_INTERRUPT_STATUS;
471 		sc->mly_interrupt_mask =   MLY_STRONGARM_INTERRUPT_MASK;
472 		break;
473 	    }
474 	    break;
475 	}
476     }
477 
478     /*
479      * Create the scatter/gather mappings.
480      */
481     if ((error = mly_sg_map(sc)))
482 	goto fail;
483 
484     /*
485      * Allocate and map the memory mailbox
486      */
487     if ((error = mly_mmbox_map(sc)))
488 	goto fail;
489 
490     error = 0;
491 
492 fail:
493     return(error);
494 }
495 
496 /********************************************************************************
497  * Shut the controller down and detach all our resources.
498  */
499 static int
mly_detach(device_t dev)500 mly_detach(device_t dev)
501 {
502     int			error;
503 
504     if ((error = mly_shutdown(dev)) != 0)
505 	return(error);
506 
507     mly_free(device_get_softc(dev));
508     return(0);
509 }
510 
511 /********************************************************************************
512  * Bring the controller to a state where it can be safely left alone.
513  *
514  * Note that it should not be necessary to wait for any outstanding commands,
515  * as they should be completed prior to calling here.
516  *
517  * XXX this applies for I/O, but not status polls; we should beware of
518  *     the case where a status command is running while we detach.
519  */
520 static int
mly_shutdown(device_t dev)521 mly_shutdown(device_t dev)
522 {
523     struct mly_softc	*sc = device_get_softc(dev);
524 
525     debug_called(1);
526 
527     MLY_LOCK(sc);
528     if (sc->mly_state & MLY_STATE_OPEN) {
529 	MLY_UNLOCK(sc);
530 	return(EBUSY);
531     }
532 
533     /* kill the periodic event */
534     callout_stop(&sc->mly_periodic);
535 #ifdef MLY_DEBUG
536     callout_stop(&sc->mly_timeout);
537 #endif
538 
539     /* flush controller */
540     mly_printf(sc, "flushing cache...");
541     printf("%s\n", mly_flush(sc) ? "failed" : "done");
542 
543     MLY_MASK_INTERRUPTS(sc);
544     MLY_UNLOCK(sc);
545 
546     return(0);
547 }
548 
549 /*******************************************************************************
550  * Take an interrupt, or be poked by other code to look for interrupt-worthy
551  * status.
552  */
553 static void
mly_intr(void * arg)554 mly_intr(void *arg)
555 {
556     struct mly_softc	*sc = (struct mly_softc *)arg;
557 
558     debug_called(2);
559 
560     MLY_LOCK(sc);
561     mly_done(sc);
562     MLY_UNLOCK(sc);
563 };
564 
565 /********************************************************************************
566  ********************************************************************************
567                                                 Bus-dependant Resource Management
568  ********************************************************************************
569  ********************************************************************************/
570 
571 /********************************************************************************
572  * Allocate memory for the scatter/gather tables
573  */
574 static int
mly_sg_map(struct mly_softc * sc)575 mly_sg_map(struct mly_softc *sc)
576 {
577     size_t	segsize;
578 
579     debug_called(1);
580 
581     /*
582      * Create a single tag describing a region large enough to hold all of
583      * the s/g lists we will need.
584      */
585     segsize = sizeof(struct mly_sg_entry) * MLY_MAX_COMMANDS *MLY_MAX_SGENTRIES;
586     if (bus_dma_tag_create(sc->mly_parent_dmat,		/* parent */
587 			   1, 0, 			/* alignment,boundary */
588 			   BUS_SPACE_MAXADDR,		/* lowaddr */
589 			   BUS_SPACE_MAXADDR, 		/* highaddr */
590 			   NULL, NULL, 			/* filter, filterarg */
591 			   segsize, 1,			/* maxsize, nsegments */
592 			   BUS_SPACE_MAXSIZE_32BIT,	/* maxsegsize */
593 			   BUS_DMA_ALLOCNOW,		/* flags */
594 			   NULL, NULL,			/* lockfunc, lockarg */
595 			   &sc->mly_sg_dmat)) {
596 	mly_printf(sc, "can't allocate scatter/gather DMA tag\n");
597 	return(ENOMEM);
598     }
599 
600     /*
601      * Allocate enough s/g maps for all commands and permanently map them into
602      * controller-visible space.
603      *
604      * XXX this assumes we can get enough space for all the s/g maps in one
605      * contiguous slab.
606      */
607     if (bus_dmamem_alloc(sc->mly_sg_dmat, (void **)&sc->mly_sg_table,
608 			 BUS_DMA_NOWAIT, &sc->mly_sg_dmamap)) {
609 	mly_printf(sc, "can't allocate s/g table\n");
610 	return(ENOMEM);
611     }
612     if (bus_dmamap_load(sc->mly_sg_dmat, sc->mly_sg_dmamap, sc->mly_sg_table,
613 			segsize, mly_sg_map_helper, sc, BUS_DMA_NOWAIT) != 0)
614 	return (ENOMEM);
615     return(0);
616 }
617 
618 /********************************************************************************
619  * Save the physical address of the base of the s/g table.
620  */
621 static void
mly_sg_map_helper(void * arg,bus_dma_segment_t * segs,int nseg,int error)622 mly_sg_map_helper(void *arg, bus_dma_segment_t *segs, int nseg, int error)
623 {
624     struct mly_softc	*sc = (struct mly_softc *)arg;
625 
626     debug_called(1);
627 
628     /* save base of s/g table's address in bus space */
629     sc->mly_sg_busaddr = segs->ds_addr;
630 }
631 
632 /********************************************************************************
633  * Allocate memory for the memory-mailbox interface
634  */
635 static int
mly_mmbox_map(struct mly_softc * sc)636 mly_mmbox_map(struct mly_softc *sc)
637 {
638 
639     /*
640      * Create a DMA tag for a single contiguous region large enough for the
641      * memory mailbox structure.
642      */
643     if (bus_dma_tag_create(sc->mly_parent_dmat,		/* parent */
644 			   1, 0, 			/* alignment,boundary */
645 			   BUS_SPACE_MAXADDR,		/* lowaddr */
646 			   BUS_SPACE_MAXADDR, 		/* highaddr */
647 			   NULL, NULL, 			/* filter, filterarg */
648 			   sizeof(struct mly_mmbox), 1,	/* maxsize, nsegments */
649 			   BUS_SPACE_MAXSIZE_32BIT,	/* maxsegsize */
650 			   BUS_DMA_ALLOCNOW,		/* flags */
651 			   NULL, NULL,			/* lockfunc, lockarg */
652 			   &sc->mly_mmbox_dmat)) {
653 	mly_printf(sc, "can't allocate memory mailbox DMA tag\n");
654 	return(ENOMEM);
655     }
656 
657     /*
658      * Allocate the buffer
659      */
660     if (bus_dmamem_alloc(sc->mly_mmbox_dmat, (void **)&sc->mly_mmbox, BUS_DMA_NOWAIT, &sc->mly_mmbox_dmamap)) {
661 	mly_printf(sc, "can't allocate memory mailbox\n");
662 	return(ENOMEM);
663     }
664     if (bus_dmamap_load(sc->mly_mmbox_dmat, sc->mly_mmbox_dmamap, sc->mly_mmbox,
665 			sizeof(struct mly_mmbox), mly_mmbox_map_helper, sc,
666 			BUS_DMA_NOWAIT) != 0)
667 	return (ENOMEM);
668     bzero(sc->mly_mmbox, sizeof(*sc->mly_mmbox));
669     return(0);
670 
671 }
672 
673 /********************************************************************************
674  * Save the physical address of the memory mailbox
675  */
676 static void
mly_mmbox_map_helper(void * arg,bus_dma_segment_t * segs,int nseg,int error)677 mly_mmbox_map_helper(void *arg, bus_dma_segment_t *segs, int nseg, int error)
678 {
679     struct mly_softc	*sc = (struct mly_softc *)arg;
680 
681     debug_called(1);
682 
683     sc->mly_mmbox_busaddr = segs->ds_addr;
684 }
685 
686 /********************************************************************************
687  * Free all of the resources associated with (sc)
688  *
689  * Should not be called if the controller is active.
690  */
691 static void
mly_free(struct mly_softc * sc)692 mly_free(struct mly_softc *sc)
693 {
694 
695     debug_called(1);
696 
697     /* Remove the management device */
698     destroy_dev(sc->mly_dev_t);
699 
700     if (sc->mly_intr)
701 	bus_teardown_intr(sc->mly_dev, sc->mly_irq, sc->mly_intr);
702     callout_drain(&sc->mly_periodic);
703 #ifdef MLY_DEBUG
704     callout_drain(&sc->mly_timeout);
705 #endif
706 
707     /* detach from CAM */
708     mly_cam_detach(sc);
709 
710     /* release command memory */
711     mly_release_commands(sc);
712 
713     /* throw away the controllerinfo structure */
714     if (sc->mly_controllerinfo != NULL)
715 	free(sc->mly_controllerinfo, M_DEVBUF);
716 
717     /* throw away the controllerparam structure */
718     if (sc->mly_controllerparam != NULL)
719 	free(sc->mly_controllerparam, M_DEVBUF);
720 
721     /* destroy data-transfer DMA tag */
722     if (sc->mly_buffer_dmat)
723 	bus_dma_tag_destroy(sc->mly_buffer_dmat);
724 
725     /* free and destroy DMA memory and tag for s/g lists */
726     if (sc->mly_sg_table) {
727 	bus_dmamap_unload(sc->mly_sg_dmat, sc->mly_sg_dmamap);
728 	bus_dmamem_free(sc->mly_sg_dmat, sc->mly_sg_table, sc->mly_sg_dmamap);
729     }
730     if (sc->mly_sg_dmat)
731 	bus_dma_tag_destroy(sc->mly_sg_dmat);
732 
733     /* free and destroy DMA memory and tag for memory mailbox */
734     if (sc->mly_mmbox) {
735 	bus_dmamap_unload(sc->mly_mmbox_dmat, sc->mly_mmbox_dmamap);
736 	bus_dmamem_free(sc->mly_mmbox_dmat, sc->mly_mmbox, sc->mly_mmbox_dmamap);
737     }
738     if (sc->mly_mmbox_dmat)
739 	bus_dma_tag_destroy(sc->mly_mmbox_dmat);
740 
741     /* disconnect the interrupt handler */
742     if (sc->mly_irq != NULL)
743 	bus_release_resource(sc->mly_dev, SYS_RES_IRQ, sc->mly_irq_rid, sc->mly_irq);
744 
745     /* destroy the parent DMA tag */
746     if (sc->mly_parent_dmat)
747 	bus_dma_tag_destroy(sc->mly_parent_dmat);
748 
749     /* release the register window mapping */
750     if (sc->mly_regs_resource != NULL)
751 	bus_release_resource(sc->mly_dev, SYS_RES_MEMORY, sc->mly_regs_rid, sc->mly_regs_resource);
752 
753     mtx_destroy(&sc->mly_lock);
754 }
755 
756 /********************************************************************************
757  ********************************************************************************
758                                                                  Command Wrappers
759  ********************************************************************************
760  ********************************************************************************/
761 
762 /********************************************************************************
763  * Fill in the mly_controllerinfo and mly_controllerparam fields in the softc.
764  */
765 static int
mly_get_controllerinfo(struct mly_softc * sc)766 mly_get_controllerinfo(struct mly_softc *sc)
767 {
768     struct mly_command_ioctl	mci;
769     u_int8_t			status;
770     int				error;
771 
772     debug_called(1);
773 
774     if (sc->mly_controllerinfo != NULL)
775 	free(sc->mly_controllerinfo, M_DEVBUF);
776 
777     /* build the getcontrollerinfo ioctl and send it */
778     bzero(&mci, sizeof(mci));
779     sc->mly_controllerinfo = NULL;
780     mci.sub_ioctl = MDACIOCTL_GETCONTROLLERINFO;
781     if ((error = mly_ioctl(sc, &mci, (void **)&sc->mly_controllerinfo, sizeof(*sc->mly_controllerinfo),
782 			   &status, NULL, NULL)))
783 	return(error);
784     if (status != 0)
785 	return(EIO);
786 
787     if (sc->mly_controllerparam != NULL)
788 	free(sc->mly_controllerparam, M_DEVBUF);
789 
790     /* build the getcontrollerparameter ioctl and send it */
791     bzero(&mci, sizeof(mci));
792     sc->mly_controllerparam = NULL;
793     mci.sub_ioctl = MDACIOCTL_GETCONTROLLERPARAMETER;
794     if ((error = mly_ioctl(sc, &mci, (void **)&sc->mly_controllerparam, sizeof(*sc->mly_controllerparam),
795 			   &status, NULL, NULL)))
796 	return(error);
797     if (status != 0)
798 	return(EIO);
799 
800     return(0);
801 }
802 
803 /********************************************************************************
804  * Schedule all possible devices for a rescan.
805  *
806  */
807 static void
mly_scan_devices(struct mly_softc * sc)808 mly_scan_devices(struct mly_softc *sc)
809 {
810     int		bus, target;
811 
812     debug_called(1);
813 
814     /*
815      * Clear any previous BTL information.
816      */
817     bzero(&sc->mly_btl, sizeof(sc->mly_btl));
818 
819     /*
820      * Mark all devices as requiring a rescan, and let the next
821      * periodic scan collect them.
822      */
823     for (bus = 0; bus < sc->mly_cam_channels; bus++)
824 	if (MLY_BUS_IS_VALID(sc, bus))
825 	    for (target = 0; target < MLY_MAX_TARGETS; target++)
826 		sc->mly_btl[bus][target].mb_flags = MLY_BTL_RESCAN;
827 
828 }
829 
830 /********************************************************************************
831  * Rescan a device, possibly as a consequence of getting an event which suggests
832  * that it may have changed.
833  *
834  * If we suffer resource starvation, we can abandon the rescan as we'll be
835  * retried.
836  */
837 static void
mly_rescan_btl(struct mly_softc * sc,int bus,int target)838 mly_rescan_btl(struct mly_softc *sc, int bus, int target)
839 {
840     struct mly_command		*mc;
841     struct mly_command_ioctl	*mci;
842 
843     debug_called(1);
844 
845     /* check that this bus is valid */
846     if (!MLY_BUS_IS_VALID(sc, bus))
847 	return;
848 
849     /* get a command */
850     if (mly_alloc_command(sc, &mc))
851 	return;
852 
853     /* set up the data buffer */
854     if ((mc->mc_data = malloc(sizeof(union mly_devinfo), M_DEVBUF, M_NOWAIT | M_ZERO)) == NULL) {
855 	mly_release_command(mc);
856 	return;
857     }
858     mc->mc_flags |= MLY_CMD_DATAIN;
859     mc->mc_complete = mly_complete_rescan;
860 
861     /*
862      * Build the ioctl.
863      */
864     mci = (struct mly_command_ioctl *)&mc->mc_packet->ioctl;
865     mci->opcode = MDACMD_IOCTL;
866     mci->addr.phys.controller = 0;
867     mci->timeout.value = 30;
868     mci->timeout.scale = MLY_TIMEOUT_SECONDS;
869     if (MLY_BUS_IS_VIRTUAL(sc, bus)) {
870 	mc->mc_length = mci->data_size = sizeof(struct mly_ioctl_getlogdevinfovalid);
871 	mci->sub_ioctl = MDACIOCTL_GETLOGDEVINFOVALID;
872 	mci->addr.log.logdev = MLY_LOGDEV_ID(sc, bus, target);
873 	debug(1, "logical device %d", mci->addr.log.logdev);
874     } else {
875 	mc->mc_length = mci->data_size = sizeof(struct mly_ioctl_getphysdevinfovalid);
876 	mci->sub_ioctl = MDACIOCTL_GETPHYSDEVINFOVALID;
877 	mci->addr.phys.lun = 0;
878 	mci->addr.phys.target = target;
879 	mci->addr.phys.channel = bus;
880 	debug(1, "physical device %d:%d", mci->addr.phys.channel, mci->addr.phys.target);
881     }
882 
883     /*
884      * Dispatch the command.  If we successfully send the command, clear the rescan
885      * bit.
886      */
887     if (mly_start(mc) != 0) {
888 	mly_release_command(mc);
889     } else {
890 	sc->mly_btl[bus][target].mb_flags &= ~MLY_BTL_RESCAN;	/* success */
891     }
892 }
893 
894 /********************************************************************************
895  * Handle the completion of a rescan operation
896  */
897 static void
mly_complete_rescan(struct mly_command * mc)898 mly_complete_rescan(struct mly_command *mc)
899 {
900     struct mly_softc				*sc = mc->mc_sc;
901     struct mly_ioctl_getlogdevinfovalid		*ldi;
902     struct mly_ioctl_getphysdevinfovalid	*pdi;
903     struct mly_command_ioctl			*mci;
904     struct mly_btl				btl, *btlp;
905     int						bus, target, rescan;
906 
907     debug_called(1);
908 
909     /*
910      * Recover the bus and target from the command.  We need these even in
911      * the case where we don't have a useful response.
912      */
913     mci = (struct mly_command_ioctl *)&mc->mc_packet->ioctl;
914     if (mci->sub_ioctl == MDACIOCTL_GETLOGDEVINFOVALID) {
915 	bus = MLY_LOGDEV_BUS(sc, mci->addr.log.logdev);
916 	target = MLY_LOGDEV_TARGET(sc, mci->addr.log.logdev);
917     } else {
918 	bus = mci->addr.phys.channel;
919 	target = mci->addr.phys.target;
920     }
921     /* XXX validate bus/target? */
922 
923     /* the default result is 'no device' */
924     bzero(&btl, sizeof(btl));
925 
926     /* if the rescan completed OK, we have possibly-new BTL data */
927     if (mc->mc_status == 0) {
928 	if (mc->mc_length == sizeof(*ldi)) {
929 	    ldi = (struct mly_ioctl_getlogdevinfovalid *)mc->mc_data;
930 	    if ((MLY_LOGDEV_BUS(sc, ldi->logical_device_number) != bus) ||
931 		(MLY_LOGDEV_TARGET(sc, ldi->logical_device_number) != target)) {
932 		mly_printf(sc, "WARNING: BTL rescan for %d:%d returned data for %d:%d instead\n",
933 			   bus, target, MLY_LOGDEV_BUS(sc, ldi->logical_device_number),
934 			   MLY_LOGDEV_TARGET(sc, ldi->logical_device_number));
935 		/* XXX what can we do about this? */
936 	    }
937 	    btl.mb_flags = MLY_BTL_LOGICAL;
938 	    btl.mb_type = ldi->raid_level;
939 	    btl.mb_state = ldi->state;
940 	    debug(1, "BTL rescan for %d returns %s, %s", ldi->logical_device_number,
941 		  mly_describe_code(mly_table_device_type, ldi->raid_level),
942 		  mly_describe_code(mly_table_device_state, ldi->state));
943 	} else if (mc->mc_length == sizeof(*pdi)) {
944 	    pdi = (struct mly_ioctl_getphysdevinfovalid *)mc->mc_data;
945 	    if ((pdi->channel != bus) || (pdi->target != target)) {
946 		mly_printf(sc, "WARNING: BTL rescan for %d:%d returned data for %d:%d instead\n",
947 			   bus, target, pdi->channel, pdi->target);
948 		/* XXX what can we do about this? */
949 	    }
950 	    btl.mb_flags = MLY_BTL_PHYSICAL;
951 	    btl.mb_type = MLY_DEVICE_TYPE_PHYSICAL;
952 	    btl.mb_state = pdi->state;
953 	    btl.mb_speed = pdi->speed;
954 	    btl.mb_width = pdi->width;
955 	    if (pdi->state != MLY_DEVICE_STATE_UNCONFIGURED)
956 		sc->mly_btl[bus][target].mb_flags |= MLY_BTL_PROTECTED;
957 	    debug(1, "BTL rescan for %d:%d returns %s", bus, target,
958 		  mly_describe_code(mly_table_device_state, pdi->state));
959 	} else {
960 	    mly_printf(sc, "BTL rescan result invalid\n");
961 	}
962     }
963 
964     free(mc->mc_data, M_DEVBUF);
965     mly_release_command(mc);
966 
967     /*
968      * Decide whether we need to rescan the device.
969      */
970     rescan = 0;
971 
972     /* device type changes (usually between 'nothing' and 'something') */
973     btlp = &sc->mly_btl[bus][target];
974     if (btl.mb_flags != btlp->mb_flags) {
975 	debug(1, "flags changed, rescanning");
976 	rescan = 1;
977     }
978 
979     /* XXX other reasons? */
980 
981     /*
982      * Update BTL information.
983      */
984     *btlp = btl;
985 
986     /*
987      * Perform CAM rescan if required.
988      */
989     if (rescan)
990 	mly_cam_rescan_btl(sc, bus, target);
991 }
992 
993 /********************************************************************************
994  * Get the current health status and set the 'next event' counter to suit.
995  */
996 static int
mly_get_eventstatus(struct mly_softc * sc)997 mly_get_eventstatus(struct mly_softc *sc)
998 {
999     struct mly_command_ioctl	mci;
1000     struct mly_health_status	*mh;
1001     u_int8_t			status;
1002     int				error;
1003 
1004     /* build the gethealthstatus ioctl and send it */
1005     bzero(&mci, sizeof(mci));
1006     mh = NULL;
1007     mci.sub_ioctl = MDACIOCTL_GETHEALTHSTATUS;
1008 
1009     if ((error = mly_ioctl(sc, &mci, (void **)&mh, sizeof(*mh), &status, NULL, NULL)))
1010 	return(error);
1011     if (status != 0)
1012 	return(EIO);
1013 
1014     /* get the event counter */
1015     sc->mly_event_change = mh->change_counter;
1016     sc->mly_event_waiting = mh->next_event;
1017     sc->mly_event_counter = mh->next_event;
1018 
1019     /* save the health status into the memory mailbox */
1020     bcopy(mh, &sc->mly_mmbox->mmm_health.status, sizeof(*mh));
1021 
1022     debug(1, "initial change counter %d, event counter %d", mh->change_counter, mh->next_event);
1023 
1024     free(mh, M_DEVBUF);
1025     return(0);
1026 }
1027 
1028 /********************************************************************************
1029  * Enable the memory mailbox mode.
1030  */
1031 static int
mly_enable_mmbox(struct mly_softc * sc)1032 mly_enable_mmbox(struct mly_softc *sc)
1033 {
1034     struct mly_command_ioctl	mci;
1035     u_int8_t			*sp, status;
1036     int				error;
1037 
1038     debug_called(1);
1039 
1040     /* build the ioctl and send it */
1041     bzero(&mci, sizeof(mci));
1042     mci.sub_ioctl = MDACIOCTL_SETMEMORYMAILBOX;
1043     /* set buffer addresses */
1044     mci.param.setmemorymailbox.command_mailbox_physaddr =
1045 	sc->mly_mmbox_busaddr + offsetof(struct mly_mmbox, mmm_command);
1046     mci.param.setmemorymailbox.status_mailbox_physaddr =
1047 	sc->mly_mmbox_busaddr + offsetof(struct mly_mmbox, mmm_status);
1048     mci.param.setmemorymailbox.health_buffer_physaddr =
1049 	sc->mly_mmbox_busaddr + offsetof(struct mly_mmbox, mmm_health);
1050 
1051     /* set buffer sizes - abuse of data_size field is revolting */
1052     sp = (u_int8_t *)&mci.data_size;
1053     sp[0] = ((sizeof(union mly_command_packet) * MLY_MMBOX_COMMANDS) / 1024);
1054     sp[1] = (sizeof(union mly_status_packet) * MLY_MMBOX_STATUS) / 1024;
1055     mci.param.setmemorymailbox.health_buffer_size = sizeof(union mly_health_region) / 1024;
1056 
1057     debug(1, "memory mailbox at %p (0x%llx/%d 0x%llx/%d 0x%llx/%d", sc->mly_mmbox,
1058 	  mci.param.setmemorymailbox.command_mailbox_physaddr, sp[0],
1059 	  mci.param.setmemorymailbox.status_mailbox_physaddr, sp[1],
1060 	  mci.param.setmemorymailbox.health_buffer_physaddr,
1061 	  mci.param.setmemorymailbox.health_buffer_size);
1062 
1063     if ((error = mly_ioctl(sc, &mci, NULL, 0, &status, NULL, NULL)))
1064 	return(error);
1065     if (status != 0)
1066 	return(EIO);
1067     sc->mly_state |= MLY_STATE_MMBOX_ACTIVE;
1068     debug(1, "memory mailbox active");
1069     return(0);
1070 }
1071 
1072 /********************************************************************************
1073  * Flush all pending I/O from the controller.
1074  */
1075 static int
mly_flush(struct mly_softc * sc)1076 mly_flush(struct mly_softc *sc)
1077 {
1078     struct mly_command_ioctl	mci;
1079     u_int8_t			status;
1080     int				error;
1081 
1082     debug_called(1);
1083 
1084     /* build the ioctl */
1085     bzero(&mci, sizeof(mci));
1086     mci.sub_ioctl = MDACIOCTL_FLUSHDEVICEDATA;
1087     mci.param.deviceoperation.operation_device = MLY_OPDEVICE_PHYSICAL_CONTROLLER;
1088 
1089     /* pass it off to the controller */
1090     if ((error = mly_ioctl(sc, &mci, NULL, 0, &status, NULL, NULL)))
1091 	return(error);
1092 
1093     return((status == 0) ? 0 : EIO);
1094 }
1095 
1096 /********************************************************************************
1097  * Perform an ioctl command.
1098  *
1099  * If (data) is not NULL, the command requires data transfer.  If (*data) is NULL
1100  * the command requires data transfer from the controller, and we will allocate
1101  * a buffer for it.  If (*data) is not NULL, the command requires data transfer
1102  * to the controller.
1103  *
1104  * XXX passing in the whole ioctl structure is ugly.  Better ideas?
1105  *
1106  * XXX we don't even try to handle the case where datasize > 4k.  We should.
1107  */
1108 static int
mly_ioctl(struct mly_softc * sc,struct mly_command_ioctl * ioctl,void ** data,size_t datasize,u_int8_t * status,void * sense_buffer,size_t * sense_length)1109 mly_ioctl(struct mly_softc *sc, struct mly_command_ioctl *ioctl, void **data, size_t datasize,
1110 	  u_int8_t *status, void *sense_buffer, size_t *sense_length)
1111 {
1112     struct mly_command		*mc;
1113     struct mly_command_ioctl	*mci;
1114     int				error;
1115 
1116     debug_called(1);
1117     MLY_ASSERT_LOCKED(sc);
1118 
1119     mc = NULL;
1120     if (mly_alloc_command(sc, &mc)) {
1121 	error = ENOMEM;
1122 	goto out;
1123     }
1124 
1125     /* copy the ioctl structure, but save some important fields and then fixup */
1126     mci = &mc->mc_packet->ioctl;
1127     ioctl->sense_buffer_address = mci->sense_buffer_address;
1128     ioctl->maximum_sense_size = mci->maximum_sense_size;
1129     *mci = *ioctl;
1130     mci->opcode = MDACMD_IOCTL;
1131     mci->timeout.value = 30;
1132     mci->timeout.scale = MLY_TIMEOUT_SECONDS;
1133 
1134     /* handle the data buffer */
1135     if (data != NULL) {
1136 	if (*data == NULL) {
1137 	    /* allocate data buffer */
1138 	    if ((mc->mc_data = malloc(datasize, M_DEVBUF, M_NOWAIT)) == NULL) {
1139 		error = ENOMEM;
1140 		goto out;
1141 	    }
1142 	    mc->mc_flags |= MLY_CMD_DATAIN;
1143 	} else {
1144 	    mc->mc_data = *data;
1145 	    mc->mc_flags |= MLY_CMD_DATAOUT;
1146 	}
1147 	mc->mc_length = datasize;
1148 	mc->mc_packet->generic.data_size = datasize;
1149     }
1150 
1151     /* run the command */
1152     if ((error = mly_immediate_command(mc)))
1153 	goto out;
1154 
1155     /* clean up and return any data */
1156     *status = mc->mc_status;
1157     if ((mc->mc_sense > 0) && (sense_buffer != NULL)) {
1158 	bcopy(mc->mc_packet, sense_buffer, mc->mc_sense);
1159 	*sense_length = mc->mc_sense;
1160 	goto out;
1161     }
1162 
1163     /* should we return a data pointer? */
1164     if ((data != NULL) && (*data == NULL))
1165 	*data = mc->mc_data;
1166 
1167     /* command completed OK */
1168     error = 0;
1169 
1170 out:
1171     if (mc != NULL) {
1172 	/* do we need to free a data buffer we allocated? */
1173 	if (error && (mc->mc_data != NULL) && (*data == NULL))
1174 	    free(mc->mc_data, M_DEVBUF);
1175 	mly_release_command(mc);
1176     }
1177     return(error);
1178 }
1179 
1180 /********************************************************************************
1181  * Check for event(s) outstanding in the controller.
1182  */
1183 static void
mly_check_event(struct mly_softc * sc)1184 mly_check_event(struct mly_softc *sc)
1185 {
1186 
1187     /*
1188      * The controller may have updated the health status information,
1189      * so check for it here.  Note that the counters are all in host memory,
1190      * so this check is very cheap.  Also note that we depend on checking on
1191      * completion
1192      */
1193     if (sc->mly_mmbox->mmm_health.status.change_counter != sc->mly_event_change) {
1194 	sc->mly_event_change = sc->mly_mmbox->mmm_health.status.change_counter;
1195 	debug(1, "event change %d, event status update, %d -> %d", sc->mly_event_change,
1196 	      sc->mly_event_waiting, sc->mly_mmbox->mmm_health.status.next_event);
1197 	sc->mly_event_waiting = sc->mly_mmbox->mmm_health.status.next_event;
1198 
1199 	/* wake up anyone that might be interested in this */
1200 	wakeup(&sc->mly_event_change);
1201     }
1202     if (sc->mly_event_counter != sc->mly_event_waiting)
1203     mly_fetch_event(sc);
1204 }
1205 
1206 /********************************************************************************
1207  * Fetch one event from the controller.
1208  *
1209  * If we fail due to resource starvation, we'll be retried the next time a
1210  * command completes.
1211  */
1212 static void
mly_fetch_event(struct mly_softc * sc)1213 mly_fetch_event(struct mly_softc *sc)
1214 {
1215     struct mly_command		*mc;
1216     struct mly_command_ioctl	*mci;
1217     u_int32_t			event;
1218 
1219     debug_called(1);
1220 
1221     /* get a command */
1222     if (mly_alloc_command(sc, &mc))
1223 	return;
1224 
1225     /* set up the data buffer */
1226     if ((mc->mc_data = malloc(sizeof(struct mly_event), M_DEVBUF, M_NOWAIT | M_ZERO)) == NULL) {
1227 	mly_release_command(mc);
1228 	return;
1229     }
1230     mc->mc_length = sizeof(struct mly_event);
1231     mc->mc_flags |= MLY_CMD_DATAIN;
1232     mc->mc_complete = mly_complete_event;
1233 
1234     /*
1235      * Get an event number to fetch.  It's possible that we've raced with another
1236      * context for the last event, in which case there will be no more events.
1237      */
1238     if (sc->mly_event_counter == sc->mly_event_waiting) {
1239 	mly_release_command(mc);
1240 	return;
1241     }
1242     event = sc->mly_event_counter++;
1243 
1244     /*
1245      * Build the ioctl.
1246      *
1247      * At this point we are committed to sending this request, as it
1248      * will be the only one constructed for this particular event number.
1249      */
1250     mci = (struct mly_command_ioctl *)&mc->mc_packet->ioctl;
1251     mci->opcode = MDACMD_IOCTL;
1252     mci->data_size = sizeof(struct mly_event);
1253     mci->addr.phys.lun = (event >> 16) & 0xff;
1254     mci->addr.phys.target = (event >> 24) & 0xff;
1255     mci->addr.phys.channel = 0;
1256     mci->addr.phys.controller = 0;
1257     mci->timeout.value = 30;
1258     mci->timeout.scale = MLY_TIMEOUT_SECONDS;
1259     mci->sub_ioctl = MDACIOCTL_GETEVENT;
1260     mci->param.getevent.sequence_number_low = event & 0xffff;
1261 
1262     debug(1, "fetch event %u", event);
1263 
1264     /*
1265      * Submit the command.
1266      *
1267      * Note that failure of mly_start() will result in this event never being
1268      * fetched.
1269      */
1270     if (mly_start(mc) != 0) {
1271 	mly_printf(sc, "couldn't fetch event %u\n", event);
1272 	mly_release_command(mc);
1273     }
1274 }
1275 
1276 /********************************************************************************
1277  * Handle the completion of an event poll.
1278  */
1279 static void
mly_complete_event(struct mly_command * mc)1280 mly_complete_event(struct mly_command *mc)
1281 {
1282     struct mly_softc	*sc = mc->mc_sc;
1283     struct mly_event	*me = (struct mly_event *)mc->mc_data;
1284 
1285     debug_called(1);
1286 
1287     /*
1288      * If the event was successfully fetched, process it.
1289      */
1290     if (mc->mc_status == SCSI_STATUS_OK) {
1291 	mly_process_event(sc, me);
1292 	free(me, M_DEVBUF);
1293     }
1294     mly_release_command(mc);
1295 
1296     /*
1297      * Check for another event.
1298      */
1299     mly_check_event(sc);
1300 }
1301 
1302 /********************************************************************************
1303  * Process a controller event.
1304  */
1305 static void
mly_process_event(struct mly_softc * sc,struct mly_event * me)1306 mly_process_event(struct mly_softc *sc, struct mly_event *me)
1307 {
1308     struct scsi_sense_data_fixed *ssd;
1309     char			 *fp, *tp;
1310     int				 bus, target, event, class, action;
1311 
1312     ssd = (struct scsi_sense_data_fixed *)&me->sense[0];
1313 
1314     /*
1315      * Errors can be reported using vendor-unique sense data.  In this case, the
1316      * event code will be 0x1c (Request sense data present), the sense key will
1317      * be 0x09 (vendor specific), the MSB of the ASC will be set, and the
1318      * actual event code will be a 16-bit value comprised of the ASCQ (low byte)
1319      * and low seven bits of the ASC (low seven bits of the high byte).
1320      */
1321     if ((me->code == 0x1c) &&
1322 	((ssd->flags & SSD_KEY) == SSD_KEY_Vendor_Specific) &&
1323 	(ssd->add_sense_code & 0x80)) {
1324 	event = ((int)(ssd->add_sense_code & ~0x80) << 8) + ssd->add_sense_code_qual;
1325     } else {
1326 	event = me->code;
1327     }
1328 
1329     /* look up event, get codes */
1330     fp = mly_describe_code(mly_table_event, event);
1331 
1332     debug(1, "Event %d  code 0x%x", me->sequence_number, me->code);
1333 
1334     /* quiet event? */
1335     class = fp[0];
1336     if (isupper(class) && bootverbose)
1337 	class = tolower(class);
1338 
1339     /* get action code, text string */
1340     action = fp[1];
1341     tp = &fp[2];
1342 
1343     /*
1344      * Print some information about the event.
1345      *
1346      * This code uses a table derived from the corresponding portion of the Linux
1347      * driver, and thus the parser is very similar.
1348      */
1349     switch(class) {
1350     case 'p':		/* error on physical device */
1351 	mly_printf(sc, "physical device %d:%d %s\n", me->channel, me->target, tp);
1352 	if (action == 'r')
1353 	    sc->mly_btl[me->channel][me->target].mb_flags |= MLY_BTL_RESCAN;
1354 	break;
1355     case 'l':		/* error on logical unit */
1356     case 'm':		/* message about logical unit */
1357 	bus = MLY_LOGDEV_BUS(sc, me->lun);
1358 	target = MLY_LOGDEV_TARGET(sc, me->lun);
1359 	mly_name_device(sc, bus, target);
1360 	mly_printf(sc, "logical device %d (%s) %s\n", me->lun, sc->mly_btl[bus][target].mb_name, tp);
1361 	if (action == 'r')
1362 	    sc->mly_btl[bus][target].mb_flags |= MLY_BTL_RESCAN;
1363 	break;
1364     case 's':		/* report of sense data */
1365 	if (((ssd->flags & SSD_KEY) == SSD_KEY_NO_SENSE) ||
1366 	    (((ssd->flags & SSD_KEY) == SSD_KEY_NOT_READY) &&
1367 	     (ssd->add_sense_code == 0x04) &&
1368 	     ((ssd->add_sense_code_qual == 0x01) || (ssd->add_sense_code_qual == 0x02))))
1369 	    break;	/* ignore NO_SENSE or NOT_READY in one case */
1370 
1371 	mly_printf(sc, "physical device %d:%d %s\n", me->channel, me->target, tp);
1372 	mly_printf(sc, "  sense key %d  asc %02x  ascq %02x\n",
1373 		      ssd->flags & SSD_KEY, ssd->add_sense_code, ssd->add_sense_code_qual);
1374 	mly_printf(sc, "  info %4D  csi %4D\n", ssd->info, "", ssd->cmd_spec_info, "");
1375 	if (action == 'r')
1376 	    sc->mly_btl[me->channel][me->target].mb_flags |= MLY_BTL_RESCAN;
1377 	break;
1378     case 'e':
1379 	mly_printf(sc, tp, me->target, me->lun);
1380 	printf("\n");
1381 	break;
1382     case 'c':
1383 	mly_printf(sc, "controller %s\n", tp);
1384 	break;
1385     case '?':
1386 	mly_printf(sc, "%s - %d\n", tp, me->code);
1387 	break;
1388     default:	/* probably a 'noisy' event being ignored */
1389 	break;
1390     }
1391 }
1392 
1393 /********************************************************************************
1394  * Perform periodic activities.
1395  */
1396 static void
mly_periodic(void * data)1397 mly_periodic(void *data)
1398 {
1399     struct mly_softc	*sc = (struct mly_softc *)data;
1400     int			bus, target;
1401 
1402     debug_called(2);
1403     MLY_ASSERT_LOCKED(sc);
1404 
1405     /*
1406      * Scan devices.
1407      */
1408     for (bus = 0; bus < sc->mly_cam_channels; bus++) {
1409 	if (MLY_BUS_IS_VALID(sc, bus)) {
1410 	    for (target = 0; target < MLY_MAX_TARGETS; target++) {
1411 		/* ignore the controller in this scan */
1412 		if (target == sc->mly_controllerparam->initiator_id)
1413 		    continue;
1414 
1415 		/* perform device rescan? */
1416 		if (sc->mly_btl[bus][target].mb_flags & MLY_BTL_RESCAN)
1417 		    mly_rescan_btl(sc, bus, target);
1418 	    }
1419 	}
1420     }
1421 
1422     /* check for controller events */
1423     mly_check_event(sc);
1424 
1425     /* reschedule ourselves */
1426     callout_schedule(&sc->mly_periodic, MLY_PERIODIC_INTERVAL * hz);
1427 }
1428 
1429 /********************************************************************************
1430  ********************************************************************************
1431                                                                Command Processing
1432  ********************************************************************************
1433  ********************************************************************************/
1434 
1435 /********************************************************************************
1436  * Run a command and wait for it to complete.
1437  *
1438  */
1439 static int
mly_immediate_command(struct mly_command * mc)1440 mly_immediate_command(struct mly_command *mc)
1441 {
1442     struct mly_softc	*sc = mc->mc_sc;
1443     int			error;
1444 
1445     debug_called(1);
1446 
1447     MLY_ASSERT_LOCKED(sc);
1448     if ((error = mly_start(mc))) {
1449 	return(error);
1450     }
1451 
1452     if (sc->mly_state & MLY_STATE_INTERRUPTS_ON) {
1453 	/* sleep on the command */
1454 	while(!(mc->mc_flags & MLY_CMD_COMPLETE)) {
1455 	    mtx_sleep(mc, &sc->mly_lock, PRIBIO, "mlywait", 0);
1456 	}
1457     } else {
1458 	/* spin and collect status while we do */
1459 	while(!(mc->mc_flags & MLY_CMD_COMPLETE)) {
1460 	    mly_done(mc->mc_sc);
1461 	}
1462     }
1463     return(0);
1464 }
1465 
1466 /********************************************************************************
1467  * Deliver a command to the controller.
1468  *
1469  * XXX it would be good to just queue commands that we can't submit immediately
1470  *     and send them later, but we probably want a wrapper for that so that
1471  *     we don't hang on a failed submission for an immediate command.
1472  */
1473 static int
mly_start(struct mly_command * mc)1474 mly_start(struct mly_command *mc)
1475 {
1476     struct mly_softc		*sc = mc->mc_sc;
1477     union mly_command_packet	*pkt;
1478 
1479     debug_called(2);
1480     MLY_ASSERT_LOCKED(sc);
1481 
1482     /*
1483      * Set the command up for delivery to the controller.
1484      */
1485     mly_map_command(mc);
1486     mc->mc_packet->generic.command_id = mc->mc_slot;
1487 
1488 #ifdef MLY_DEBUG
1489     mc->mc_timestamp = time_second;
1490 #endif
1491 
1492     /*
1493      * Do we have to use the hardware mailbox?
1494      */
1495     if (!(sc->mly_state & MLY_STATE_MMBOX_ACTIVE)) {
1496 	/*
1497 	 * Check to see if the controller is ready for us.
1498 	 */
1499 	if (MLY_IDBR_TRUE(sc, MLY_HM_CMDSENT)) {
1500 	    return(EBUSY);
1501 	}
1502 	mc->mc_flags |= MLY_CMD_BUSY;
1503 
1504 	/*
1505 	 * It's ready, send the command.
1506 	 */
1507 	MLY_SET_MBOX(sc, sc->mly_command_mailbox, &mc->mc_packetphys);
1508 	MLY_SET_REG(sc, sc->mly_idbr, MLY_HM_CMDSENT);
1509 
1510     } else {	/* use memory-mailbox mode */
1511 
1512 	pkt = &sc->mly_mmbox->mmm_command[sc->mly_mmbox_command_index];
1513 
1514 	/* check to see if the next index is free yet */
1515 	if (pkt->mmbox.flag != 0) {
1516 	    return(EBUSY);
1517 	}
1518 	mc->mc_flags |= MLY_CMD_BUSY;
1519 
1520 	/* copy in new command */
1521 	bcopy(mc->mc_packet->mmbox.data, pkt->mmbox.data, sizeof(pkt->mmbox.data));
1522 	/* barrier to ensure completion of previous write before we write the flag */
1523 	bus_barrier(sc->mly_regs_resource, 0, 0, BUS_SPACE_BARRIER_WRITE);
1524 	/* copy flag last */
1525 	pkt->mmbox.flag = mc->mc_packet->mmbox.flag;
1526 	/* barrier to ensure completion of previous write before we notify the controller */
1527 	bus_barrier(sc->mly_regs_resource, 0, 0, BUS_SPACE_BARRIER_WRITE);
1528 
1529 	/* signal controller, update index */
1530 	MLY_SET_REG(sc, sc->mly_idbr, MLY_AM_CMDSENT);
1531 	sc->mly_mmbox_command_index = (sc->mly_mmbox_command_index + 1) % MLY_MMBOX_COMMANDS;
1532     }
1533 
1534     mly_enqueue_busy(mc);
1535     return(0);
1536 }
1537 
1538 /********************************************************************************
1539  * Pick up command status from the controller, schedule a completion event
1540  */
1541 static void
mly_done(struct mly_softc * sc)1542 mly_done(struct mly_softc *sc)
1543 {
1544     struct mly_command		*mc;
1545     union mly_status_packet	*sp;
1546     u_int16_t			slot;
1547     int				worked;
1548 
1549     MLY_ASSERT_LOCKED(sc);
1550     worked = 0;
1551 
1552     /* pick up hardware-mailbox commands */
1553     if (MLY_ODBR_TRUE(sc, MLY_HM_STSREADY)) {
1554 	slot = MLY_GET_REG2(sc, sc->mly_status_mailbox);
1555 	if (slot < MLY_SLOT_MAX) {
1556 	    mc = &sc->mly_command[slot - MLY_SLOT_START];
1557 	    mc->mc_status = MLY_GET_REG(sc, sc->mly_status_mailbox + 2);
1558 	    mc->mc_sense = MLY_GET_REG(sc, sc->mly_status_mailbox + 3);
1559 	    mc->mc_resid = MLY_GET_REG4(sc, sc->mly_status_mailbox + 4);
1560 	    mly_remove_busy(mc);
1561 	    mc->mc_flags &= ~MLY_CMD_BUSY;
1562 	    mly_enqueue_complete(mc);
1563 	    worked = 1;
1564 	} else {
1565 	    /* slot 0xffff may mean "extremely bogus command" */
1566 	    mly_printf(sc, "got HM completion for illegal slot %u\n", slot);
1567 	}
1568 	/* unconditionally acknowledge status */
1569 	MLY_SET_REG(sc, sc->mly_odbr, MLY_HM_STSREADY);
1570 	MLY_SET_REG(sc, sc->mly_idbr, MLY_HM_STSACK);
1571     }
1572 
1573     /* pick up memory-mailbox commands */
1574     if (MLY_ODBR_TRUE(sc, MLY_AM_STSREADY)) {
1575 	for (;;) {
1576 	    sp = &sc->mly_mmbox->mmm_status[sc->mly_mmbox_status_index];
1577 
1578 	    /* check for more status */
1579 	    if (sp->mmbox.flag == 0)
1580 		break;
1581 
1582 	    /* get slot number */
1583 	    slot = sp->status.command_id;
1584 	    if (slot < MLY_SLOT_MAX) {
1585 		mc = &sc->mly_command[slot - MLY_SLOT_START];
1586 		mc->mc_status = sp->status.status;
1587 		mc->mc_sense = sp->status.sense_length;
1588 		mc->mc_resid = sp->status.residue;
1589 		mly_remove_busy(mc);
1590 		mc->mc_flags &= ~MLY_CMD_BUSY;
1591 		mly_enqueue_complete(mc);
1592 		worked = 1;
1593 	    } else {
1594 		/* slot 0xffff may mean "extremely bogus command" */
1595 		mly_printf(sc, "got AM completion for illegal slot %u at %d\n",
1596 			   slot, sc->mly_mmbox_status_index);
1597 	    }
1598 
1599 	    /* clear and move to next index */
1600 	    sp->mmbox.flag = 0;
1601 	    sc->mly_mmbox_status_index = (sc->mly_mmbox_status_index + 1) % MLY_MMBOX_STATUS;
1602 	}
1603 	/* acknowledge that we have collected status value(s) */
1604 	MLY_SET_REG(sc, sc->mly_odbr, MLY_AM_STSREADY);
1605     }
1606 
1607     if (worked) {
1608 	if (sc->mly_state & MLY_STATE_INTERRUPTS_ON)
1609 	    taskqueue_enqueue(taskqueue_thread, &sc->mly_task_complete);
1610 	else
1611 	    mly_complete(sc);
1612     }
1613 }
1614 
1615 /********************************************************************************
1616  * Process completed commands
1617  */
1618 static void
mly_complete_handler(void * context,int pending)1619 mly_complete_handler(void *context, int pending)
1620 {
1621     struct mly_softc	*sc = (struct mly_softc *)context;
1622 
1623     MLY_LOCK(sc);
1624     mly_complete(sc);
1625     MLY_UNLOCK(sc);
1626 }
1627 
1628 static void
mly_complete(struct mly_softc * sc)1629 mly_complete(struct mly_softc *sc)
1630 {
1631     struct mly_command	*mc;
1632     void	        (* mc_complete)(struct mly_command *mc);
1633 
1634     debug_called(2);
1635 
1636     /*
1637      * Spin pulling commands off the completed queue and processing them.
1638      */
1639     while ((mc = mly_dequeue_complete(sc)) != NULL) {
1640 	/*
1641 	 * Free controller resources, mark command complete.
1642 	 *
1643 	 * Note that as soon as we mark the command complete, it may be freed
1644 	 * out from under us, so we need to save the mc_complete field in
1645 	 * order to later avoid dereferencing mc.  (We would not expect to
1646 	 * have a polling/sleeping consumer with mc_complete != NULL).
1647 	 */
1648 	mly_unmap_command(mc);
1649 	mc_complete = mc->mc_complete;
1650 	mc->mc_flags |= MLY_CMD_COMPLETE;
1651 
1652 	/*
1653 	 * Call completion handler or wake up sleeping consumer.
1654 	 */
1655 	if (mc_complete != NULL) {
1656 	    mc_complete(mc);
1657 	} else {
1658 	    wakeup(mc);
1659 	}
1660     }
1661 
1662     /*
1663      * XXX if we are deferring commands due to controller-busy status, we should
1664      *     retry submitting them here.
1665      */
1666 }
1667 
1668 /********************************************************************************
1669  ********************************************************************************
1670                                                         Command Buffer Management
1671  ********************************************************************************
1672  ********************************************************************************/
1673 
1674 /********************************************************************************
1675  * Allocate a command.
1676  */
1677 static int
mly_alloc_command(struct mly_softc * sc,struct mly_command ** mcp)1678 mly_alloc_command(struct mly_softc *sc, struct mly_command **mcp)
1679 {
1680     struct mly_command	*mc;
1681 
1682     debug_called(3);
1683 
1684     if ((mc = mly_dequeue_free(sc)) == NULL)
1685 	return(ENOMEM);
1686 
1687     *mcp = mc;
1688     return(0);
1689 }
1690 
1691 /********************************************************************************
1692  * Release a command back to the freelist.
1693  */
1694 static void
mly_release_command(struct mly_command * mc)1695 mly_release_command(struct mly_command *mc)
1696 {
1697     debug_called(3);
1698 
1699     /*
1700      * Fill in parts of the command that may cause confusion if
1701      * a consumer doesn't when we are later allocated.
1702      */
1703     mc->mc_data = NULL;
1704     mc->mc_flags = 0;
1705     mc->mc_complete = NULL;
1706     mc->mc_private = NULL;
1707 
1708     /*
1709      * By default, we set up to overwrite the command packet with
1710      * sense information.
1711      */
1712     mc->mc_packet->generic.sense_buffer_address = mc->mc_packetphys;
1713     mc->mc_packet->generic.maximum_sense_size = sizeof(union mly_command_packet);
1714 
1715     mly_enqueue_free(mc);
1716 }
1717 
1718 /********************************************************************************
1719  * Map helper for command allocation.
1720  */
1721 static void
mly_alloc_commands_map(void * arg,bus_dma_segment_t * segs,int nseg,int error)1722 mly_alloc_commands_map(void *arg, bus_dma_segment_t *segs, int nseg, int error)
1723 {
1724     struct mly_softc	*sc = (struct mly_softc *)arg;
1725 
1726     debug_called(1);
1727 
1728     sc->mly_packetphys = segs[0].ds_addr;
1729 }
1730 
1731 /********************************************************************************
1732  * Allocate and initialise command and packet structures.
1733  *
1734  * If the controller supports fewer than MLY_MAX_COMMANDS commands, limit our
1735  * allocation to that number.  If we don't yet know how many commands the
1736  * controller supports, allocate a very small set (suitable for initialisation
1737  * purposes only).
1738  */
1739 static int
mly_alloc_commands(struct mly_softc * sc)1740 mly_alloc_commands(struct mly_softc *sc)
1741 {
1742     struct mly_command		*mc;
1743     int				i, ncmd;
1744 
1745     if (sc->mly_controllerinfo == NULL) {
1746 	ncmd = 4;
1747     } else {
1748 	ncmd = min(MLY_MAX_COMMANDS, sc->mly_controllerinfo->maximum_parallel_commands);
1749     }
1750 
1751     /*
1752      * Allocate enough space for all the command packets in one chunk and
1753      * map them permanently into controller-visible space.
1754      */
1755     if (bus_dmamem_alloc(sc->mly_packet_dmat, (void **)&sc->mly_packet,
1756 			 BUS_DMA_NOWAIT, &sc->mly_packetmap)) {
1757 	return(ENOMEM);
1758     }
1759     if (bus_dmamap_load(sc->mly_packet_dmat, sc->mly_packetmap, sc->mly_packet,
1760 			ncmd * sizeof(union mly_command_packet),
1761 			mly_alloc_commands_map, sc, BUS_DMA_NOWAIT) != 0)
1762 	return (ENOMEM);
1763 
1764     for (i = 0; i < ncmd; i++) {
1765 	mc = &sc->mly_command[i];
1766 	bzero(mc, sizeof(*mc));
1767 	mc->mc_sc = sc;
1768 	mc->mc_slot = MLY_SLOT_START + i;
1769 	mc->mc_packet = sc->mly_packet + i;
1770 	mc->mc_packetphys = sc->mly_packetphys + (i * sizeof(union mly_command_packet));
1771 	if (!bus_dmamap_create(sc->mly_buffer_dmat, 0, &mc->mc_datamap))
1772 	    mly_release_command(mc);
1773     }
1774     return(0);
1775 }
1776 
1777 /********************************************************************************
1778  * Free all the storage held by commands.
1779  *
1780  * Must be called with all commands on the free list.
1781  */
1782 static void
mly_release_commands(struct mly_softc * sc)1783 mly_release_commands(struct mly_softc *sc)
1784 {
1785     struct mly_command	*mc;
1786 
1787     /* throw away command buffer DMA maps */
1788     while (mly_alloc_command(sc, &mc) == 0)
1789 	bus_dmamap_destroy(sc->mly_buffer_dmat, mc->mc_datamap);
1790 
1791     /* release the packet storage */
1792     if (sc->mly_packet != NULL) {
1793 	bus_dmamap_unload(sc->mly_packet_dmat, sc->mly_packetmap);
1794 	bus_dmamem_free(sc->mly_packet_dmat, sc->mly_packet, sc->mly_packetmap);
1795 	sc->mly_packet = NULL;
1796     }
1797 }
1798 
1799 /********************************************************************************
1800  * Command-mapping helper function - populate this command's s/g table
1801  * with the s/g entries for its data.
1802  */
1803 static void
mly_map_command_sg(void * arg,bus_dma_segment_t * segs,int nseg,int error)1804 mly_map_command_sg(void *arg, bus_dma_segment_t *segs, int nseg, int error)
1805 {
1806     struct mly_command		*mc = (struct mly_command *)arg;
1807     struct mly_softc		*sc = mc->mc_sc;
1808     struct mly_command_generic	*gen = &(mc->mc_packet->generic);
1809     struct mly_sg_entry		*sg;
1810     int				i, tabofs;
1811 
1812     debug_called(2);
1813 
1814     /* can we use the transfer structure directly? */
1815     if (nseg <= 2) {
1816 	sg = &gen->transfer.direct.sg[0];
1817 	gen->command_control.extended_sg_table = 0;
1818     } else {
1819 	tabofs = ((mc->mc_slot - MLY_SLOT_START) * MLY_MAX_SGENTRIES);
1820 	sg = sc->mly_sg_table + tabofs;
1821 	gen->transfer.indirect.entries[0] = nseg;
1822 	gen->transfer.indirect.table_physaddr[0] = sc->mly_sg_busaddr + (tabofs * sizeof(struct mly_sg_entry));
1823 	gen->command_control.extended_sg_table = 1;
1824     }
1825 
1826     /* copy the s/g table */
1827     for (i = 0; i < nseg; i++) {
1828 	sg[i].physaddr = segs[i].ds_addr;
1829 	sg[i].length = segs[i].ds_len;
1830     }
1831 
1832 }
1833 
1834 #if 0
1835 /********************************************************************************
1836  * Command-mapping helper function - save the cdb's physical address.
1837  *
1838  * We don't support 'large' SCSI commands at this time, so this is unused.
1839  */
1840 static void
1841 mly_map_command_cdb(void *arg, bus_dma_segment_t *segs, int nseg, int error)
1842 {
1843     struct mly_command			*mc = (struct mly_command *)arg;
1844 
1845     debug_called(2);
1846 
1847     /* XXX can we safely assume that a CDB will never cross a page boundary? */
1848     if ((segs[0].ds_addr % PAGE_SIZE) >
1849 	((segs[0].ds_addr + mc->mc_packet->scsi_large.cdb_length) % PAGE_SIZE))
1850 	panic("cdb crosses page boundary");
1851 
1852     /* fix up fields in the command packet */
1853     mc->mc_packet->scsi_large.cdb_physaddr = segs[0].ds_addr;
1854 }
1855 #endif
1856 
1857 /********************************************************************************
1858  * Map a command into controller-visible space
1859  */
1860 static void
mly_map_command(struct mly_command * mc)1861 mly_map_command(struct mly_command *mc)
1862 {
1863     struct mly_softc	*sc = mc->mc_sc;
1864 
1865     debug_called(2);
1866 
1867     /* don't map more than once */
1868     if (mc->mc_flags & MLY_CMD_MAPPED)
1869 	return;
1870 
1871     /* does the command have a data buffer? */
1872     if (mc->mc_data != NULL) {
1873 	if (mc->mc_flags & MLY_CMD_CCB)
1874 		bus_dmamap_load_ccb(sc->mly_buffer_dmat, mc->mc_datamap,
1875 				mc->mc_data, mly_map_command_sg, mc, 0);
1876 	else
1877 		bus_dmamap_load(sc->mly_buffer_dmat, mc->mc_datamap,
1878 				mc->mc_data, mc->mc_length,
1879 				mly_map_command_sg, mc, 0);
1880 	if (mc->mc_flags & MLY_CMD_DATAIN)
1881 	    bus_dmamap_sync(sc->mly_buffer_dmat, mc->mc_datamap, BUS_DMASYNC_PREREAD);
1882 	if (mc->mc_flags & MLY_CMD_DATAOUT)
1883 	    bus_dmamap_sync(sc->mly_buffer_dmat, mc->mc_datamap, BUS_DMASYNC_PREWRITE);
1884     }
1885     mc->mc_flags |= MLY_CMD_MAPPED;
1886 }
1887 
1888 /********************************************************************************
1889  * Unmap a command from controller-visible space
1890  */
1891 static void
mly_unmap_command(struct mly_command * mc)1892 mly_unmap_command(struct mly_command *mc)
1893 {
1894     struct mly_softc	*sc = mc->mc_sc;
1895 
1896     debug_called(2);
1897 
1898     if (!(mc->mc_flags & MLY_CMD_MAPPED))
1899 	return;
1900 
1901     /* does the command have a data buffer? */
1902     if (mc->mc_data != NULL) {
1903 	if (mc->mc_flags & MLY_CMD_DATAIN)
1904 	    bus_dmamap_sync(sc->mly_buffer_dmat, mc->mc_datamap, BUS_DMASYNC_POSTREAD);
1905 	if (mc->mc_flags & MLY_CMD_DATAOUT)
1906 	    bus_dmamap_sync(sc->mly_buffer_dmat, mc->mc_datamap, BUS_DMASYNC_POSTWRITE);
1907 
1908 	bus_dmamap_unload(sc->mly_buffer_dmat, mc->mc_datamap);
1909     }
1910     mc->mc_flags &= ~MLY_CMD_MAPPED;
1911 }
1912 
1913 /********************************************************************************
1914  ********************************************************************************
1915                                                                     CAM interface
1916  ********************************************************************************
1917  ********************************************************************************/
1918 
1919 /********************************************************************************
1920  * Attach the physical and virtual SCSI busses to CAM.
1921  *
1922  * Physical bus numbering starts from 0, virtual bus numbering from one greater
1923  * than the highest physical bus.  Physical busses are only registered if
1924  * the kernel environment variable "hw.mly.register_physical_channels" is set.
1925  *
1926  * When we refer to a "bus", we are referring to the bus number registered with
1927  * the SIM, whereas a "channel" is a channel number given to the adapter.  In order
1928  * to keep things simple, we map these 1:1, so "bus" and "channel" may be used
1929  * interchangeably.
1930  */
1931 static int
mly_cam_attach(struct mly_softc * sc)1932 mly_cam_attach(struct mly_softc *sc)
1933 {
1934     struct cam_devq	*devq;
1935     int			chn, i;
1936 
1937     debug_called(1);
1938 
1939     /*
1940      * Allocate a devq for all our channels combined.
1941      */
1942     if ((devq = cam_simq_alloc(sc->mly_controllerinfo->maximum_parallel_commands)) == NULL) {
1943 	mly_printf(sc, "can't allocate CAM SIM queue\n");
1944 	return(ENOMEM);
1945     }
1946 
1947     /*
1948      * If physical channel registration has been requested, register these first.
1949      * Note that we enable tagged command queueing for physical channels.
1950      */
1951     if (testenv("hw.mly.register_physical_channels")) {
1952 	chn = 0;
1953 	for (i = 0; i < sc->mly_controllerinfo->physical_channels_present; i++, chn++) {
1954 	    if ((sc->mly_cam_sim[chn] = cam_sim_alloc(mly_cam_action, mly_cam_poll, "mly", sc,
1955 						      device_get_unit(sc->mly_dev),
1956 						      &sc->mly_lock,
1957 						      sc->mly_controllerinfo->maximum_parallel_commands,
1958 						      1, devq)) == NULL) {
1959 		return(ENOMEM);
1960 	    }
1961 	    MLY_LOCK(sc);
1962 	    if (xpt_bus_register(sc->mly_cam_sim[chn], sc->mly_dev, chn)) {
1963 		MLY_UNLOCK(sc);
1964 		mly_printf(sc, "CAM XPT phsyical channel registration failed\n");
1965 		return(ENXIO);
1966 	    }
1967 	    MLY_UNLOCK(sc);
1968 	    debug(1, "registered physical channel %d", chn);
1969 	}
1970     }
1971 
1972     /*
1973      * Register our virtual channels, with bus numbers matching channel numbers.
1974      */
1975     chn = sc->mly_controllerinfo->physical_channels_present;
1976     for (i = 0; i < sc->mly_controllerinfo->virtual_channels_present; i++, chn++) {
1977 	if ((sc->mly_cam_sim[chn] = cam_sim_alloc(mly_cam_action, mly_cam_poll, "mly", sc,
1978 						  device_get_unit(sc->mly_dev),
1979 						  &sc->mly_lock,
1980 						  sc->mly_controllerinfo->maximum_parallel_commands,
1981 						  0, devq)) == NULL) {
1982 	    return(ENOMEM);
1983 	}
1984 	MLY_LOCK(sc);
1985 	if (xpt_bus_register(sc->mly_cam_sim[chn], sc->mly_dev, chn)) {
1986 	    MLY_UNLOCK(sc);
1987 	    mly_printf(sc, "CAM XPT virtual channel registration failed\n");
1988 	    return(ENXIO);
1989 	}
1990 	MLY_UNLOCK(sc);
1991 	debug(1, "registered virtual channel %d", chn);
1992     }
1993 
1994     /*
1995      * This is the total number of channels that (might have been) registered with
1996      * CAM.  Some may not have been; check the mly_cam_sim array to be certain.
1997      */
1998     sc->mly_cam_channels = sc->mly_controllerinfo->physical_channels_present +
1999 	sc->mly_controllerinfo->virtual_channels_present;
2000 
2001     return(0);
2002 }
2003 
2004 /********************************************************************************
2005  * Detach from CAM
2006  */
2007 static void
mly_cam_detach(struct mly_softc * sc)2008 mly_cam_detach(struct mly_softc *sc)
2009 {
2010     int		i;
2011 
2012     debug_called(1);
2013 
2014     MLY_LOCK(sc);
2015     for (i = 0; i < sc->mly_cam_channels; i++) {
2016 	if (sc->mly_cam_sim[i] != NULL) {
2017 	    xpt_bus_deregister(cam_sim_path(sc->mly_cam_sim[i]));
2018 	    cam_sim_free(sc->mly_cam_sim[i], 0);
2019 	}
2020     }
2021     MLY_UNLOCK(sc);
2022     if (sc->mly_cam_devq != NULL)
2023 	cam_simq_free(sc->mly_cam_devq);
2024 }
2025 
2026 /************************************************************************
2027  * Rescan a device.
2028  */
2029 static void
mly_cam_rescan_btl(struct mly_softc * sc,int bus,int target)2030 mly_cam_rescan_btl(struct mly_softc *sc, int bus, int target)
2031 {
2032     union ccb	*ccb;
2033 
2034     debug_called(1);
2035 
2036     if ((ccb = xpt_alloc_ccb()) == NULL) {
2037 	mly_printf(sc, "rescan failed (can't allocate CCB)\n");
2038 	return;
2039     }
2040     if (xpt_create_path(&ccb->ccb_h.path, NULL,
2041 	    cam_sim_path(sc->mly_cam_sim[bus]), target, 0) != CAM_REQ_CMP) {
2042 	mly_printf(sc, "rescan failed (can't create path)\n");
2043 	xpt_free_ccb(ccb);
2044 	return;
2045     }
2046     debug(1, "rescan target %d:%d", bus, target);
2047     xpt_rescan(ccb);
2048 }
2049 
2050 /********************************************************************************
2051  * Handle an action requested by CAM
2052  */
2053 static void
mly_cam_action(struct cam_sim * sim,union ccb * ccb)2054 mly_cam_action(struct cam_sim *sim, union ccb *ccb)
2055 {
2056     struct mly_softc	*sc = cam_sim_softc(sim);
2057 
2058     debug_called(2);
2059     MLY_ASSERT_LOCKED(sc);
2060 
2061     switch (ccb->ccb_h.func_code) {
2062 	/* perform SCSI I/O */
2063     case XPT_SCSI_IO:
2064 	if (!mly_cam_action_io(sim, (struct ccb_scsiio *)&ccb->csio))
2065 	    return;
2066 	break;
2067 
2068 	/* perform geometry calculations */
2069     case XPT_CALC_GEOMETRY:
2070     {
2071 	struct ccb_calc_geometry	*ccg = &ccb->ccg;
2072         u_int32_t			secs_per_cylinder;
2073 
2074 	debug(2, "XPT_CALC_GEOMETRY %d:%d:%d", cam_sim_bus(sim), ccb->ccb_h.target_id, ccb->ccb_h.target_lun);
2075 
2076 	if (sc->mly_controllerparam->bios_geometry == MLY_BIOSGEOM_8G) {
2077 	    ccg->heads = 255;
2078             ccg->secs_per_track = 63;
2079 	} else {				/* MLY_BIOSGEOM_2G */
2080 	    ccg->heads = 128;
2081             ccg->secs_per_track = 32;
2082 	}
2083 	secs_per_cylinder = ccg->heads * ccg->secs_per_track;
2084         ccg->cylinders = ccg->volume_size / secs_per_cylinder;
2085         ccb->ccb_h.status = CAM_REQ_CMP;
2086         break;
2087     }
2088 
2089 	/* handle path attribute inquiry */
2090     case XPT_PATH_INQ:
2091     {
2092 	struct ccb_pathinq	*cpi = &ccb->cpi;
2093 
2094 	debug(2, "XPT_PATH_INQ %d:%d:%d", cam_sim_bus(sim), ccb->ccb_h.target_id, ccb->ccb_h.target_lun);
2095 
2096 	cpi->version_num = 1;
2097 	cpi->hba_inquiry = PI_TAG_ABLE;		/* XXX extra flags for physical channels? */
2098 	cpi->target_sprt = 0;
2099 	cpi->hba_misc = 0;
2100 	cpi->max_target = MLY_MAX_TARGETS - 1;
2101 	cpi->max_lun = MLY_MAX_LUNS - 1;
2102 	cpi->initiator_id = sc->mly_controllerparam->initiator_id;
2103 	strlcpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
2104 	strlcpy(cpi->hba_vid, "Mylex", HBA_IDLEN);
2105 	strlcpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
2106 	cpi->unit_number = cam_sim_unit(sim);
2107 	cpi->bus_id = cam_sim_bus(sim);
2108 	cpi->base_transfer_speed = 132 * 1024;	/* XXX what to set this to? */
2109 	cpi->transport = XPORT_SPI;
2110 	cpi->transport_version = 2;
2111 	cpi->protocol = PROTO_SCSI;
2112 	cpi->protocol_version = SCSI_REV_2;
2113 	ccb->ccb_h.status = CAM_REQ_CMP;
2114 	break;
2115     }
2116 
2117     case XPT_GET_TRAN_SETTINGS:
2118     {
2119 	struct ccb_trans_settings	*cts = &ccb->cts;
2120 	int				bus, target;
2121 	struct ccb_trans_settings_scsi *scsi = &cts->proto_specific.scsi;
2122 	struct ccb_trans_settings_spi *spi = &cts->xport_specific.spi;
2123 
2124 	cts->protocol = PROTO_SCSI;
2125 	cts->protocol_version = SCSI_REV_2;
2126 	cts->transport = XPORT_SPI;
2127 	cts->transport_version = 2;
2128 
2129 	scsi->flags = 0;
2130 	scsi->valid = 0;
2131 	spi->flags = 0;
2132 	spi->valid = 0;
2133 
2134 	bus = cam_sim_bus(sim);
2135 	target = cts->ccb_h.target_id;
2136 	debug(2, "XPT_GET_TRAN_SETTINGS %d:%d", bus, target);
2137 	/* logical device? */
2138 	if (sc->mly_btl[bus][target].mb_flags & MLY_BTL_LOGICAL) {
2139 	    /* nothing special for these */
2140 	/* physical device? */
2141 	} else if (sc->mly_btl[bus][target].mb_flags & MLY_BTL_PHYSICAL) {
2142 	    /* allow CAM to try tagged transactions */
2143 	    scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
2144 	    scsi->valid |= CTS_SCSI_VALID_TQ;
2145 
2146 	    /* convert speed (MHz) to usec */
2147 	    if (sc->mly_btl[bus][target].mb_speed == 0) {
2148 		spi->sync_period = 1000000 / 5;
2149 	    } else {
2150 		spi->sync_period = 1000000 / sc->mly_btl[bus][target].mb_speed;
2151 	    }
2152 
2153 	    /* convert bus width to CAM internal encoding */
2154 	    switch (sc->mly_btl[bus][target].mb_width) {
2155 	    case 32:
2156 		spi->bus_width = MSG_EXT_WDTR_BUS_32_BIT;
2157 		break;
2158 	    case 16:
2159 		spi->bus_width = MSG_EXT_WDTR_BUS_16_BIT;
2160 		break;
2161 	    case 8:
2162 	    default:
2163 		spi->bus_width = MSG_EXT_WDTR_BUS_8_BIT;
2164 		break;
2165 	    }
2166 	    spi->valid |= CTS_SPI_VALID_SYNC_RATE | CTS_SPI_VALID_BUS_WIDTH;
2167 
2168 	    /* not a device, bail out */
2169 	} else {
2170 	    cts->ccb_h.status = CAM_REQ_CMP_ERR;
2171 	    break;
2172 	}
2173 
2174 	/* disconnect always OK */
2175 	spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
2176 	spi->valid |= CTS_SPI_VALID_DISC;
2177 
2178 	cts->ccb_h.status = CAM_REQ_CMP;
2179 	break;
2180     }
2181 
2182     default:		/* we can't do this */
2183 	debug(2, "unspported func_code = 0x%x", ccb->ccb_h.func_code);
2184 	ccb->ccb_h.status = CAM_REQ_INVALID;
2185 	break;
2186     }
2187 
2188     xpt_done(ccb);
2189 }
2190 
2191 /********************************************************************************
2192  * Handle an I/O operation requested by CAM
2193  */
2194 static int
mly_cam_action_io(struct cam_sim * sim,struct ccb_scsiio * csio)2195 mly_cam_action_io(struct cam_sim *sim, struct ccb_scsiio *csio)
2196 {
2197     struct mly_softc			*sc = cam_sim_softc(sim);
2198     struct mly_command			*mc;
2199     struct mly_command_scsi_small	*ss;
2200     int					bus, target;
2201     int					error;
2202 
2203     bus = cam_sim_bus(sim);
2204     target = csio->ccb_h.target_id;
2205 
2206     debug(2, "XPT_SCSI_IO %d:%d:%d", bus, target, csio->ccb_h.target_lun);
2207 
2208     /* validate bus number */
2209     if (!MLY_BUS_IS_VALID(sc, bus)) {
2210 	debug(0, " invalid bus %d", bus);
2211 	csio->ccb_h.status = CAM_REQ_CMP_ERR;
2212     }
2213 
2214     /*  check for I/O attempt to a protected device */
2215     if (sc->mly_btl[bus][target].mb_flags & MLY_BTL_PROTECTED) {
2216 	debug(2, "  device protected");
2217 	csio->ccb_h.status = CAM_REQ_CMP_ERR;
2218     }
2219 
2220     /* check for I/O attempt to nonexistent device */
2221     if (!(sc->mly_btl[bus][target].mb_flags & (MLY_BTL_LOGICAL | MLY_BTL_PHYSICAL))) {
2222 	debug(2, "  device %d:%d does not exist", bus, target);
2223 	csio->ccb_h.status = CAM_REQ_CMP_ERR;
2224     }
2225 
2226     /* XXX increase if/when we support large SCSI commands */
2227     if (csio->cdb_len > MLY_CMD_SCSI_SMALL_CDB) {
2228 	debug(0, "  command too large (%d > %d)", csio->cdb_len, MLY_CMD_SCSI_SMALL_CDB);
2229 	csio->ccb_h.status = CAM_REQ_CMP_ERR;
2230     }
2231 
2232     /* check that the CDB pointer is not to a physical address */
2233     if ((csio->ccb_h.flags & CAM_CDB_POINTER) && (csio->ccb_h.flags & CAM_CDB_PHYS)) {
2234 	debug(0, "  CDB pointer is to physical address");
2235 	csio->ccb_h.status = CAM_REQ_CMP_ERR;
2236     }
2237 
2238     /* abandon aborted ccbs or those that have failed validation */
2239     if ((csio->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_INPROG) {
2240 	debug(2, "abandoning CCB due to abort/validation failure");
2241 	return(EINVAL);
2242     }
2243 
2244     /*
2245      * Get a command, or push the ccb back to CAM and freeze the queue.
2246      */
2247     if ((error = mly_alloc_command(sc, &mc))) {
2248 	xpt_freeze_simq(sim, 1);
2249 	csio->ccb_h.status |= CAM_REQUEUE_REQ;
2250 	sc->mly_qfrzn_cnt++;
2251 	return(error);
2252     }
2253 
2254     /* build the command */
2255     mc->mc_data = csio;
2256     mc->mc_length = csio->dxfer_len;
2257     mc->mc_complete = mly_cam_complete;
2258     mc->mc_private = csio;
2259     mc->mc_flags |= MLY_CMD_CCB;
2260     /* XXX This code doesn't set the data direction in mc_flags. */
2261 
2262     /* save the bus number in the ccb for later recovery XXX should be a better way */
2263      csio->ccb_h.sim_priv.entries[0].field = bus;
2264 
2265     /* build the packet for the controller */
2266     ss = &mc->mc_packet->scsi_small;
2267     ss->opcode = MDACMD_SCSI;
2268     if (csio->ccb_h.flags & CAM_DIS_DISCONNECT)
2269 	ss->command_control.disable_disconnect = 1;
2270     if ((csio->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT)
2271 	ss->command_control.data_direction = MLY_CCB_WRITE;
2272     ss->data_size = csio->dxfer_len;
2273     ss->addr.phys.lun = csio->ccb_h.target_lun;
2274     ss->addr.phys.target = csio->ccb_h.target_id;
2275     ss->addr.phys.channel = bus;
2276     if (csio->ccb_h.timeout < (60 * 1000)) {
2277 	ss->timeout.value = csio->ccb_h.timeout / 1000;
2278 	ss->timeout.scale = MLY_TIMEOUT_SECONDS;
2279     } else if (csio->ccb_h.timeout < (60 * 60 * 1000)) {
2280 	ss->timeout.value = csio->ccb_h.timeout / (60 * 1000);
2281 	ss->timeout.scale = MLY_TIMEOUT_MINUTES;
2282     } else {
2283 	ss->timeout.value = csio->ccb_h.timeout / (60 * 60 * 1000);	/* overflow? */
2284 	ss->timeout.scale = MLY_TIMEOUT_HOURS;
2285     }
2286     ss->maximum_sense_size = csio->sense_len;
2287     ss->cdb_length = csio->cdb_len;
2288     if (csio->ccb_h.flags & CAM_CDB_POINTER) {
2289 	bcopy(csio->cdb_io.cdb_ptr, ss->cdb, csio->cdb_len);
2290     } else {
2291 	bcopy(csio->cdb_io.cdb_bytes, ss->cdb, csio->cdb_len);
2292     }
2293 
2294     /* give the command to the controller */
2295     if ((error = mly_start(mc))) {
2296 	xpt_freeze_simq(sim, 1);
2297 	csio->ccb_h.status |= CAM_REQUEUE_REQ;
2298 	sc->mly_qfrzn_cnt++;
2299 	return(error);
2300     }
2301 
2302     return(0);
2303 }
2304 
2305 /********************************************************************************
2306  * Check for possibly-completed commands.
2307  */
2308 static void
mly_cam_poll(struct cam_sim * sim)2309 mly_cam_poll(struct cam_sim *sim)
2310 {
2311     struct mly_softc	*sc = cam_sim_softc(sim);
2312 
2313     debug_called(2);
2314 
2315     mly_done(sc);
2316 }
2317 
2318 /********************************************************************************
2319  * Handle completion of a command - pass results back through the CCB
2320  */
2321 static void
mly_cam_complete(struct mly_command * mc)2322 mly_cam_complete(struct mly_command *mc)
2323 {
2324     struct mly_softc		*sc = mc->mc_sc;
2325     struct ccb_scsiio		*csio = (struct ccb_scsiio *)mc->mc_private;
2326     struct scsi_inquiry_data	*inq = (struct scsi_inquiry_data *)csio->data_ptr;
2327     struct mly_btl		*btl;
2328     u_int8_t			cmd;
2329     int				bus, target;
2330 
2331     debug_called(2);
2332 
2333     csio->scsi_status = mc->mc_status;
2334     switch(mc->mc_status) {
2335     case SCSI_STATUS_OK:
2336 	/*
2337 	 * In order to report logical device type and status, we overwrite
2338 	 * the result of the INQUIRY command to logical devices.
2339 	 */
2340 	bus = csio->ccb_h.sim_priv.entries[0].field;
2341 	target = csio->ccb_h.target_id;
2342 	/* XXX validate bus/target? */
2343 	if (sc->mly_btl[bus][target].mb_flags & MLY_BTL_LOGICAL) {
2344 	    if (csio->ccb_h.flags & CAM_CDB_POINTER) {
2345 		cmd = *csio->cdb_io.cdb_ptr;
2346 	    } else {
2347 		cmd = csio->cdb_io.cdb_bytes[0];
2348 	    }
2349 	    if (cmd == INQUIRY) {
2350 		btl = &sc->mly_btl[bus][target];
2351 		padstr(inq->vendor, mly_describe_code(mly_table_device_type, btl->mb_type), 8);
2352 		padstr(inq->product, mly_describe_code(mly_table_device_state, btl->mb_state), 16);
2353 		padstr(inq->revision, "", 4);
2354 	    }
2355 	}
2356 
2357 	debug(2, "SCSI_STATUS_OK");
2358 	csio->ccb_h.status = CAM_REQ_CMP;
2359 	break;
2360 
2361     case SCSI_STATUS_CHECK_COND:
2362 	debug(1, "SCSI_STATUS_CHECK_COND  sense %d  resid %d", mc->mc_sense, mc->mc_resid);
2363 	csio->ccb_h.status = CAM_SCSI_STATUS_ERROR;
2364 	bzero(&csio->sense_data, SSD_FULL_SIZE);
2365 	bcopy(mc->mc_packet, &csio->sense_data, mc->mc_sense);
2366 	csio->sense_len = mc->mc_sense;
2367 	csio->ccb_h.status |= CAM_AUTOSNS_VALID;
2368 	csio->resid = mc->mc_resid;	/* XXX this is a signed value... */
2369 	break;
2370 
2371     case SCSI_STATUS_BUSY:
2372 	debug(1, "SCSI_STATUS_BUSY");
2373 	csio->ccb_h.status = CAM_SCSI_BUSY;
2374 	break;
2375 
2376     default:
2377 	debug(1, "unknown status 0x%x", csio->scsi_status);
2378 	csio->ccb_h.status = CAM_REQ_CMP_ERR;
2379 	break;
2380     }
2381 
2382     if (sc->mly_qfrzn_cnt) {
2383 	csio->ccb_h.status |= CAM_RELEASE_SIMQ;
2384 	sc->mly_qfrzn_cnt--;
2385     }
2386 
2387     xpt_done((union ccb *)csio);
2388     mly_release_command(mc);
2389 }
2390 
2391 /********************************************************************************
2392  * Find a peripheral attahed at (bus),(target)
2393  */
2394 static struct cam_periph *
mly_find_periph(struct mly_softc * sc,int bus,int target)2395 mly_find_periph(struct mly_softc *sc, int bus, int target)
2396 {
2397     struct cam_periph	*periph;
2398     struct cam_path	*path;
2399     int			status;
2400 
2401     status = xpt_create_path(&path, NULL, cam_sim_path(sc->mly_cam_sim[bus]), target, 0);
2402     if (status == CAM_REQ_CMP) {
2403 	periph = cam_periph_find(path, NULL);
2404 	xpt_free_path(path);
2405     } else {
2406 	periph = NULL;
2407     }
2408     return(periph);
2409 }
2410 
2411 /********************************************************************************
2412  * Name the device at (bus)(target)
2413  */
2414 static int
mly_name_device(struct mly_softc * sc,int bus,int target)2415 mly_name_device(struct mly_softc *sc, int bus, int target)
2416 {
2417     struct cam_periph	*periph;
2418 
2419     if ((periph = mly_find_periph(sc, bus, target)) != NULL) {
2420 	sprintf(sc->mly_btl[bus][target].mb_name, "%s%d", periph->periph_name, periph->unit_number);
2421 	return(0);
2422     }
2423     sc->mly_btl[bus][target].mb_name[0] = 0;
2424     return(ENOENT);
2425 }
2426 
2427 /********************************************************************************
2428  ********************************************************************************
2429                                                                  Hardware Control
2430  ********************************************************************************
2431  ********************************************************************************/
2432 
2433 /********************************************************************************
2434  * Handshake with the firmware while the card is being initialised.
2435  */
2436 static int
mly_fwhandshake(struct mly_softc * sc)2437 mly_fwhandshake(struct mly_softc *sc)
2438 {
2439     u_int8_t	error, param0, param1;
2440     int		spinup = 0;
2441 
2442     debug_called(1);
2443 
2444     /* set HM_STSACK and let the firmware initialise */
2445     MLY_SET_REG(sc, sc->mly_idbr, MLY_HM_STSACK);
2446     DELAY(1000);	/* too short? */
2447 
2448     /* if HM_STSACK is still true, the controller is initialising */
2449     if (!MLY_IDBR_TRUE(sc, MLY_HM_STSACK))
2450 	return(0);
2451     mly_printf(sc, "controller initialisation started\n");
2452 
2453     /* spin waiting for initialisation to finish, or for a message to be delivered */
2454     while (MLY_IDBR_TRUE(sc, MLY_HM_STSACK)) {
2455 	/* check for a message */
2456 	if (MLY_ERROR_VALID(sc)) {
2457 	    error = MLY_GET_REG(sc, sc->mly_error_status) & ~MLY_MSG_EMPTY;
2458 	    param0 = MLY_GET_REG(sc, sc->mly_command_mailbox);
2459 	    param1 = MLY_GET_REG(sc, sc->mly_command_mailbox + 1);
2460 
2461 	    switch(error) {
2462 	    case MLY_MSG_SPINUP:
2463 		if (!spinup) {
2464 		    mly_printf(sc, "drive spinup in progress\n");
2465 		    spinup = 1;			/* only print this once (should print drive being spun?) */
2466 		}
2467 		break;
2468 	    case MLY_MSG_RACE_RECOVERY_FAIL:
2469 		mly_printf(sc, "mirror race recovery failed, one or more drives offline\n");
2470 		break;
2471 	    case MLY_MSG_RACE_IN_PROGRESS:
2472 		mly_printf(sc, "mirror race recovery in progress\n");
2473 		break;
2474 	    case MLY_MSG_RACE_ON_CRITICAL:
2475 		mly_printf(sc, "mirror race recovery on a critical drive\n");
2476 		break;
2477 	    case MLY_MSG_PARITY_ERROR:
2478 		mly_printf(sc, "FATAL MEMORY PARITY ERROR\n");
2479 		return(ENXIO);
2480 	    default:
2481 		mly_printf(sc, "unknown initialisation code 0x%x\n", error);
2482 	    }
2483 	}
2484     }
2485     return(0);
2486 }
2487 
2488 /********************************************************************************
2489  ********************************************************************************
2490                                                         Debugging and Diagnostics
2491  ********************************************************************************
2492  ********************************************************************************/
2493 
2494 /********************************************************************************
2495  * Print some information about the controller.
2496  */
2497 static void
mly_describe_controller(struct mly_softc * sc)2498 mly_describe_controller(struct mly_softc *sc)
2499 {
2500     struct mly_ioctl_getcontrollerinfo	*mi = sc->mly_controllerinfo;
2501 
2502     mly_printf(sc, "%16s, %d channel%s, firmware %d.%02d-%d-%02d (%02d%02d%02d%02d), %dMB RAM\n",
2503 	       mi->controller_name, mi->physical_channels_present, (mi->physical_channels_present) > 1 ? "s" : "",
2504 	       mi->fw_major, mi->fw_minor, mi->fw_turn, mi->fw_build,	/* XXX turn encoding? */
2505 	       mi->fw_century, mi->fw_year, mi->fw_month, mi->fw_day,
2506 	       mi->memory_size);
2507 
2508     if (bootverbose) {
2509 	mly_printf(sc, "%s %s (%x), %dMHz %d-bit %.16s\n",
2510 		   mly_describe_code(mly_table_oemname, mi->oem_information),
2511 		   mly_describe_code(mly_table_controllertype, mi->controller_type), mi->controller_type,
2512 		   mi->interface_speed, mi->interface_width, mi->interface_name);
2513 	mly_printf(sc, "%dMB %dMHz %d-bit %s%s%s, cache %dMB\n",
2514 		   mi->memory_size, mi->memory_speed, mi->memory_width,
2515 		   mly_describe_code(mly_table_memorytype, mi->memory_type),
2516 		   mi->memory_parity ? "+parity": "",mi->memory_ecc ? "+ECC": "",
2517 		   mi->cache_size);
2518 	mly_printf(sc, "CPU: %s @ %dMHz\n",
2519 		   mly_describe_code(mly_table_cputype, mi->cpu[0].type), mi->cpu[0].speed);
2520 	if (mi->l2cache_size != 0)
2521 	    mly_printf(sc, "%dKB L2 cache\n", mi->l2cache_size);
2522 	if (mi->exmemory_size != 0)
2523 	    mly_printf(sc, "%dMB %dMHz %d-bit private %s%s%s\n",
2524 		       mi->exmemory_size, mi->exmemory_speed, mi->exmemory_width,
2525 		       mly_describe_code(mly_table_memorytype, mi->exmemory_type),
2526 		       mi->exmemory_parity ? "+parity": "",mi->exmemory_ecc ? "+ECC": "");
2527 	mly_printf(sc, "battery backup %s\n", mi->bbu_present ? "present" : "not installed");
2528 	mly_printf(sc, "maximum data transfer %d blocks, maximum sg entries/command %d\n",
2529 		   mi->maximum_block_count, mi->maximum_sg_entries);
2530 	mly_printf(sc, "logical devices present/critical/offline %d/%d/%d\n",
2531 		   mi->logical_devices_present, mi->logical_devices_critical, mi->logical_devices_offline);
2532 	mly_printf(sc, "physical devices present %d\n",
2533 		   mi->physical_devices_present);
2534 	mly_printf(sc, "physical disks present/offline %d/%d\n",
2535 		   mi->physical_disks_present, mi->physical_disks_offline);
2536 	mly_printf(sc, "%d physical channel%s, %d virtual channel%s of %d possible\n",
2537 		   mi->physical_channels_present, mi->physical_channels_present == 1 ? "" : "s",
2538 		   mi->virtual_channels_present, mi->virtual_channels_present == 1 ? "" : "s",
2539 		   mi->virtual_channels_possible);
2540 	mly_printf(sc, "%d parallel commands supported\n", mi->maximum_parallel_commands);
2541 	mly_printf(sc, "%dMB flash ROM, %d of %d maximum cycles\n",
2542 		   mi->flash_size, mi->flash_age, mi->flash_maximum_age);
2543     }
2544 }
2545 
2546 #ifdef MLY_DEBUG
2547 /********************************************************************************
2548  * Print some controller state
2549  */
2550 static void
mly_printstate(struct mly_softc * sc)2551 mly_printstate(struct mly_softc *sc)
2552 {
2553     mly_printf(sc, "IDBR %02x  ODBR %02x  ERROR %02x  (%x %x %x)\n",
2554 		  MLY_GET_REG(sc, sc->mly_idbr),
2555 		  MLY_GET_REG(sc, sc->mly_odbr),
2556 		  MLY_GET_REG(sc, sc->mly_error_status),
2557 		  sc->mly_idbr,
2558 		  sc->mly_odbr,
2559 		  sc->mly_error_status);
2560     mly_printf(sc, "IMASK %02x  ISTATUS %02x\n",
2561 		  MLY_GET_REG(sc, sc->mly_interrupt_mask),
2562 		  MLY_GET_REG(sc, sc->mly_interrupt_status));
2563     mly_printf(sc, "COMMAND %02x %02x %02x %02x %02x %02x %02x %02x\n",
2564 		  MLY_GET_REG(sc, sc->mly_command_mailbox),
2565 		  MLY_GET_REG(sc, sc->mly_command_mailbox + 1),
2566 		  MLY_GET_REG(sc, sc->mly_command_mailbox + 2),
2567 		  MLY_GET_REG(sc, sc->mly_command_mailbox + 3),
2568 		  MLY_GET_REG(sc, sc->mly_command_mailbox + 4),
2569 		  MLY_GET_REG(sc, sc->mly_command_mailbox + 5),
2570 		  MLY_GET_REG(sc, sc->mly_command_mailbox + 6),
2571 		  MLY_GET_REG(sc, sc->mly_command_mailbox + 7));
2572     mly_printf(sc, "STATUS  %02x %02x %02x %02x %02x %02x %02x %02x\n",
2573 		  MLY_GET_REG(sc, sc->mly_status_mailbox),
2574 		  MLY_GET_REG(sc, sc->mly_status_mailbox + 1),
2575 		  MLY_GET_REG(sc, sc->mly_status_mailbox + 2),
2576 		  MLY_GET_REG(sc, sc->mly_status_mailbox + 3),
2577 		  MLY_GET_REG(sc, sc->mly_status_mailbox + 4),
2578 		  MLY_GET_REG(sc, sc->mly_status_mailbox + 5),
2579 		  MLY_GET_REG(sc, sc->mly_status_mailbox + 6),
2580 		  MLY_GET_REG(sc, sc->mly_status_mailbox + 7));
2581     mly_printf(sc, "        %04x        %08x\n",
2582 		  MLY_GET_REG2(sc, sc->mly_status_mailbox),
2583 		  MLY_GET_REG4(sc, sc->mly_status_mailbox + 4));
2584 }
2585 
2586 struct mly_softc	*mly_softc0 = NULL;
2587 void
mly_printstate0(void)2588 mly_printstate0(void)
2589 {
2590     if (mly_softc0 != NULL)
2591 	mly_printstate(mly_softc0);
2592 }
2593 
2594 /********************************************************************************
2595  * Print a command
2596  */
2597 static void
mly_print_command(struct mly_command * mc)2598 mly_print_command(struct mly_command *mc)
2599 {
2600     struct mly_softc	*sc = mc->mc_sc;
2601 
2602     mly_printf(sc, "COMMAND @ %p\n", mc);
2603     mly_printf(sc, "  slot      %d\n", mc->mc_slot);
2604     mly_printf(sc, "  status    0x%x\n", mc->mc_status);
2605     mly_printf(sc, "  sense len %d\n", mc->mc_sense);
2606     mly_printf(sc, "  resid     %d\n", mc->mc_resid);
2607     mly_printf(sc, "  packet    %p/0x%llx\n", mc->mc_packet, mc->mc_packetphys);
2608     if (mc->mc_packet != NULL)
2609 	mly_print_packet(mc);
2610     mly_printf(sc, "  data      %p/%d\n", mc->mc_data, mc->mc_length);
2611     mly_printf(sc, "  flags     %b\n", mc->mc_flags, "\20\1busy\2complete\3slotted\4mapped\5datain\6dataout\n");
2612     mly_printf(sc, "  complete  %p\n", mc->mc_complete);
2613     mly_printf(sc, "  private   %p\n", mc->mc_private);
2614 }
2615 
2616 /********************************************************************************
2617  * Print a command packet
2618  */
2619 static void
mly_print_packet(struct mly_command * mc)2620 mly_print_packet(struct mly_command *mc)
2621 {
2622     struct mly_softc			*sc = mc->mc_sc;
2623     struct mly_command_generic		*ge = (struct mly_command_generic *)mc->mc_packet;
2624     struct mly_command_scsi_small	*ss = (struct mly_command_scsi_small *)mc->mc_packet;
2625     struct mly_command_scsi_large	*sl = (struct mly_command_scsi_large *)mc->mc_packet;
2626     struct mly_command_ioctl		*io = (struct mly_command_ioctl *)mc->mc_packet;
2627     int					transfer;
2628 
2629     mly_printf(sc, "   command_id           %d\n", ge->command_id);
2630     mly_printf(sc, "   opcode               %d\n", ge->opcode);
2631     mly_printf(sc, "   command_control      fua %d  dpo %d  est %d  dd %s  nas %d ddis %d\n",
2632 		  ge->command_control.force_unit_access,
2633 		  ge->command_control.disable_page_out,
2634 		  ge->command_control.extended_sg_table,
2635 		  (ge->command_control.data_direction == MLY_CCB_WRITE) ? "WRITE" : "READ",
2636 		  ge->command_control.no_auto_sense,
2637 		  ge->command_control.disable_disconnect);
2638     mly_printf(sc, "   data_size            %d\n", ge->data_size);
2639     mly_printf(sc, "   sense_buffer_address 0x%llx\n", ge->sense_buffer_address);
2640     mly_printf(sc, "   lun                  %d\n", ge->addr.phys.lun);
2641     mly_printf(sc, "   target               %d\n", ge->addr.phys.target);
2642     mly_printf(sc, "   channel              %d\n", ge->addr.phys.channel);
2643     mly_printf(sc, "   logical device       %d\n", ge->addr.log.logdev);
2644     mly_printf(sc, "   controller           %d\n", ge->addr.phys.controller);
2645     mly_printf(sc, "   timeout              %d %s\n",
2646 		  ge->timeout.value,
2647 		  (ge->timeout.scale == MLY_TIMEOUT_SECONDS) ? "seconds" :
2648 		  ((ge->timeout.scale == MLY_TIMEOUT_MINUTES) ? "minutes" : "hours"));
2649     mly_printf(sc, "   maximum_sense_size   %d\n", ge->maximum_sense_size);
2650     switch(ge->opcode) {
2651     case MDACMD_SCSIPT:
2652     case MDACMD_SCSI:
2653 	mly_printf(sc, "   cdb length           %d\n", ss->cdb_length);
2654 	mly_printf(sc, "   cdb                  %*D\n", ss->cdb_length, ss->cdb, " ");
2655 	transfer = 1;
2656 	break;
2657     case MDACMD_SCSILC:
2658     case MDACMD_SCSILCPT:
2659 	mly_printf(sc, "   cdb length           %d\n", sl->cdb_length);
2660 	mly_printf(sc, "   cdb                  0x%llx\n", sl->cdb_physaddr);
2661 	transfer = 1;
2662 	break;
2663     case MDACMD_IOCTL:
2664 	mly_printf(sc, "   sub_ioctl            0x%x\n", io->sub_ioctl);
2665 	switch(io->sub_ioctl) {
2666 	case MDACIOCTL_SETMEMORYMAILBOX:
2667 	    mly_printf(sc, "   health_buffer_size   %d\n",
2668 			  io->param.setmemorymailbox.health_buffer_size);
2669 	    mly_printf(sc, "   health_buffer_phys   0x%llx\n",
2670 			  io->param.setmemorymailbox.health_buffer_physaddr);
2671 	    mly_printf(sc, "   command_mailbox      0x%llx\n",
2672 			  io->param.setmemorymailbox.command_mailbox_physaddr);
2673 	    mly_printf(sc, "   status_mailbox       0x%llx\n",
2674 			  io->param.setmemorymailbox.status_mailbox_physaddr);
2675 	    transfer = 0;
2676 	    break;
2677 
2678 	case MDACIOCTL_SETREALTIMECLOCK:
2679 	case MDACIOCTL_GETHEALTHSTATUS:
2680 	case MDACIOCTL_GETCONTROLLERINFO:
2681 	case MDACIOCTL_GETLOGDEVINFOVALID:
2682 	case MDACIOCTL_GETPHYSDEVINFOVALID:
2683 	case MDACIOCTL_GETPHYSDEVSTATISTICS:
2684 	case MDACIOCTL_GETLOGDEVSTATISTICS:
2685 	case MDACIOCTL_GETCONTROLLERSTATISTICS:
2686 	case MDACIOCTL_GETBDT_FOR_SYSDRIVE:
2687 	case MDACIOCTL_CREATENEWCONF:
2688 	case MDACIOCTL_ADDNEWCONF:
2689 	case MDACIOCTL_GETDEVCONFINFO:
2690 	case MDACIOCTL_GETFREESPACELIST:
2691 	case MDACIOCTL_MORE:
2692 	case MDACIOCTL_SETPHYSDEVPARAMETER:
2693 	case MDACIOCTL_GETPHYSDEVPARAMETER:
2694 	case MDACIOCTL_GETLOGDEVPARAMETER:
2695 	case MDACIOCTL_SETLOGDEVPARAMETER:
2696 	    mly_printf(sc, "   param                %10D\n", io->param.data.param, " ");
2697 	    transfer = 1;
2698 	    break;
2699 
2700 	case MDACIOCTL_GETEVENT:
2701 	    mly_printf(sc, "   event                %d\n",
2702 		       io->param.getevent.sequence_number_low + ((u_int32_t)io->addr.log.logdev << 16));
2703 	    transfer = 1;
2704 	    break;
2705 
2706 	case MDACIOCTL_SETRAIDDEVSTATE:
2707 	    mly_printf(sc, "   state                %d\n", io->param.setraiddevstate.state);
2708 	    transfer = 0;
2709 	    break;
2710 
2711 	case MDACIOCTL_XLATEPHYSDEVTORAIDDEV:
2712 	    mly_printf(sc, "   raid_device          %d\n", io->param.xlatephysdevtoraiddev.raid_device);
2713 	    mly_printf(sc, "   controller           %d\n", io->param.xlatephysdevtoraiddev.controller);
2714 	    mly_printf(sc, "   channel              %d\n", io->param.xlatephysdevtoraiddev.channel);
2715 	    mly_printf(sc, "   target               %d\n", io->param.xlatephysdevtoraiddev.target);
2716 	    mly_printf(sc, "   lun                  %d\n", io->param.xlatephysdevtoraiddev.lun);
2717 	    transfer = 0;
2718 	    break;
2719 
2720 	case MDACIOCTL_GETGROUPCONFINFO:
2721 	    mly_printf(sc, "   group                %d\n", io->param.getgroupconfinfo.group);
2722 	    transfer = 1;
2723 	    break;
2724 
2725 	case MDACIOCTL_GET_SUBSYSTEM_DATA:
2726 	case MDACIOCTL_SET_SUBSYSTEM_DATA:
2727 	case MDACIOCTL_STARTDISOCVERY:
2728 	case MDACIOCTL_INITPHYSDEVSTART:
2729 	case MDACIOCTL_INITPHYSDEVSTOP:
2730 	case MDACIOCTL_INITRAIDDEVSTART:
2731 	case MDACIOCTL_INITRAIDDEVSTOP:
2732 	case MDACIOCTL_REBUILDRAIDDEVSTART:
2733 	case MDACIOCTL_REBUILDRAIDDEVSTOP:
2734 	case MDACIOCTL_MAKECONSISTENTDATASTART:
2735 	case MDACIOCTL_MAKECONSISTENTDATASTOP:
2736 	case MDACIOCTL_CONSISTENCYCHECKSTART:
2737 	case MDACIOCTL_CONSISTENCYCHECKSTOP:
2738 	case MDACIOCTL_RESETDEVICE:
2739 	case MDACIOCTL_FLUSHDEVICEDATA:
2740 	case MDACIOCTL_PAUSEDEVICE:
2741 	case MDACIOCTL_UNPAUSEDEVICE:
2742 	case MDACIOCTL_LOCATEDEVICE:
2743 	case MDACIOCTL_SETMASTERSLAVEMODE:
2744 	case MDACIOCTL_DELETERAIDDEV:
2745 	case MDACIOCTL_REPLACEINTERNALDEV:
2746 	case MDACIOCTL_CLEARCONF:
2747 	case MDACIOCTL_GETCONTROLLERPARAMETER:
2748 	case MDACIOCTL_SETCONTRLLERPARAMETER:
2749 	case MDACIOCTL_CLEARCONFSUSPMODE:
2750 	case MDACIOCTL_STOREIMAGE:
2751 	case MDACIOCTL_READIMAGE:
2752 	case MDACIOCTL_FLASHIMAGES:
2753 	case MDACIOCTL_RENAMERAIDDEV:
2754 	default:			/* no idea what to print */
2755 	    transfer = 0;
2756 	    break;
2757 	}
2758 	break;
2759 
2760     case MDACMD_IOCTLCHECK:
2761     case MDACMD_MEMCOPY:
2762     default:
2763 	transfer = 0;
2764 	break;	/* print nothing */
2765     }
2766     if (transfer) {
2767 	if (ge->command_control.extended_sg_table) {
2768 	    mly_printf(sc, "   sg table             0x%llx/%d\n",
2769 			  ge->transfer.indirect.table_physaddr[0], ge->transfer.indirect.entries[0]);
2770 	} else {
2771 	    mly_printf(sc, "   0000                 0x%llx/%lld\n",
2772 			  ge->transfer.direct.sg[0].physaddr, ge->transfer.direct.sg[0].length);
2773 	    mly_printf(sc, "   0001                 0x%llx/%lld\n",
2774 			  ge->transfer.direct.sg[1].physaddr, ge->transfer.direct.sg[1].length);
2775 	}
2776     }
2777 }
2778 
2779 /********************************************************************************
2780  * Panic in a slightly informative fashion
2781  */
2782 static void
mly_panic(struct mly_softc * sc,char * reason)2783 mly_panic(struct mly_softc *sc, char *reason)
2784 {
2785     mly_printstate(sc);
2786     panic(reason);
2787 }
2788 
2789 /********************************************************************************
2790  * Print queue statistics, callable from DDB.
2791  */
2792 void
mly_print_controller(int controller)2793 mly_print_controller(int controller)
2794 {
2795     struct mly_softc	*sc;
2796 
2797     if ((sc = devclass_get_softc(devclass_find("mly"), controller)) == NULL) {
2798 	printf("mly: controller %d invalid\n", controller);
2799     } else {
2800 	device_printf(sc->mly_dev, "queue    curr max\n");
2801 	device_printf(sc->mly_dev, "free     %04d/%04d\n",
2802 		      sc->mly_qstat[MLYQ_FREE].q_length, sc->mly_qstat[MLYQ_FREE].q_max);
2803 	device_printf(sc->mly_dev, "busy     %04d/%04d\n",
2804 		      sc->mly_qstat[MLYQ_BUSY].q_length, sc->mly_qstat[MLYQ_BUSY].q_max);
2805 	device_printf(sc->mly_dev, "complete %04d/%04d\n",
2806 		      sc->mly_qstat[MLYQ_COMPLETE].q_length, sc->mly_qstat[MLYQ_COMPLETE].q_max);
2807     }
2808 }
2809 #endif
2810 
2811 /********************************************************************************
2812  ********************************************************************************
2813                                                          Control device interface
2814  ********************************************************************************
2815  ********************************************************************************/
2816 
2817 /********************************************************************************
2818  * Accept an open operation on the control device.
2819  */
2820 static int
mly_user_open(struct cdev * dev,int flags,int fmt,struct thread * td)2821 mly_user_open(struct cdev *dev, int flags, int fmt, struct thread *td)
2822 {
2823     struct mly_softc	*sc = dev->si_drv1;
2824 
2825     MLY_LOCK(sc);
2826     sc->mly_state |= MLY_STATE_OPEN;
2827     MLY_UNLOCK(sc);
2828     return(0);
2829 }
2830 
2831 /********************************************************************************
2832  * Accept the last close on the control device.
2833  */
2834 static int
mly_user_close(struct cdev * dev,int flags,int fmt,struct thread * td)2835 mly_user_close(struct cdev *dev, int flags, int fmt, struct thread *td)
2836 {
2837     struct mly_softc	*sc = dev->si_drv1;
2838 
2839     MLY_LOCK(sc);
2840     sc->mly_state &= ~MLY_STATE_OPEN;
2841     MLY_UNLOCK(sc);
2842     return (0);
2843 }
2844 
2845 /********************************************************************************
2846  * Handle controller-specific control operations.
2847  */
2848 static int
mly_user_ioctl(struct cdev * dev,u_long cmd,caddr_t addr,int32_t flag,struct thread * td)2849 mly_user_ioctl(struct cdev *dev, u_long cmd, caddr_t addr,
2850 				int32_t flag, struct thread *td)
2851 {
2852     struct mly_softc		*sc = (struct mly_softc *)dev->si_drv1;
2853     struct mly_user_command	*uc = (struct mly_user_command *)addr;
2854     struct mly_user_health	*uh = (struct mly_user_health *)addr;
2855 
2856     switch(cmd) {
2857     case MLYIO_COMMAND:
2858 	return(mly_user_command(sc, uc));
2859     case MLYIO_HEALTH:
2860 	return(mly_user_health(sc, uh));
2861     default:
2862 	return(ENOIOCTL);
2863     }
2864 }
2865 
2866 /********************************************************************************
2867  * Execute a command passed in from userspace.
2868  *
2869  * The control structure contains the actual command for the controller, as well
2870  * as the user-space data pointer and data size, and an optional sense buffer
2871  * size/pointer.  On completion, the data size is adjusted to the command
2872  * residual, and the sense buffer size to the size of the returned sense data.
2873  *
2874  */
2875 static int
mly_user_command(struct mly_softc * sc,struct mly_user_command * uc)2876 mly_user_command(struct mly_softc *sc, struct mly_user_command *uc)
2877 {
2878     struct mly_command	*mc;
2879     int			error;
2880 
2881     /* allocate a command */
2882     MLY_LOCK(sc);
2883     if (mly_alloc_command(sc, &mc)) {
2884 	MLY_UNLOCK(sc);
2885 	return (ENOMEM);	/* XXX Linux version will wait for a command */
2886     }
2887     MLY_UNLOCK(sc);
2888 
2889     /* handle data size/direction */
2890     mc->mc_length = (uc->DataTransferLength >= 0) ? uc->DataTransferLength : -uc->DataTransferLength;
2891     if (mc->mc_length > 0) {
2892 	if ((mc->mc_data = malloc(mc->mc_length, M_DEVBUF, M_NOWAIT)) == NULL) {
2893 	    error = ENOMEM;
2894 	    goto out;
2895 	}
2896     }
2897     if (uc->DataTransferLength > 0) {
2898 	mc->mc_flags |= MLY_CMD_DATAIN;
2899 	bzero(mc->mc_data, mc->mc_length);
2900     }
2901     if (uc->DataTransferLength < 0) {
2902 	mc->mc_flags |= MLY_CMD_DATAOUT;
2903 	if ((error = copyin(uc->DataTransferBuffer, mc->mc_data, mc->mc_length)) != 0)
2904 	    goto out;
2905     }
2906 
2907     /* copy the controller command */
2908     bcopy(&uc->CommandMailbox, mc->mc_packet, sizeof(uc->CommandMailbox));
2909 
2910     /* clear command completion handler so that we get woken up */
2911     mc->mc_complete = NULL;
2912 
2913     /* execute the command */
2914     MLY_LOCK(sc);
2915     if ((error = mly_start(mc)) != 0) {
2916 	MLY_UNLOCK(sc);
2917 	goto out;
2918     }
2919     while (!(mc->mc_flags & MLY_CMD_COMPLETE))
2920 	mtx_sleep(mc, &sc->mly_lock, PRIBIO, "mlyioctl", 0);
2921     MLY_UNLOCK(sc);
2922 
2923     /* return the data to userspace */
2924     if (uc->DataTransferLength > 0)
2925 	if ((error = copyout(mc->mc_data, uc->DataTransferBuffer, mc->mc_length)) != 0)
2926 	    goto out;
2927 
2928     /* return the sense buffer to userspace */
2929     if ((uc->RequestSenseLength > 0) && (mc->mc_sense > 0)) {
2930 	if ((error = copyout(mc->mc_packet, uc->RequestSenseBuffer,
2931 			     min(uc->RequestSenseLength, mc->mc_sense))) != 0)
2932 	    goto out;
2933     }
2934 
2935     /* return command results to userspace (caller will copy out) */
2936     uc->DataTransferLength = mc->mc_resid;
2937     uc->RequestSenseLength = min(uc->RequestSenseLength, mc->mc_sense);
2938     uc->CommandStatus = mc->mc_status;
2939     error = 0;
2940 
2941  out:
2942     if (mc->mc_data != NULL)
2943 	free(mc->mc_data, M_DEVBUF);
2944     MLY_LOCK(sc);
2945     mly_release_command(mc);
2946     MLY_UNLOCK(sc);
2947     return(error);
2948 }
2949 
2950 /********************************************************************************
2951  * Return health status to userspace.  If the health change index in the user
2952  * structure does not match that currently exported by the controller, we
2953  * return the current status immediately.  Otherwise, we block until either
2954  * interrupted or new status is delivered.
2955  */
2956 static int
mly_user_health(struct mly_softc * sc,struct mly_user_health * uh)2957 mly_user_health(struct mly_softc *sc, struct mly_user_health *uh)
2958 {
2959     struct mly_health_status		mh;
2960     int					error;
2961 
2962     /* fetch the current health status from userspace */
2963     if ((error = copyin(uh->HealthStatusBuffer, &mh, sizeof(mh))) != 0)
2964 	return(error);
2965 
2966     /* spin waiting for a status update */
2967     MLY_LOCK(sc);
2968     error = EWOULDBLOCK;
2969     while ((error != 0) && (sc->mly_event_change == mh.change_counter))
2970 	error = mtx_sleep(&sc->mly_event_change, &sc->mly_lock, PRIBIO | PCATCH,
2971 	    "mlyhealth", 0);
2972     mh = sc->mly_mmbox->mmm_health.status;
2973     MLY_UNLOCK(sc);
2974 
2975     /* copy the controller's health status buffer out */
2976     error = copyout(&mh, uh->HealthStatusBuffer, sizeof(mh));
2977     return(error);
2978 }
2979 
2980 #ifdef MLY_DEBUG
2981 static void
mly_timeout(void * arg)2982 mly_timeout(void *arg)
2983 {
2984 	struct mly_softc *sc;
2985 	struct mly_command *mc;
2986 	int deadline;
2987 
2988 	sc = arg;
2989 	MLY_ASSERT_LOCKED(sc);
2990 	deadline = time_second - MLY_CMD_TIMEOUT;
2991 	TAILQ_FOREACH(mc, &sc->mly_busy, mc_link) {
2992 		if ((mc->mc_timestamp < deadline)) {
2993 			device_printf(sc->mly_dev,
2994 			    "COMMAND %p TIMEOUT AFTER %d SECONDS\n", mc,
2995 			    (int)(time_second - mc->mc_timestamp));
2996 		}
2997 	}
2998 
2999 	callout_reset(&sc->mly_timeout, MLY_CMD_TIMEOUT * hz, mly_timeout, sc);
3000 }
3001 #endif
3002