Deleted Added
full compact
amr.c (65245) amr.c (65763)
1/*-
2 * Copyright (c) 1999,2000 Michael Smith
3 * Copyright (c) 2000 BSDi
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
1/*-
2 * Copyright (c) 1999,2000 Michael Smith
3 * Copyright (c) 2000 BSDi
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
27 * $FreeBSD: head/sys/dev/amr/amr.c 65245 2000-08-30 07:52:50Z msmith $
27 * $FreeBSD: head/sys/dev/amr/amr.c 65763 2000-09-11 23:19:13Z msmith $
28 */
29
30/*
31 * Driver for the AMI MegaRaid family of controllers.
32 */
33
34#include <sys/param.h>
35#include <sys/systm.h>
36#include <sys/malloc.h>
37#include <sys/kernel.h>
38
39#include <dev/amr/amr_compat.h>
40#include <sys/bus.h>
41#include <sys/conf.h>
42#include <sys/devicestat.h>
43#include <sys/disk.h>
44#include <sys/stat.h>
45
46#include <machine/bus_memio.h>
47#include <machine/bus_pio.h>
48#include <machine/bus.h>
49#include <machine/resource.h>
50#include <machine/clock.h>
51#include <sys/rman.h>
52
53#include <pci/pcireg.h>
54#include <pci/pcivar.h>
55
56#include <dev/amr/amrio.h>
57#include <dev/amr/amrreg.h>
58#include <dev/amr/amrvar.h>
59#define AMR_DEFINE_TABLES
60#include <dev/amr/amr_tables.h>
61
62#define AMR_CDEV_MAJOR 132
63
64static d_open_t amr_open;
65static d_close_t amr_close;
66static d_ioctl_t amr_ioctl;
67
68static struct cdevsw amr_cdevsw = {
69 /* open */ amr_open,
70 /* close */ amr_close,
71 /* read */ noread,
72 /* write */ nowrite,
73 /* ioctl */ amr_ioctl,
74 /* poll */ nopoll,
75 /* mmap */ nommap,
76 /* strategy */ nostrategy,
77 /* name */ "amr",
78 /* maj */ AMR_CDEV_MAJOR,
79 /* dump */ nodump,
80 /* psize */ nopsize,
81 /* flags */ 0,
82 /* bmaj */ 254 /* XXX magic no-bdev */
83};
84
85/*
86 * Initialisation, bus interface.
87 */
88static void amr_startup(void *arg);
89
90/*
91 * Command wrappers
92 */
93static int amr_query_controller(struct amr_softc *sc);
94static void *amr_enquiry(struct amr_softc *sc, size_t bufsize,
95 u_int8_t cmd, u_int8_t cmdsub, u_int8_t cmdqual);
96static void amr_completeio(struct amr_command *ac);
97
98/*
99 * Command buffer allocation.
100 */
101static void amr_alloccmd_cluster(struct amr_softc *sc);
102static void amr_freecmd_cluster(struct amr_command_cluster *acc);
103
104/*
105 * Command processing.
106 */
107static int amr_bio_command(struct amr_softc *sc, struct amr_command **acp);
108static int amr_wait_command(struct amr_command *ac);
109static int amr_poll_command(struct amr_command *ac);
110static int amr_getslot(struct amr_command *ac);
111static void amr_mapcmd(struct amr_command *ac);
112static void amr_unmapcmd(struct amr_command *ac);
113static int amr_start(struct amr_command *ac);
114static void amr_complete(void *context, int pending);
115
116/*
117 * Status monitoring
118 */
119static void amr_periodic(void *data);
120
121/*
122 * Interface-specific shims
123 */
124static int amr_quartz_submit_command(struct amr_softc *sc);
125static int amr_quartz_get_work(struct amr_softc *sc, struct amr_mailbox *mbsave);
126
127static int amr_std_submit_command(struct amr_softc *sc);
128static int amr_std_get_work(struct amr_softc *sc, struct amr_mailbox *mbsave);
129static void amr_std_attach_mailbox(struct amr_softc *sc);
130
131#ifdef AMR_BOARD_INIT
132static int amr_quartz_init(struct amr_softc *sc);
133static int amr_std_init(struct amr_softc *sc);
134#endif
135
136/*
137 * Debugging
138 */
139static void amr_describe_controller(struct amr_softc *sc);
140#ifdef AMR_DEBUG
141static void amr_printcommand(struct amr_command *ac);
142#endif
143
144/********************************************************************************
145 ********************************************************************************
146 Inline Glue
147 ********************************************************************************
148 ********************************************************************************/
149
150/********************************************************************************
151 ********************************************************************************
152 Public Interfaces
153 ********************************************************************************
154 ********************************************************************************/
155
156/********************************************************************************
157 * Initialise the controller and softc.
158 */
159int
160amr_attach(struct amr_softc *sc)
161{
162
163 debug_called(1);
164
165 /*
166 * Initialise per-controller queues.
167 */
168 TAILQ_INIT(&sc->amr_completed);
169 TAILQ_INIT(&sc->amr_freecmds);
170 TAILQ_INIT(&sc->amr_cmd_clusters);
171 TAILQ_INIT(&sc->amr_ready);
172 bioq_init(&sc->amr_bioq);
173
174#if __FreeBSD_version >= 500005
175 /*
176 * Initialise command-completion task.
177 */
178 TASK_INIT(&sc->amr_task_complete, 0, amr_complete, sc);
179#endif
180
181 debug(2, "queue init done");
182
183 /*
184 * Configure for this controller type.
185 */
186 if (AMR_IS_QUARTZ(sc)) {
187 sc->amr_submit_command = amr_quartz_submit_command;
188 sc->amr_get_work = amr_quartz_get_work;
189 } else {
190 sc->amr_submit_command = amr_std_submit_command;
191 sc->amr_get_work = amr_std_get_work;
192 amr_std_attach_mailbox(sc);;
193 }
194
195#ifdef AMR_BOARD_INIT
196 if ((AMR_IS_QUARTZ(sc) ? amr_quartz_init(sc) : amr_std_init(sc))))
197 return(ENXIO);
198#endif
199
200 /*
201 * Quiz controller for features and limits.
202 */
203 if (amr_query_controller(sc))
204 return(ENXIO);
205
206 debug(2, "controller query complete");
207
208#ifdef AMR_SCSI_PASSTHROUGH
209 /*
210 * Attach our 'real' SCSI channels to CAM.
211 */
212 if (amr_cam_attach(sc))
213 return(ENXIO);
214 debug(2, "CAM attach done");
215#endif
216
217 /*
218 * Create the control device.
219 */
220 sc->amr_dev_t = make_dev(&amr_cdevsw, device_get_unit(sc->amr_dev), UID_ROOT, GID_OPERATOR,
221 S_IRUSR | S_IWUSR, "amr%d", device_get_unit(sc->amr_dev));
222 sc->amr_dev_t->si_drv1 = sc;
223
224 /*
225 * Schedule ourselves to bring the controller up once interrupts are
226 * available.
227 */
228 bzero(&sc->amr_ich, sizeof(struct intr_config_hook));
229 sc->amr_ich.ich_func = amr_startup;
230 sc->amr_ich.ich_arg = sc;
231 if (config_intrhook_establish(&sc->amr_ich) != 0) {
232 device_printf(sc->amr_dev, "can't establish configuration hook\n");
233 return(ENOMEM);
234 }
235
236 /*
237 * Print a little information about the controller.
238 */
239 amr_describe_controller(sc);
240
241 debug(2, "attach complete");
242 return(0);
243}
244
245/********************************************************************************
246 * Locate disk resources and attach children to them.
247 */
248static void
249amr_startup(void *arg)
250{
251 struct amr_softc *sc = (struct amr_softc *)arg;
252 struct amr_logdrive *dr;
253 int i, error;
254
255 debug_called(1);
256
257 /* pull ourselves off the intrhook chain */
258 config_intrhook_disestablish(&sc->amr_ich);
259
260 /* get up-to-date drive information */
261 if (amr_query_controller(sc)) {
262 device_printf(sc->amr_dev, "can't scan controller for drives\n");
263 return;
264 }
265
266 /* iterate over available drives */
267 for (i = 0, dr = &sc->amr_drive[0]; (i < AMR_MAXLD) && (dr->al_size != 0xffffffff); i++, dr++) {
268 /* are we already attached to this drive? */
269 if (dr->al_disk == 0) {
270 /* generate geometry information */
271 if (dr->al_size > 0x200000) { /* extended translation? */
272 dr->al_heads = 255;
273 dr->al_sectors = 63;
274 } else {
275 dr->al_heads = 64;
276 dr->al_sectors = 32;
277 }
278 dr->al_cylinders = dr->al_size / (dr->al_heads * dr->al_sectors);
279
280 dr->al_disk = device_add_child(sc->amr_dev, NULL, -1);
281 if (dr->al_disk == 0)
282 device_printf(sc->amr_dev, "device_add_child failed\n");
283 device_set_ivars(dr->al_disk, dr);
284 }
285 }
286
287 if ((error = bus_generic_attach(sc->amr_dev)) != 0)
288 device_printf(sc->amr_dev, "bus_generic_attach returned %d\n", error);
289
290 /* mark controller back up */
291 sc->amr_state &= ~AMR_STATE_SHUTDOWN;
292
293 /* interrupts will be enabled before we do anything more */
294 sc->amr_state |= AMR_STATE_INTEN;
295
296 /*
297 * Start the timeout routine.
298 */
299/* sc->amr_timeout = timeout(amr_periodic, sc, hz);*/
300
301 return;
302}
303
304/*******************************************************************************
305 * Free resources associated with a controller instance
306 */
307void
308amr_free(struct amr_softc *sc)
309{
310 struct amr_command_cluster *acc;
311
312#ifdef AMR_SCSI_PASSTHROUGH
313 /* detach from CAM */
314 amr_cam_detach(sc);
315#endif
316
317 /* cancel status timeout */
318 untimeout(amr_periodic, sc, sc->amr_timeout);
319
320 /* throw away any command buffers */
321 while ((acc = TAILQ_FIRST(&sc->amr_cmd_clusters)) != NULL) {
322 TAILQ_REMOVE(&sc->amr_cmd_clusters, acc, acc_link);
323 amr_freecmd_cluster(acc);
324 }
325}
326
327/*******************************************************************************
328 * Receive a bio structure from a child device and queue it on a particular
329 * disk resource, then poke the disk resource to start as much work as it can.
330 */
331int
332amr_submit_bio(struct amr_softc *sc, struct bio *bio)
333{
334 debug_called(2);
335
336 amr_enqueue_bio(sc, bio);
337 amr_startio(sc);
338 return(0);
339}
340
341/********************************************************************************
342 * Accept an open operation on the control device.
343 */
344int
345amr_open(dev_t dev, int flags, int fmt, struct proc *p)
346{
347 int unit = minor(dev);
348 struct amr_softc *sc = devclass_get_softc(amr_devclass, unit);
349
350 debug_called(1);
351
352 sc->amr_state |= AMR_STATE_OPEN;
353 return(0);
354}
355
356/********************************************************************************
357 * Accept the last close on the control device.
358 */
359int
360amr_close(dev_t dev, int flags, int fmt, struct proc *p)
361{
362 int unit = minor(dev);
363 struct amr_softc *sc = devclass_get_softc(amr_devclass, unit);
364
365 debug_called(1);
366
367 sc->amr_state &= ~AMR_STATE_OPEN;
368 return (0);
369}
370
371/********************************************************************************
372 * Handle controller-specific control operations.
373 */
374int
375amr_ioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, struct proc *p)
376{
377 struct amr_softc *sc = (struct amr_softc *)dev->si_drv1;
378 int *arg = (int *)addr;
379 struct amr_user_ioctl *au = (struct amr_user_ioctl *)addr;
380 struct amr_command *ac;
381 struct amr_mailbox_ioctl *mbi;
382 struct amr_passthrough *ap;
383 void *dp;
384 int error;
385
386 debug_called(1);
387
388 error = 0;
389 dp = NULL;
390 ap = NULL;
391 ac = NULL;
392 switch(cmd) {
393
394 case AMR_IO_VERSION:
395 debug(1, "AMR_IO_VERSION");
396 *arg = AMR_IO_VERSION_NUMBER;
397 break;
398
399 case AMR_IO_COMMAND:
400 debug(1, "AMR_IO_COMMAND");
401 /* handle inbound data buffer */
402 if (au->au_length != 0) {
403 if ((dp = malloc(au->au_length, M_DEVBUF, M_WAITOK)) == NULL) {
404 error = ENOMEM;
405 break;
406 }
407 if ((error = copyin(au->au_buffer, dp, au->au_length)) != 0)
408 break;
409 }
410
411 if ((ac = amr_alloccmd(sc)) == NULL) {
412 error = ENOMEM;
413 break;
414 }
415
416 /* handle SCSI passthrough command */
417 if (au->au_cmd[0] == AMR_CMD_PASS) {
418 if ((ap = malloc(sizeof(*ap), M_DEVBUF, M_WAITOK)) == NULL) {
419 error = ENOMEM;
420 break;
421 }
422 bzero(ap, sizeof(*ap));
423
424 /* copy cdb */
425 ap->ap_cdb_length = au->au_cmd[2];
426 bcopy(&au->au_cmd[3], &ap->ap_cdb[0], ap->ap_cdb_length);
427
428 /* build passthrough */
429 ap->ap_timeout = au->au_cmd[ap->ap_cdb_length + 3] & 0x07;
430 ap->ap_ars = (au->au_cmd[ap->ap_cdb_length + 3] & 0x08) ? 1 : 0;
431 ap->ap_islogical = (au->au_cmd[ap->ap_cdb_length + 3] & 0x80) ? 1 : 0;
432 ap->ap_logical_drive_no = au->au_cmd[ap->ap_cdb_length + 4];
433 ap->ap_channel = au->au_cmd[ap->ap_cdb_length + 5];
434 ap->ap_scsi_id = au->au_cmd[ap->ap_cdb_length + 6];
435 ap->ap_request_sense_length = 14;
436 /* XXX what about the request-sense area? does the caller want it? */
437
438 /* build command */
439 ac->ac_data = ap;
440 ac->ac_length = sizeof(*ap);
441 ac->ac_flags |= AMR_CMD_DATAOUT;
442 ac->ac_ccb_data = dp;
443 ac->ac_ccb_length = au->au_length;
444 if (au->au_direction & AMR_IO_READ)
445 ac->ac_flags |= AMR_CMD_CCB_DATAIN;
446 if (au->au_direction & AMR_IO_WRITE)
447 ac->ac_flags |= AMR_CMD_CCB_DATAOUT;
448
449 ac->ac_mailbox.mb_command = AMR_CMD_PASS;
450
451 } else {
452 /* direct command to controller */
453 mbi = (struct amr_mailbox_ioctl *)&ac->ac_mailbox;
454
455 /* copy pertinent mailbox items */
456 mbi->mb_command = au->au_cmd[0];
457 mbi->mb_channel = au->au_cmd[1];
458 mbi->mb_param = au->au_cmd[2];
459 mbi->mb_pad[0] = au->au_cmd[3];
460 mbi->mb_drive = au->au_cmd[4];
461
462 /* build the command */
463 ac->ac_data = dp;
464 ac->ac_length = au->au_length;
465 if (au->au_direction & AMR_IO_READ)
466 ac->ac_flags |= AMR_CMD_DATAIN;
467 if (au->au_direction & AMR_IO_WRITE)
468 ac->ac_flags |= AMR_CMD_DATAOUT;
469 }
470
471 /* run the command */
472 if ((error = amr_wait_command(ac)) != 0)
473 break;
474
475 /* copy out data and set status */
476 if (au->au_length != 0)
477 error = copyout(dp, au->au_buffer, au->au_length);
478 au->au_status = ac->ac_status;
479 break;
480
481 default:
482 debug(1, "unknown ioctl 0x%lx", cmd);
483 error = ENOIOCTL;
484 break;
485 }
486
487 if (dp != NULL)
488 free(dp, M_DEVBUF);
489 if (ap != NULL)
490 free(ap, M_DEVBUF);
491 if (ac != NULL)
492 amr_releasecmd(ac);
493 return(error);
494}
495
496/********************************************************************************
497 ********************************************************************************
498 Status Monitoring
499 ********************************************************************************
500 ********************************************************************************/
501
502/********************************************************************************
503 * Perform a periodic check of the controller status
504 */
505static void
506amr_periodic(void *data)
507{
508 struct amr_softc *sc = (struct amr_softc *)data;
509
510 debug_called(2);
511
512 /* XXX perform periodic status checks here */
513
514 /* compensate for missed interrupts */
515 amr_done(sc);
516
517 /* reschedule */
518 sc->amr_timeout = timeout(amr_periodic, sc, hz);
519}
520
521/********************************************************************************
522 ********************************************************************************
523 Command Wrappers
524 ********************************************************************************
525 ********************************************************************************/
526
527/********************************************************************************
528 * Interrogate the controller for the operational parameters we require.
529 */
530static int
531amr_query_controller(struct amr_softc *sc)
532{
533 struct amr_enquiry3 *aex;
534 struct amr_prodinfo *ap;
535 struct amr_enquiry *ae;
536 int ldrv;
537
538 /*
539 * If we haven't found the real limit yet, let us have a couple of commands in
540 * order to be able to probe.
541 */
542 if (sc->amr_maxio == 0)
543 sc->amr_maxio = 2;
544
545 /*
546 * Try to issue an ENQUIRY3 command
547 */
548 if ((aex = amr_enquiry(sc, 2048, AMR_CMD_CONFIG, AMR_CONFIG_ENQ3,
549 AMR_CONFIG_ENQ3_SOLICITED_FULL)) != NULL) {
550
551 /*
552 * Fetch current state of logical drives.
553 */
554 for (ldrv = 0; ldrv < aex->ae_numldrives; ldrv++) {
555 sc->amr_drive[ldrv].al_size = aex->ae_drivesize[ldrv];
556 sc->amr_drive[ldrv].al_state = aex->ae_drivestate[ldrv];
557 sc->amr_drive[ldrv].al_properties = aex->ae_driveprop[ldrv];
558 debug(2, " drive %d: %d state %x properties %x\n", ldrv, sc->amr_drive[ldrv].al_size,
559 sc->amr_drive[ldrv].al_state, sc->amr_drive[ldrv].al_properties);
560 }
561 free(aex, M_DEVBUF);
562
563 /*
564 * Get product info for channel count.
565 */
566 if ((ap = amr_enquiry(sc, 2048, AMR_CMD_CONFIG, AMR_CONFIG_PRODUCT_INFO, 0)) == NULL) {
567 device_printf(sc->amr_dev, "can't obtain product data from controller\n");
568 return(1);
569 }
570 sc->amr_maxdrives = 40;
571 sc->amr_maxchan = ap->ap_nschan;
572 sc->amr_maxio = ap->ap_maxio;
573 sc->amr_type |= AMR_TYPE_40LD;
574 free(ap, M_DEVBUF);
575
576 } else {
577
578 /* failed, try the 8LD ENQUIRY commands */
579 if ((ae = (struct amr_enquiry *)amr_enquiry(sc, 2048, AMR_CMD_EXT_ENQUIRY2, 0, 0)) == NULL) {
580 if ((ae = (struct amr_enquiry *)amr_enquiry(sc, 2048, AMR_CMD_ENQUIRY, 0, 0)) == NULL) {
581 device_printf(sc->amr_dev, "can't obtain configuration data from controller\n");
582 return(1);
583 }
584 ae->ae_signature = 0;
585 }
586
587 /*
588 * Fetch current state of logical drives.
589 */
590 for (ldrv = 0; ldrv < ae->ae_ldrv.al_numdrives; ldrv++) {
591 sc->amr_drive[ldrv].al_size = ae->ae_ldrv.al_size[ldrv];
592 sc->amr_drive[ldrv].al_state = ae->ae_ldrv.al_state[ldrv];
593 sc->amr_drive[ldrv].al_properties = ae->ae_ldrv.al_properties[ldrv];
594 debug(2, " drive %d: %d state %x properties %x\n", ldrv, sc->amr_drive[ldrv].al_size,
595 sc->amr_drive[ldrv].al_state, sc->amr_drive[ldrv].al_properties);
596 }
597
598 sc->amr_maxdrives = 8;
599 sc->amr_maxchan = ae->ae_adapter.aa_channels;
600 sc->amr_maxio = ae->ae_adapter.aa_maxio;
601 free(ae, M_DEVBUF);
602 }
603
604 /*
605 * Mark remaining drives as unused.
606 */
607 for (; ldrv < AMR_MAXLD; ldrv++)
608 sc->amr_drive[ldrv].al_size = 0xffffffff;
609
610 /*
611 * Cap the maximum number of outstanding I/Os. AMI's Linux driver doesn't trust
612 * the controller's reported value, and lockups have been seen when we do.
613 */
614 sc->amr_maxio = imin(sc->amr_maxio, AMR_LIMITCMD);
615
616 return(0);
617}
618
619/********************************************************************************
620 * Run a generic enquiry-style command.
621 */
622static void *
623amr_enquiry(struct amr_softc *sc, size_t bufsize, u_int8_t cmd, u_int8_t cmdsub, u_int8_t cmdqual)
624{
625 struct amr_command *ac;
626 void *result;
627 u_int8_t *mbox;
628 int error;
629
630 debug_called(1);
631
632 error = 1;
633 result = NULL;
634
635 /* get ourselves a command buffer */
636 if ((ac = amr_alloccmd(sc)) == NULL)
637 goto out;
638 /* allocate the response structure */
639 if ((result = malloc(bufsize, M_DEVBUF, M_NOWAIT)) == NULL)
640 goto out;
641 /* set command flags */
642 ac->ac_flags |= AMR_CMD_PRIORITY | AMR_CMD_DATAOUT;
643
644 /* point the command at our data */
645 ac->ac_data = result;
646 ac->ac_length = bufsize;
647
648 /* build the command proper */
649 mbox = (u_int8_t *)&ac->ac_mailbox; /* XXX want a real structure for this? */
650 mbox[0] = cmd;
651 mbox[2] = cmdsub;
652 mbox[3] = cmdqual;
653
654 /* can't assume that interrupts are going to work here, so play it safe */
655 if (amr_poll_command(ac))
656 goto out;
657 error = ac->ac_status;
658
659 out:
660 if (ac != NULL)
661 amr_releasecmd(ac);
662 if ((error != 0) && (result != NULL)) {
663 free(result, M_DEVBUF);
664 result = NULL;
665 }
666 return(result);
667}
668
669/********************************************************************************
670 * Flush the controller's internal cache, return status.
671 */
672int
673amr_flush(struct amr_softc *sc)
674{
675 struct amr_command *ac;
676 int error;
677
678 /* get ourselves a command buffer */
679 error = 1;
680 if ((ac = amr_alloccmd(sc)) == NULL)
681 goto out;
682 /* set command flags */
683 ac->ac_flags |= AMR_CMD_PRIORITY | AMR_CMD_DATAOUT;
684
685 /* build the command proper */
686 ac->ac_mailbox.mb_command = AMR_CMD_FLUSH;
687
688 /* we have to poll, as the system may be going down or otherwise damaged */
689 if (amr_poll_command(ac))
690 goto out;
691 error = ac->ac_status;
692
693 out:
694 if (ac != NULL)
695 amr_releasecmd(ac);
696 return(error);
697}
698
699/********************************************************************************
700 * Try to find I/O work for the controller from one or more of the work queues.
701 *
702 * We make the assumption that if the controller is not ready to take a command
703 * at some given time, it will generate an interrupt at some later time when
704 * it is.
705 */
706void
707amr_startio(struct amr_softc *sc)
708{
709 struct amr_command *ac;
710
711 /* spin until something prevents us from doing any work */
712 for (;;) {
713
714 /* try to get a ready command */
715 ac = amr_dequeue_ready(sc);
716
717 /* if that failed, build a command from a bio */
718 if (ac == NULL)
719 (void)amr_bio_command(sc, &ac);
720
721#ifdef AMR_SCSI_PASSTHROUGH
722 /* if that failed, build a command from a ccb */
723 if (ac == NULL)
724 (void)amr_cam_command(sc, &ac);
725#endif
726
727 /* if we don't have anything to do, give up */
728 if (ac == NULL)
729 break;
730
731 /* try to give the command to the controller; if this fails save it for later and give up */
732 if (amr_start(ac)) {
733 debug(2, "controller busy, command deferred");
734 amr_requeue_ready(ac); /* XXX schedule retry very soon? */
735 break;
736 }
737 }
738}
739
740/********************************************************************************
741 * Handle completion of an I/O command.
742 */
743static void
744amr_completeio(struct amr_command *ac)
745{
746 struct amr_softc *sc = ac->ac_sc;
747
748 if (ac->ac_status != AMR_STATUS_SUCCESS) { /* could be more verbose here? */
749 ac->ac_bio->bio_error = EIO;
750 ac->ac_bio->bio_flags |= BIO_ERROR;
751
752 device_printf(sc->amr_dev, "I/O error - 0x%x\n", ac->ac_status);
753/* amr_printcommand(ac);*/
754 }
755 amrd_intr(ac->ac_bio);
756 amr_releasecmd(ac);
757}
758
759/********************************************************************************
760 ********************************************************************************
761 Command Processing
762 ********************************************************************************
763 ********************************************************************************/
764
765/********************************************************************************
766 * Convert a bio off the top of the bio queue into a command.
767 */
768static int
769amr_bio_command(struct amr_softc *sc, struct amr_command **acp)
770{
771 struct amr_command *ac;
772 struct amrd_softc *amrd;
773 struct bio *bio;
774 int error;
775 int blkcount;
776 int driveno;
777 int cmd;
778
779 ac = NULL;
780 error = 0;
781
782 /* get a bio to work on */
783 if ((bio = amr_dequeue_bio(sc)) == NULL)
784 goto out;
785
786 /* get a command */
787 if ((ac = amr_alloccmd(sc)) == NULL) {
788 error = ENOMEM;
789 goto out;
790 }
791
792 /* connect the bio to the command */
793 ac->ac_complete = amr_completeio;
794 ac->ac_bio = bio;
795 ac->ac_data = bio->bio_data;
796 ac->ac_length = bio->bio_bcount;
797 if (BIO_IS_READ(bio)) {
798 ac->ac_flags |= AMR_CMD_DATAIN;
799 cmd = AMR_CMD_LREAD;
800 } else {
801 ac->ac_flags |= AMR_CMD_DATAOUT;
802 cmd = AMR_CMD_LWRITE;
803 }
804 amrd = (struct amrd_softc *)bio->bio_dev->si_drv1;
805 driveno = amrd->amrd_drive - sc->amr_drive;
806 blkcount = (bio->bio_bcount + AMR_BLKSIZE - 1) / AMR_BLKSIZE;
807
808 ac->ac_mailbox.mb_command = cmd;
809 ac->ac_mailbox.mb_blkcount = blkcount;
810 ac->ac_mailbox.mb_lba = bio->bio_pblkno;
811 ac->ac_mailbox.mb_drive = driveno;
812 /* we fill in the s/g related data when the command is mapped */
813
814 if ((bio->bio_pblkno + blkcount) > sc->amr_drive[driveno].al_size)
815 device_printf(sc->amr_dev, "I/O beyond end of unit (%u,%d > %u)\n",
816 bio->bio_pblkno, blkcount, sc->amr_drive[driveno].al_size);
817
818out:
819 if (error != 0) {
820 if (ac != NULL)
821 amr_releasecmd(ac);
822 if (bio != NULL) /* this breaks ordering... */
823 amr_enqueue_bio(sc, bio);
824 }
825 *acp = ac;
826 return(error);
827}
828
829/********************************************************************************
830 * Take a command, submit it to the controller and sleep until it completes
831 * or fails. Interrupts must be enabled, returns nonzero on error.
832 */
833static int
834amr_wait_command(struct amr_command *ac)
835{
836 struct amr_softc *sc = ac->ac_sc;
837 int error, count;
838
839 debug_called(1);
840
841 ac->ac_complete = NULL;
842 ac->ac_flags |= AMR_CMD_SLEEP;
843 if ((error = amr_start(ac)) != 0)
844 return(error);
845
846 count = 0;
847 /* XXX better timeout? */
848 while ((ac->ac_flags & AMR_CMD_BUSY) && (count < 30)) {
849 tsleep(ac, PRIBIO | PCATCH, "amrwcmd", hz);
850 }
851
852 if (ac->ac_status != 0) {
853 device_printf(sc->amr_dev, "I/O error - 0x%x\n", ac->ac_status);
854 return(EIO);
855 }
856 return(0);
857}
858
859/********************************************************************************
860 * Take a command, submit it to the controller and busy-wait for it to return.
861 * Returns nonzero on error. Can be safely called with interrupts enabled.
862 */
863static int
864amr_poll_command(struct amr_command *ac)
865{
866 struct amr_softc *sc = ac->ac_sc;
867 int error, count;
868
869 debug_called(2);
870
871 ac->ac_complete = NULL;
872 if ((error = amr_start(ac)) != 0)
873 return(error);
874
875 count = 0;
876 do {
877 /*
878 * Poll for completion, although the interrupt handler may beat us to it.
879 * Note that the timeout here is somewhat arbitrary.
880 */
881 amr_done(sc);
882 DELAY(1000);
883 } while ((ac->ac_flags & AMR_CMD_BUSY) && (count++ < 1000));
884 if (!(ac->ac_flags & AMR_CMD_BUSY)) {
885 error = 0;
886 } else {
887 /* XXX the slot is now marked permanently busy */
888 error = EIO;
889 device_printf(sc->amr_dev, "polled command timeout\n");
890 }
891 return(error);
892}
893
894/********************************************************************************
895 * Get a free command slot for a command if it doesn't already have one.
896 *
897 * May be safely called multiple times for a given command.
898 */
899static int
900amr_getslot(struct amr_command *ac)
901{
902 struct amr_softc *sc = ac->ac_sc;
903 int s, slot, limit, error;
904
905 debug_called(3);
906
907 /* if the command already has a slot, don't try to give it another one */
908 if (ac->ac_slot != 0)
909 return(0);
910
911 /* enforce slot usage limit */
912 limit = (ac->ac_flags & AMR_CMD_PRIORITY) ? sc->amr_maxio : sc->amr_maxio - 4;
913 if (sc->amr_busyslots > limit)
914 return(EBUSY);
915
916 /*
917 * Allocate a slot. XXX linear scan is slow
918 */
919 error = EBUSY;
920 s = splbio();
921 for (slot = 0; slot < sc->amr_maxio; slot++) {
922 if (sc->amr_busycmd[slot] == NULL) {
923 sc->amr_busycmd[slot] = ac;
924 sc->amr_busyslots++;
925 ac->ac_slot = slot;
926 error = 0;
927 break;
928 }
929 }
930 splx(s);
931
932 return(error);
933}
934
935/********************************************************************************
936 * Map/unmap (ac)'s data in the controller's addressable space as required.
937 *
938 * These functions may be safely called multiple times on a given command.
939 */
940static void
941amr_setup_dmamap(void *arg, bus_dma_segment_t *segs, int nsegments, int error)
942{
943 struct amr_command *ac = (struct amr_command *)arg;
944 struct amr_softc *sc = ac->ac_sc;
945 struct amr_sgentry *sg;
946 int i;
947
948 debug_called(3);
949
950 /* get base address of s/g table */
951 sg = sc->amr_sgtable + (ac->ac_slot * AMR_NSEG);
952
953 /* save data physical address */
954 ac->ac_dataphys = segs[0].ds_addr;
955
956 /* decide whether we need to populate the s/g table */
957 if (nsegments < 2) {
958 ac->ac_mailbox.mb_nsgelem = 0;
959 ac->ac_mailbox.mb_physaddr = ac->ac_dataphys;
960 } else {
961 ac->ac_mailbox.mb_nsgelem = nsegments;
962 ac->ac_mailbox.mb_physaddr = sc->amr_sgbusaddr + (ac->ac_slot * AMR_NSEG * sizeof(struct amr_sgentry));
963 for (i = 0; i < nsegments; i++, sg++) {
964 sg->sg_addr = segs[i].ds_addr;
965 sg->sg_count = segs[i].ds_len;
966 }
967 }
968}
969
970static void
971amr_setup_ccbmap(void *arg, bus_dma_segment_t *segs, int nsegments, int error)
972{
973 struct amr_command *ac = (struct amr_command *)arg;
974 struct amr_softc *sc = ac->ac_sc;
975 struct amr_sgentry *sg;
976 struct amr_passthrough *ap = (struct amr_passthrough *)ac->ac_data;
977 int i;
978
979 /* get base address of s/g table */
980 sg = sc->amr_sgtable + (ac->ac_slot * AMR_NSEG);
981
982 /* save s/g table information in passthrough */
983 ap->ap_no_sg_elements = nsegments;
984 ap->ap_data_transfer_address = sc->amr_sgbusaddr + (ac->ac_slot * AMR_NSEG * sizeof(struct amr_sgentry));
985
986 /* save pointer to passthrough in command XXX is this already done above? */
987 ac->ac_mailbox.mb_physaddr = ac->ac_dataphys;
988
989 debug(2, "slot %d %d segments at 0x%x, passthrough at 0x%x", ac->ac_slot,
990 ap->ap_no_sg_elements, ap->ap_data_transfer_address, ac->ac_dataphys);
991
992 /* populate s/g table (overwrites previous call which mapped the passthrough) */
993 for (i = 0; i < nsegments; i++, sg++) {
994 sg->sg_addr = segs[i].ds_addr;
995 sg->sg_count = segs[i].ds_len;
996 debug(2, " %d: 0x%x/%d", i, sg->sg_addr, sg->sg_count);
997 }
998}
999
1000static void
1001amr_mapcmd(struct amr_command *ac)
1002{
1003 struct amr_softc *sc = ac->ac_sc;
1004
1005 debug_called(2);
1006
1007 /* if the command involves data at all, and hasn't been mapped */
1008 if (!(ac->ac_flags & AMR_CMD_MAPPED)) {
1009
1010 if (ac->ac_data != NULL) {
1011 /* map the data buffers into bus space and build the s/g list */
1012 bus_dmamap_load(sc->amr_buffer_dmat, ac->ac_dmamap, ac->ac_data, ac->ac_length,
1013 amr_setup_dmamap, ac, 0);
1014 if (ac->ac_flags & AMR_CMD_DATAIN)
1015 bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_dmamap, BUS_DMASYNC_PREREAD);
1016 if (ac->ac_flags & AMR_CMD_DATAOUT)
1017 bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_dmamap, BUS_DMASYNC_PREWRITE);
1018 }
1019
1020 if (ac->ac_ccb_data != NULL) {
1021 bus_dmamap_load(sc->amr_buffer_dmat, ac->ac_ccb_dmamap, ac->ac_ccb_data, ac->ac_ccb_length,
1022 amr_setup_ccbmap, ac, 0);
1023 if (ac->ac_flags & AMR_CMD_CCB_DATAIN)
1024 bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_ccb_dmamap, BUS_DMASYNC_PREREAD);
1025 if (ac->ac_flags & AMR_CMD_CCB_DATAOUT)
1026 bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_ccb_dmamap, BUS_DMASYNC_PREWRITE);
1027 }
1028 ac->ac_flags |= AMR_CMD_MAPPED;
1029 }
1030}
1031
1032static void
1033amr_unmapcmd(struct amr_command *ac)
1034{
1035 struct amr_softc *sc = ac->ac_sc;
1036
1037 debug_called(2);
1038
1039 /* if the command involved data at all and was mapped */
1040 if (ac->ac_flags & AMR_CMD_MAPPED) {
1041
1042 if (ac->ac_data != NULL) {
1043 if (ac->ac_flags & AMR_CMD_DATAIN)
1044 bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_dmamap, BUS_DMASYNC_POSTREAD);
1045 if (ac->ac_flags & AMR_CMD_DATAOUT)
1046 bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_dmamap, BUS_DMASYNC_POSTWRITE);
1047 bus_dmamap_unload(sc->amr_buffer_dmat, ac->ac_dmamap);
1048 }
1049
1050 if (ac->ac_ccb_data != NULL) {
1051 if (ac->ac_flags & AMR_CMD_CCB_DATAIN)
1052 bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_ccb_dmamap, BUS_DMASYNC_POSTREAD);
1053 if (ac->ac_flags & AMR_CMD_CCB_DATAOUT)
1054 bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_ccb_dmamap, BUS_DMASYNC_POSTWRITE);
1055 bus_dmamap_unload(sc->amr_buffer_dmat, ac->ac_ccb_dmamap);
1056 }
1057 ac->ac_flags &= ~AMR_CMD_MAPPED;
1058 }
1059}
1060
1061/********************************************************************************
1062 * Take a command and give it to the controller, returns 0 if successful, or
1063 * EBUSY if the command should be retried later.
1064 */
1065static int
1066amr_start(struct amr_command *ac)
1067{
1068 struct amr_softc *sc = ac->ac_sc;
1069 int done, s, i;
1070
1071 debug_called(2);
1072
1073 /* mark command as busy so that polling consumer can tell */
1074 ac->ac_flags |= AMR_CMD_BUSY;
1075
1076 /* get a command slot (freed in amr_done) */
1077 if (amr_getslot(ac))
1078 return(EBUSY);
1079
1080 /* now we have a slot, we can map the command (unmapped in amr_complete) */
1081 amr_mapcmd(ac);
1082
1083 /* mark the new mailbox we are going to copy in as busy */
1084 ac->ac_mailbox.mb_busy = 1;
1085
1086 /* clear the poll/ack fields in the mailbox */
1087 sc->amr_mailbox->mb_poll = 0;
1088 sc->amr_mailbox->mb_ack = 0;
1089
1090 /*
1091 * Save the slot number so that we can locate this command when complete.
1092 * Note that ident = 0 seems to be special, so we don't use it.
1093 */
1094 ac->ac_mailbox.mb_ident = ac->ac_slot + 1;
1095
1096 /*
1097 * Spin waiting for the mailbox, give up after ~1 second. We expect the
1098 * controller to be able to handle our I/O.
1099 *
1100 * XXX perhaps we should wait for less time, and count on the deferred command
1101 * handling to deal with retries?
1102 */
1103 debug(2, "wait for mailbox");
1104 for (i = 10000, done = 0; (i > 0) && !done; i--) {
1105 s = splbio();
1106
1107 /* is the mailbox free? */
1108 if (sc->amr_mailbox->mb_busy == 0) {
1109 debug(2, "got mailbox");
1110 sc->amr_mailbox64->mb64_segment = 0;
1111 bcopy(&ac->ac_mailbox, (void *)(uintptr_t)(volatile void *)sc->amr_mailbox, AMR_MBOX_CMDSIZE);
1112 done = 1;
1113
1114 /* not free, spin waiting */
1115 } else {
1116 debug(3, "busy flag %x\n", sc->amr_mailbox->mb_busy);
1117 /* this is somewhat ugly */
1118 DELAY(100);
1119 }
1120 splx(s); /* drop spl to allow completion interrupts */
1121 }
1122
1123 /*
1124 * Now give the command to the controller
1125 */
1126 if (done) {
1127 if (sc->amr_submit_command(sc)) {
1128 /* the controller wasn't ready to take the command, forget that we tried to post it */
1129 sc->amr_mailbox->mb_busy = 0;
1130 return(EBUSY);
1131 }
1132 debug(2, "posted command");
1133 return(0);
1134 }
1135
1136 /*
1137 * The controller wouldn't take the command. Return the command as busy
1138 * so that it is retried later.
1139 */
1140 return(EBUSY);
1141}
1142
1143/********************************************************************************
1144 * Extract one or more completed commands from the controller (sc)
1145 *
1146 * Returns nonzero if any commands on the work queue were marked as completed.
1147 */
1148int
1149amr_done(struct amr_softc *sc)
1150{
1151 struct amr_command *ac;
1152 struct amr_mailbox mbox;
1153 int i, idx, result;
1154
1155 debug_called(2);
1156
1157 /* See if there's anything for us to do */
1158 result = 0;
1159
1160 /* loop collecting completed commands */
1161 for (;;) {
1162 /* poll for a completed command's identifier and status */
1163 if (sc->amr_get_work(sc, &mbox)) {
1164 result = 1;
1165
1166 /* iterate over completed commands in this result */
1167 for (i = 0; i < mbox.mb_nstatus; i++) {
1168 /* get pointer to busy command */
1169 idx = mbox.mb_completed[i] - 1;
1170 ac = sc->amr_busycmd[idx];
1171
1172 /* really a busy command? */
1173 if (ac != NULL) {
1174
1175 /* pull the command from the busy index */
1176 sc->amr_busycmd[idx] = NULL;
1177 sc->amr_busyslots--;
1178
1179 /* save status for later use */
1180 ac->ac_status = mbox.mb_status;
1181 amr_enqueue_completed(ac);
1182 debug(3, "completed command with status %x", mbox.mb_status);
1183 } else {
1184 device_printf(sc->amr_dev, "bad slot %d completed\n", idx);
1185 }
1186 }
1187 } else {
1188 break; /* no work */
1189 }
1190 }
1191
1192 /* if we've completed any commands, try posting some more */
1193 if (result)
1194 amr_startio(sc);
1195
1196 /* handle completion and timeouts */
1197#if __FreeBSD_version >= 500005
1198 if (sc->amr_state & AMR_STATE_INTEN)
1199 taskqueue_enqueue(taskqueue_swi, &sc->amr_task_complete);
1200 else
1201#endif
1202 amr_complete(sc, 0);
1203
1204 return(result);
1205}
1206
1207/********************************************************************************
1208 * Do completion processing on done commands on (sc)
1209 */
1210static void
1211amr_complete(void *context, int pending)
1212{
1213 struct amr_softc *sc = (struct amr_softc *)context;
1214 struct amr_command *ac;
1215
1216 debug_called(2);
1217
1218 /* pull completed commands off the queue */
1219 for (;;) {
1220 ac = amr_dequeue_completed(sc);
1221 if (ac == NULL)
1222 break;
1223
1224 /* unmap the command's data buffer */
1225 amr_unmapcmd(ac);
1226
1227 /* unbusy the command */
1228 ac->ac_flags &= ~AMR_CMD_BUSY;
1229
1230 /*
1231 * Is there a completion handler?
1232 */
1233 if (ac->ac_complete != NULL) {
1234 ac->ac_complete(ac);
1235
1236 /*
1237 * Is someone sleeping on this one?
1238 */
1239 } else if (ac->ac_flags & AMR_CMD_SLEEP) {
1240 wakeup(ac);
1241 }
1242 }
1243}
1244
1245/********************************************************************************
1246 ********************************************************************************
1247 Command Buffer Management
1248 ********************************************************************************
1249 ********************************************************************************/
1250
1251/********************************************************************************
1252 * Get a new command buffer.
1253 *
1254 * This may return NULL in low-memory cases.
1255 *
1256 * If possible, we recycle a command buffer that's been used before.
1257 */
1258struct amr_command *
1259amr_alloccmd(struct amr_softc *sc)
1260{
1261 struct amr_command *ac;
1262
1263 debug_called(3);
1264
1265 ac = amr_dequeue_free(sc);
1266 if (ac == NULL) {
1267 amr_alloccmd_cluster(sc);
1268 ac = amr_dequeue_free(sc);
1269 }
1270 if (ac == NULL)
1271 return(NULL);
1272
1273 /* clear out significant fields */
1274 ac->ac_slot = 0;
1275 ac->ac_status = 0;
1276 bzero(&ac->ac_mailbox, sizeof(struct amr_mailbox));
1277 ac->ac_flags = 0;
1278 ac->ac_bio = NULL;
1279 ac->ac_data = NULL;
1280 ac->ac_ccb_data = NULL;
1281 ac->ac_complete = NULL;
1282 return(ac);
1283}
1284
1285/********************************************************************************
1286 * Release a command buffer for recycling.
1287 */
1288void
1289amr_releasecmd(struct amr_command *ac)
1290{
1291 debug_called(3);
1292
1293 amr_enqueue_free(ac);
1294}
1295
1296/********************************************************************************
1297 * Allocate a new command cluster and initialise it.
1298 */
1299void
1300amr_alloccmd_cluster(struct amr_softc *sc)
1301{
1302 struct amr_command_cluster *acc;
1303 struct amr_command *ac;
1304 int s, i;
1305
1306 acc = malloc(AMR_CMD_CLUSTERSIZE, M_DEVBUF, M_NOWAIT);
1307 if (acc != NULL) {
1308 s = splbio();
1309 TAILQ_INSERT_TAIL(&sc->amr_cmd_clusters, acc, acc_link);
1310 splx(s);
1311 for (i = 0; i < AMR_CMD_CLUSTERCOUNT; i++) {
1312 ac = &acc->acc_command[i];
1313 bzero(ac, sizeof(*ac));
1314 ac->ac_sc = sc;
1315 if (!bus_dmamap_create(sc->amr_buffer_dmat, 0, &ac->ac_dmamap) &&
1316 !bus_dmamap_create(sc->amr_buffer_dmat, 0, &ac->ac_ccb_dmamap))
1317 amr_releasecmd(ac);
1318 }
1319 }
1320}
1321
1322/********************************************************************************
1323 * Free a command cluster
1324 */
1325void
1326amr_freecmd_cluster(struct amr_command_cluster *acc)
1327{
1328 struct amr_softc *sc = acc->acc_command[0].ac_sc;
1329 int i;
1330
1331 for (i = 0; i < AMR_CMD_CLUSTERCOUNT; i++)
1332 bus_dmamap_destroy(sc->amr_buffer_dmat, acc->acc_command[i].ac_dmamap);
1333 free(acc, M_DEVBUF);
1334}
1335
1336/********************************************************************************
1337 ********************************************************************************
1338 Interface-specific Shims
1339 ********************************************************************************
1340 ********************************************************************************/
1341
1342/********************************************************************************
1343 * Tell the controller that the mailbox contains a valid command
1344 */
1345static int
1346amr_quartz_submit_command(struct amr_softc *sc)
1347{
1348 debug_called(3);
1349
1350 if (AMR_QGET_IDB(sc) & AMR_QIDB_SUBMIT)
1351 return(EBUSY);
1352 AMR_QPUT_IDB(sc, sc->amr_mailboxphys | AMR_QIDB_SUBMIT);
1353 return(0);
1354}
1355
1356static int
1357amr_std_submit_command(struct amr_softc *sc)
1358{
1359 debug_called(3);
1360
1361 if (AMR_SGET_MBSTAT(sc) & AMR_SMBOX_BUSYFLAG)
1362 return(EBUSY);
1363 AMR_SPOST_COMMAND(sc);
1364 return(0);
1365}
1366
1367/********************************************************************************
1368 * Claim any work that the controller has completed; acknowledge completion,
1369 * save details of the completion in (mbsave)
1370 */
1371static int
1372amr_quartz_get_work(struct amr_softc *sc, struct amr_mailbox *mbsave)
1373{
1374 int s, worked;
1375 u_int32_t outd;
1376
1377 debug_called(3);
1378
1379 worked = 0;
1380 s = splbio();
1381
1382 /* work waiting for us? */
1383 if ((outd = AMR_QGET_ODB(sc)) == AMR_QODB_READY) {
1384
1385 /* save mailbox, which contains a list of completed commands */
1386 bcopy((void *)(uintptr_t)(volatile void *)sc->amr_mailbox, mbsave, sizeof(*mbsave));
1387
1388 /* acknowledge interrupt */
1389 AMR_QPUT_ODB(sc, AMR_QODB_READY);
1390
1391 /* acknowledge that we have the commands */
1392 AMR_QPUT_IDB(sc, sc->amr_mailboxphys | AMR_QIDB_ACK);
1393
28 */
29
30/*
31 * Driver for the AMI MegaRaid family of controllers.
32 */
33
34#include <sys/param.h>
35#include <sys/systm.h>
36#include <sys/malloc.h>
37#include <sys/kernel.h>
38
39#include <dev/amr/amr_compat.h>
40#include <sys/bus.h>
41#include <sys/conf.h>
42#include <sys/devicestat.h>
43#include <sys/disk.h>
44#include <sys/stat.h>
45
46#include <machine/bus_memio.h>
47#include <machine/bus_pio.h>
48#include <machine/bus.h>
49#include <machine/resource.h>
50#include <machine/clock.h>
51#include <sys/rman.h>
52
53#include <pci/pcireg.h>
54#include <pci/pcivar.h>
55
56#include <dev/amr/amrio.h>
57#include <dev/amr/amrreg.h>
58#include <dev/amr/amrvar.h>
59#define AMR_DEFINE_TABLES
60#include <dev/amr/amr_tables.h>
61
62#define AMR_CDEV_MAJOR 132
63
64static d_open_t amr_open;
65static d_close_t amr_close;
66static d_ioctl_t amr_ioctl;
67
68static struct cdevsw amr_cdevsw = {
69 /* open */ amr_open,
70 /* close */ amr_close,
71 /* read */ noread,
72 /* write */ nowrite,
73 /* ioctl */ amr_ioctl,
74 /* poll */ nopoll,
75 /* mmap */ nommap,
76 /* strategy */ nostrategy,
77 /* name */ "amr",
78 /* maj */ AMR_CDEV_MAJOR,
79 /* dump */ nodump,
80 /* psize */ nopsize,
81 /* flags */ 0,
82 /* bmaj */ 254 /* XXX magic no-bdev */
83};
84
85/*
86 * Initialisation, bus interface.
87 */
88static void amr_startup(void *arg);
89
90/*
91 * Command wrappers
92 */
93static int amr_query_controller(struct amr_softc *sc);
94static void *amr_enquiry(struct amr_softc *sc, size_t bufsize,
95 u_int8_t cmd, u_int8_t cmdsub, u_int8_t cmdqual);
96static void amr_completeio(struct amr_command *ac);
97
98/*
99 * Command buffer allocation.
100 */
101static void amr_alloccmd_cluster(struct amr_softc *sc);
102static void amr_freecmd_cluster(struct amr_command_cluster *acc);
103
104/*
105 * Command processing.
106 */
107static int amr_bio_command(struct amr_softc *sc, struct amr_command **acp);
108static int amr_wait_command(struct amr_command *ac);
109static int amr_poll_command(struct amr_command *ac);
110static int amr_getslot(struct amr_command *ac);
111static void amr_mapcmd(struct amr_command *ac);
112static void amr_unmapcmd(struct amr_command *ac);
113static int amr_start(struct amr_command *ac);
114static void amr_complete(void *context, int pending);
115
116/*
117 * Status monitoring
118 */
119static void amr_periodic(void *data);
120
121/*
122 * Interface-specific shims
123 */
124static int amr_quartz_submit_command(struct amr_softc *sc);
125static int amr_quartz_get_work(struct amr_softc *sc, struct amr_mailbox *mbsave);
126
127static int amr_std_submit_command(struct amr_softc *sc);
128static int amr_std_get_work(struct amr_softc *sc, struct amr_mailbox *mbsave);
129static void amr_std_attach_mailbox(struct amr_softc *sc);
130
131#ifdef AMR_BOARD_INIT
132static int amr_quartz_init(struct amr_softc *sc);
133static int amr_std_init(struct amr_softc *sc);
134#endif
135
136/*
137 * Debugging
138 */
139static void amr_describe_controller(struct amr_softc *sc);
140#ifdef AMR_DEBUG
141static void amr_printcommand(struct amr_command *ac);
142#endif
143
144/********************************************************************************
145 ********************************************************************************
146 Inline Glue
147 ********************************************************************************
148 ********************************************************************************/
149
150/********************************************************************************
151 ********************************************************************************
152 Public Interfaces
153 ********************************************************************************
154 ********************************************************************************/
155
156/********************************************************************************
157 * Initialise the controller and softc.
158 */
159int
160amr_attach(struct amr_softc *sc)
161{
162
163 debug_called(1);
164
165 /*
166 * Initialise per-controller queues.
167 */
168 TAILQ_INIT(&sc->amr_completed);
169 TAILQ_INIT(&sc->amr_freecmds);
170 TAILQ_INIT(&sc->amr_cmd_clusters);
171 TAILQ_INIT(&sc->amr_ready);
172 bioq_init(&sc->amr_bioq);
173
174#if __FreeBSD_version >= 500005
175 /*
176 * Initialise command-completion task.
177 */
178 TASK_INIT(&sc->amr_task_complete, 0, amr_complete, sc);
179#endif
180
181 debug(2, "queue init done");
182
183 /*
184 * Configure for this controller type.
185 */
186 if (AMR_IS_QUARTZ(sc)) {
187 sc->amr_submit_command = amr_quartz_submit_command;
188 sc->amr_get_work = amr_quartz_get_work;
189 } else {
190 sc->amr_submit_command = amr_std_submit_command;
191 sc->amr_get_work = amr_std_get_work;
192 amr_std_attach_mailbox(sc);;
193 }
194
195#ifdef AMR_BOARD_INIT
196 if ((AMR_IS_QUARTZ(sc) ? amr_quartz_init(sc) : amr_std_init(sc))))
197 return(ENXIO);
198#endif
199
200 /*
201 * Quiz controller for features and limits.
202 */
203 if (amr_query_controller(sc))
204 return(ENXIO);
205
206 debug(2, "controller query complete");
207
208#ifdef AMR_SCSI_PASSTHROUGH
209 /*
210 * Attach our 'real' SCSI channels to CAM.
211 */
212 if (amr_cam_attach(sc))
213 return(ENXIO);
214 debug(2, "CAM attach done");
215#endif
216
217 /*
218 * Create the control device.
219 */
220 sc->amr_dev_t = make_dev(&amr_cdevsw, device_get_unit(sc->amr_dev), UID_ROOT, GID_OPERATOR,
221 S_IRUSR | S_IWUSR, "amr%d", device_get_unit(sc->amr_dev));
222 sc->amr_dev_t->si_drv1 = sc;
223
224 /*
225 * Schedule ourselves to bring the controller up once interrupts are
226 * available.
227 */
228 bzero(&sc->amr_ich, sizeof(struct intr_config_hook));
229 sc->amr_ich.ich_func = amr_startup;
230 sc->amr_ich.ich_arg = sc;
231 if (config_intrhook_establish(&sc->amr_ich) != 0) {
232 device_printf(sc->amr_dev, "can't establish configuration hook\n");
233 return(ENOMEM);
234 }
235
236 /*
237 * Print a little information about the controller.
238 */
239 amr_describe_controller(sc);
240
241 debug(2, "attach complete");
242 return(0);
243}
244
245/********************************************************************************
246 * Locate disk resources and attach children to them.
247 */
248static void
249amr_startup(void *arg)
250{
251 struct amr_softc *sc = (struct amr_softc *)arg;
252 struct amr_logdrive *dr;
253 int i, error;
254
255 debug_called(1);
256
257 /* pull ourselves off the intrhook chain */
258 config_intrhook_disestablish(&sc->amr_ich);
259
260 /* get up-to-date drive information */
261 if (amr_query_controller(sc)) {
262 device_printf(sc->amr_dev, "can't scan controller for drives\n");
263 return;
264 }
265
266 /* iterate over available drives */
267 for (i = 0, dr = &sc->amr_drive[0]; (i < AMR_MAXLD) && (dr->al_size != 0xffffffff); i++, dr++) {
268 /* are we already attached to this drive? */
269 if (dr->al_disk == 0) {
270 /* generate geometry information */
271 if (dr->al_size > 0x200000) { /* extended translation? */
272 dr->al_heads = 255;
273 dr->al_sectors = 63;
274 } else {
275 dr->al_heads = 64;
276 dr->al_sectors = 32;
277 }
278 dr->al_cylinders = dr->al_size / (dr->al_heads * dr->al_sectors);
279
280 dr->al_disk = device_add_child(sc->amr_dev, NULL, -1);
281 if (dr->al_disk == 0)
282 device_printf(sc->amr_dev, "device_add_child failed\n");
283 device_set_ivars(dr->al_disk, dr);
284 }
285 }
286
287 if ((error = bus_generic_attach(sc->amr_dev)) != 0)
288 device_printf(sc->amr_dev, "bus_generic_attach returned %d\n", error);
289
290 /* mark controller back up */
291 sc->amr_state &= ~AMR_STATE_SHUTDOWN;
292
293 /* interrupts will be enabled before we do anything more */
294 sc->amr_state |= AMR_STATE_INTEN;
295
296 /*
297 * Start the timeout routine.
298 */
299/* sc->amr_timeout = timeout(amr_periodic, sc, hz);*/
300
301 return;
302}
303
304/*******************************************************************************
305 * Free resources associated with a controller instance
306 */
307void
308amr_free(struct amr_softc *sc)
309{
310 struct amr_command_cluster *acc;
311
312#ifdef AMR_SCSI_PASSTHROUGH
313 /* detach from CAM */
314 amr_cam_detach(sc);
315#endif
316
317 /* cancel status timeout */
318 untimeout(amr_periodic, sc, sc->amr_timeout);
319
320 /* throw away any command buffers */
321 while ((acc = TAILQ_FIRST(&sc->amr_cmd_clusters)) != NULL) {
322 TAILQ_REMOVE(&sc->amr_cmd_clusters, acc, acc_link);
323 amr_freecmd_cluster(acc);
324 }
325}
326
327/*******************************************************************************
328 * Receive a bio structure from a child device and queue it on a particular
329 * disk resource, then poke the disk resource to start as much work as it can.
330 */
331int
332amr_submit_bio(struct amr_softc *sc, struct bio *bio)
333{
334 debug_called(2);
335
336 amr_enqueue_bio(sc, bio);
337 amr_startio(sc);
338 return(0);
339}
340
341/********************************************************************************
342 * Accept an open operation on the control device.
343 */
344int
345amr_open(dev_t dev, int flags, int fmt, struct proc *p)
346{
347 int unit = minor(dev);
348 struct amr_softc *sc = devclass_get_softc(amr_devclass, unit);
349
350 debug_called(1);
351
352 sc->amr_state |= AMR_STATE_OPEN;
353 return(0);
354}
355
356/********************************************************************************
357 * Accept the last close on the control device.
358 */
359int
360amr_close(dev_t dev, int flags, int fmt, struct proc *p)
361{
362 int unit = minor(dev);
363 struct amr_softc *sc = devclass_get_softc(amr_devclass, unit);
364
365 debug_called(1);
366
367 sc->amr_state &= ~AMR_STATE_OPEN;
368 return (0);
369}
370
371/********************************************************************************
372 * Handle controller-specific control operations.
373 */
374int
375amr_ioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, struct proc *p)
376{
377 struct amr_softc *sc = (struct amr_softc *)dev->si_drv1;
378 int *arg = (int *)addr;
379 struct amr_user_ioctl *au = (struct amr_user_ioctl *)addr;
380 struct amr_command *ac;
381 struct amr_mailbox_ioctl *mbi;
382 struct amr_passthrough *ap;
383 void *dp;
384 int error;
385
386 debug_called(1);
387
388 error = 0;
389 dp = NULL;
390 ap = NULL;
391 ac = NULL;
392 switch(cmd) {
393
394 case AMR_IO_VERSION:
395 debug(1, "AMR_IO_VERSION");
396 *arg = AMR_IO_VERSION_NUMBER;
397 break;
398
399 case AMR_IO_COMMAND:
400 debug(1, "AMR_IO_COMMAND");
401 /* handle inbound data buffer */
402 if (au->au_length != 0) {
403 if ((dp = malloc(au->au_length, M_DEVBUF, M_WAITOK)) == NULL) {
404 error = ENOMEM;
405 break;
406 }
407 if ((error = copyin(au->au_buffer, dp, au->au_length)) != 0)
408 break;
409 }
410
411 if ((ac = amr_alloccmd(sc)) == NULL) {
412 error = ENOMEM;
413 break;
414 }
415
416 /* handle SCSI passthrough command */
417 if (au->au_cmd[0] == AMR_CMD_PASS) {
418 if ((ap = malloc(sizeof(*ap), M_DEVBUF, M_WAITOK)) == NULL) {
419 error = ENOMEM;
420 break;
421 }
422 bzero(ap, sizeof(*ap));
423
424 /* copy cdb */
425 ap->ap_cdb_length = au->au_cmd[2];
426 bcopy(&au->au_cmd[3], &ap->ap_cdb[0], ap->ap_cdb_length);
427
428 /* build passthrough */
429 ap->ap_timeout = au->au_cmd[ap->ap_cdb_length + 3] & 0x07;
430 ap->ap_ars = (au->au_cmd[ap->ap_cdb_length + 3] & 0x08) ? 1 : 0;
431 ap->ap_islogical = (au->au_cmd[ap->ap_cdb_length + 3] & 0x80) ? 1 : 0;
432 ap->ap_logical_drive_no = au->au_cmd[ap->ap_cdb_length + 4];
433 ap->ap_channel = au->au_cmd[ap->ap_cdb_length + 5];
434 ap->ap_scsi_id = au->au_cmd[ap->ap_cdb_length + 6];
435 ap->ap_request_sense_length = 14;
436 /* XXX what about the request-sense area? does the caller want it? */
437
438 /* build command */
439 ac->ac_data = ap;
440 ac->ac_length = sizeof(*ap);
441 ac->ac_flags |= AMR_CMD_DATAOUT;
442 ac->ac_ccb_data = dp;
443 ac->ac_ccb_length = au->au_length;
444 if (au->au_direction & AMR_IO_READ)
445 ac->ac_flags |= AMR_CMD_CCB_DATAIN;
446 if (au->au_direction & AMR_IO_WRITE)
447 ac->ac_flags |= AMR_CMD_CCB_DATAOUT;
448
449 ac->ac_mailbox.mb_command = AMR_CMD_PASS;
450
451 } else {
452 /* direct command to controller */
453 mbi = (struct amr_mailbox_ioctl *)&ac->ac_mailbox;
454
455 /* copy pertinent mailbox items */
456 mbi->mb_command = au->au_cmd[0];
457 mbi->mb_channel = au->au_cmd[1];
458 mbi->mb_param = au->au_cmd[2];
459 mbi->mb_pad[0] = au->au_cmd[3];
460 mbi->mb_drive = au->au_cmd[4];
461
462 /* build the command */
463 ac->ac_data = dp;
464 ac->ac_length = au->au_length;
465 if (au->au_direction & AMR_IO_READ)
466 ac->ac_flags |= AMR_CMD_DATAIN;
467 if (au->au_direction & AMR_IO_WRITE)
468 ac->ac_flags |= AMR_CMD_DATAOUT;
469 }
470
471 /* run the command */
472 if ((error = amr_wait_command(ac)) != 0)
473 break;
474
475 /* copy out data and set status */
476 if (au->au_length != 0)
477 error = copyout(dp, au->au_buffer, au->au_length);
478 au->au_status = ac->ac_status;
479 break;
480
481 default:
482 debug(1, "unknown ioctl 0x%lx", cmd);
483 error = ENOIOCTL;
484 break;
485 }
486
487 if (dp != NULL)
488 free(dp, M_DEVBUF);
489 if (ap != NULL)
490 free(ap, M_DEVBUF);
491 if (ac != NULL)
492 amr_releasecmd(ac);
493 return(error);
494}
495
496/********************************************************************************
497 ********************************************************************************
498 Status Monitoring
499 ********************************************************************************
500 ********************************************************************************/
501
502/********************************************************************************
503 * Perform a periodic check of the controller status
504 */
505static void
506amr_periodic(void *data)
507{
508 struct amr_softc *sc = (struct amr_softc *)data;
509
510 debug_called(2);
511
512 /* XXX perform periodic status checks here */
513
514 /* compensate for missed interrupts */
515 amr_done(sc);
516
517 /* reschedule */
518 sc->amr_timeout = timeout(amr_periodic, sc, hz);
519}
520
521/********************************************************************************
522 ********************************************************************************
523 Command Wrappers
524 ********************************************************************************
525 ********************************************************************************/
526
527/********************************************************************************
528 * Interrogate the controller for the operational parameters we require.
529 */
530static int
531amr_query_controller(struct amr_softc *sc)
532{
533 struct amr_enquiry3 *aex;
534 struct amr_prodinfo *ap;
535 struct amr_enquiry *ae;
536 int ldrv;
537
538 /*
539 * If we haven't found the real limit yet, let us have a couple of commands in
540 * order to be able to probe.
541 */
542 if (sc->amr_maxio == 0)
543 sc->amr_maxio = 2;
544
545 /*
546 * Try to issue an ENQUIRY3 command
547 */
548 if ((aex = amr_enquiry(sc, 2048, AMR_CMD_CONFIG, AMR_CONFIG_ENQ3,
549 AMR_CONFIG_ENQ3_SOLICITED_FULL)) != NULL) {
550
551 /*
552 * Fetch current state of logical drives.
553 */
554 for (ldrv = 0; ldrv < aex->ae_numldrives; ldrv++) {
555 sc->amr_drive[ldrv].al_size = aex->ae_drivesize[ldrv];
556 sc->amr_drive[ldrv].al_state = aex->ae_drivestate[ldrv];
557 sc->amr_drive[ldrv].al_properties = aex->ae_driveprop[ldrv];
558 debug(2, " drive %d: %d state %x properties %x\n", ldrv, sc->amr_drive[ldrv].al_size,
559 sc->amr_drive[ldrv].al_state, sc->amr_drive[ldrv].al_properties);
560 }
561 free(aex, M_DEVBUF);
562
563 /*
564 * Get product info for channel count.
565 */
566 if ((ap = amr_enquiry(sc, 2048, AMR_CMD_CONFIG, AMR_CONFIG_PRODUCT_INFO, 0)) == NULL) {
567 device_printf(sc->amr_dev, "can't obtain product data from controller\n");
568 return(1);
569 }
570 sc->amr_maxdrives = 40;
571 sc->amr_maxchan = ap->ap_nschan;
572 sc->amr_maxio = ap->ap_maxio;
573 sc->amr_type |= AMR_TYPE_40LD;
574 free(ap, M_DEVBUF);
575
576 } else {
577
578 /* failed, try the 8LD ENQUIRY commands */
579 if ((ae = (struct amr_enquiry *)amr_enquiry(sc, 2048, AMR_CMD_EXT_ENQUIRY2, 0, 0)) == NULL) {
580 if ((ae = (struct amr_enquiry *)amr_enquiry(sc, 2048, AMR_CMD_ENQUIRY, 0, 0)) == NULL) {
581 device_printf(sc->amr_dev, "can't obtain configuration data from controller\n");
582 return(1);
583 }
584 ae->ae_signature = 0;
585 }
586
587 /*
588 * Fetch current state of logical drives.
589 */
590 for (ldrv = 0; ldrv < ae->ae_ldrv.al_numdrives; ldrv++) {
591 sc->amr_drive[ldrv].al_size = ae->ae_ldrv.al_size[ldrv];
592 sc->amr_drive[ldrv].al_state = ae->ae_ldrv.al_state[ldrv];
593 sc->amr_drive[ldrv].al_properties = ae->ae_ldrv.al_properties[ldrv];
594 debug(2, " drive %d: %d state %x properties %x\n", ldrv, sc->amr_drive[ldrv].al_size,
595 sc->amr_drive[ldrv].al_state, sc->amr_drive[ldrv].al_properties);
596 }
597
598 sc->amr_maxdrives = 8;
599 sc->amr_maxchan = ae->ae_adapter.aa_channels;
600 sc->amr_maxio = ae->ae_adapter.aa_maxio;
601 free(ae, M_DEVBUF);
602 }
603
604 /*
605 * Mark remaining drives as unused.
606 */
607 for (; ldrv < AMR_MAXLD; ldrv++)
608 sc->amr_drive[ldrv].al_size = 0xffffffff;
609
610 /*
611 * Cap the maximum number of outstanding I/Os. AMI's Linux driver doesn't trust
612 * the controller's reported value, and lockups have been seen when we do.
613 */
614 sc->amr_maxio = imin(sc->amr_maxio, AMR_LIMITCMD);
615
616 return(0);
617}
618
619/********************************************************************************
620 * Run a generic enquiry-style command.
621 */
622static void *
623amr_enquiry(struct amr_softc *sc, size_t bufsize, u_int8_t cmd, u_int8_t cmdsub, u_int8_t cmdqual)
624{
625 struct amr_command *ac;
626 void *result;
627 u_int8_t *mbox;
628 int error;
629
630 debug_called(1);
631
632 error = 1;
633 result = NULL;
634
635 /* get ourselves a command buffer */
636 if ((ac = amr_alloccmd(sc)) == NULL)
637 goto out;
638 /* allocate the response structure */
639 if ((result = malloc(bufsize, M_DEVBUF, M_NOWAIT)) == NULL)
640 goto out;
641 /* set command flags */
642 ac->ac_flags |= AMR_CMD_PRIORITY | AMR_CMD_DATAOUT;
643
644 /* point the command at our data */
645 ac->ac_data = result;
646 ac->ac_length = bufsize;
647
648 /* build the command proper */
649 mbox = (u_int8_t *)&ac->ac_mailbox; /* XXX want a real structure for this? */
650 mbox[0] = cmd;
651 mbox[2] = cmdsub;
652 mbox[3] = cmdqual;
653
654 /* can't assume that interrupts are going to work here, so play it safe */
655 if (amr_poll_command(ac))
656 goto out;
657 error = ac->ac_status;
658
659 out:
660 if (ac != NULL)
661 amr_releasecmd(ac);
662 if ((error != 0) && (result != NULL)) {
663 free(result, M_DEVBUF);
664 result = NULL;
665 }
666 return(result);
667}
668
669/********************************************************************************
670 * Flush the controller's internal cache, return status.
671 */
672int
673amr_flush(struct amr_softc *sc)
674{
675 struct amr_command *ac;
676 int error;
677
678 /* get ourselves a command buffer */
679 error = 1;
680 if ((ac = amr_alloccmd(sc)) == NULL)
681 goto out;
682 /* set command flags */
683 ac->ac_flags |= AMR_CMD_PRIORITY | AMR_CMD_DATAOUT;
684
685 /* build the command proper */
686 ac->ac_mailbox.mb_command = AMR_CMD_FLUSH;
687
688 /* we have to poll, as the system may be going down or otherwise damaged */
689 if (amr_poll_command(ac))
690 goto out;
691 error = ac->ac_status;
692
693 out:
694 if (ac != NULL)
695 amr_releasecmd(ac);
696 return(error);
697}
698
699/********************************************************************************
700 * Try to find I/O work for the controller from one or more of the work queues.
701 *
702 * We make the assumption that if the controller is not ready to take a command
703 * at some given time, it will generate an interrupt at some later time when
704 * it is.
705 */
706void
707amr_startio(struct amr_softc *sc)
708{
709 struct amr_command *ac;
710
711 /* spin until something prevents us from doing any work */
712 for (;;) {
713
714 /* try to get a ready command */
715 ac = amr_dequeue_ready(sc);
716
717 /* if that failed, build a command from a bio */
718 if (ac == NULL)
719 (void)amr_bio_command(sc, &ac);
720
721#ifdef AMR_SCSI_PASSTHROUGH
722 /* if that failed, build a command from a ccb */
723 if (ac == NULL)
724 (void)amr_cam_command(sc, &ac);
725#endif
726
727 /* if we don't have anything to do, give up */
728 if (ac == NULL)
729 break;
730
731 /* try to give the command to the controller; if this fails save it for later and give up */
732 if (amr_start(ac)) {
733 debug(2, "controller busy, command deferred");
734 amr_requeue_ready(ac); /* XXX schedule retry very soon? */
735 break;
736 }
737 }
738}
739
740/********************************************************************************
741 * Handle completion of an I/O command.
742 */
743static void
744amr_completeio(struct amr_command *ac)
745{
746 struct amr_softc *sc = ac->ac_sc;
747
748 if (ac->ac_status != AMR_STATUS_SUCCESS) { /* could be more verbose here? */
749 ac->ac_bio->bio_error = EIO;
750 ac->ac_bio->bio_flags |= BIO_ERROR;
751
752 device_printf(sc->amr_dev, "I/O error - 0x%x\n", ac->ac_status);
753/* amr_printcommand(ac);*/
754 }
755 amrd_intr(ac->ac_bio);
756 amr_releasecmd(ac);
757}
758
759/********************************************************************************
760 ********************************************************************************
761 Command Processing
762 ********************************************************************************
763 ********************************************************************************/
764
765/********************************************************************************
766 * Convert a bio off the top of the bio queue into a command.
767 */
768static int
769amr_bio_command(struct amr_softc *sc, struct amr_command **acp)
770{
771 struct amr_command *ac;
772 struct amrd_softc *amrd;
773 struct bio *bio;
774 int error;
775 int blkcount;
776 int driveno;
777 int cmd;
778
779 ac = NULL;
780 error = 0;
781
782 /* get a bio to work on */
783 if ((bio = amr_dequeue_bio(sc)) == NULL)
784 goto out;
785
786 /* get a command */
787 if ((ac = amr_alloccmd(sc)) == NULL) {
788 error = ENOMEM;
789 goto out;
790 }
791
792 /* connect the bio to the command */
793 ac->ac_complete = amr_completeio;
794 ac->ac_bio = bio;
795 ac->ac_data = bio->bio_data;
796 ac->ac_length = bio->bio_bcount;
797 if (BIO_IS_READ(bio)) {
798 ac->ac_flags |= AMR_CMD_DATAIN;
799 cmd = AMR_CMD_LREAD;
800 } else {
801 ac->ac_flags |= AMR_CMD_DATAOUT;
802 cmd = AMR_CMD_LWRITE;
803 }
804 amrd = (struct amrd_softc *)bio->bio_dev->si_drv1;
805 driveno = amrd->amrd_drive - sc->amr_drive;
806 blkcount = (bio->bio_bcount + AMR_BLKSIZE - 1) / AMR_BLKSIZE;
807
808 ac->ac_mailbox.mb_command = cmd;
809 ac->ac_mailbox.mb_blkcount = blkcount;
810 ac->ac_mailbox.mb_lba = bio->bio_pblkno;
811 ac->ac_mailbox.mb_drive = driveno;
812 /* we fill in the s/g related data when the command is mapped */
813
814 if ((bio->bio_pblkno + blkcount) > sc->amr_drive[driveno].al_size)
815 device_printf(sc->amr_dev, "I/O beyond end of unit (%u,%d > %u)\n",
816 bio->bio_pblkno, blkcount, sc->amr_drive[driveno].al_size);
817
818out:
819 if (error != 0) {
820 if (ac != NULL)
821 amr_releasecmd(ac);
822 if (bio != NULL) /* this breaks ordering... */
823 amr_enqueue_bio(sc, bio);
824 }
825 *acp = ac;
826 return(error);
827}
828
829/********************************************************************************
830 * Take a command, submit it to the controller and sleep until it completes
831 * or fails. Interrupts must be enabled, returns nonzero on error.
832 */
833static int
834amr_wait_command(struct amr_command *ac)
835{
836 struct amr_softc *sc = ac->ac_sc;
837 int error, count;
838
839 debug_called(1);
840
841 ac->ac_complete = NULL;
842 ac->ac_flags |= AMR_CMD_SLEEP;
843 if ((error = amr_start(ac)) != 0)
844 return(error);
845
846 count = 0;
847 /* XXX better timeout? */
848 while ((ac->ac_flags & AMR_CMD_BUSY) && (count < 30)) {
849 tsleep(ac, PRIBIO | PCATCH, "amrwcmd", hz);
850 }
851
852 if (ac->ac_status != 0) {
853 device_printf(sc->amr_dev, "I/O error - 0x%x\n", ac->ac_status);
854 return(EIO);
855 }
856 return(0);
857}
858
859/********************************************************************************
860 * Take a command, submit it to the controller and busy-wait for it to return.
861 * Returns nonzero on error. Can be safely called with interrupts enabled.
862 */
863static int
864amr_poll_command(struct amr_command *ac)
865{
866 struct amr_softc *sc = ac->ac_sc;
867 int error, count;
868
869 debug_called(2);
870
871 ac->ac_complete = NULL;
872 if ((error = amr_start(ac)) != 0)
873 return(error);
874
875 count = 0;
876 do {
877 /*
878 * Poll for completion, although the interrupt handler may beat us to it.
879 * Note that the timeout here is somewhat arbitrary.
880 */
881 amr_done(sc);
882 DELAY(1000);
883 } while ((ac->ac_flags & AMR_CMD_BUSY) && (count++ < 1000));
884 if (!(ac->ac_flags & AMR_CMD_BUSY)) {
885 error = 0;
886 } else {
887 /* XXX the slot is now marked permanently busy */
888 error = EIO;
889 device_printf(sc->amr_dev, "polled command timeout\n");
890 }
891 return(error);
892}
893
894/********************************************************************************
895 * Get a free command slot for a command if it doesn't already have one.
896 *
897 * May be safely called multiple times for a given command.
898 */
899static int
900amr_getslot(struct amr_command *ac)
901{
902 struct amr_softc *sc = ac->ac_sc;
903 int s, slot, limit, error;
904
905 debug_called(3);
906
907 /* if the command already has a slot, don't try to give it another one */
908 if (ac->ac_slot != 0)
909 return(0);
910
911 /* enforce slot usage limit */
912 limit = (ac->ac_flags & AMR_CMD_PRIORITY) ? sc->amr_maxio : sc->amr_maxio - 4;
913 if (sc->amr_busyslots > limit)
914 return(EBUSY);
915
916 /*
917 * Allocate a slot. XXX linear scan is slow
918 */
919 error = EBUSY;
920 s = splbio();
921 for (slot = 0; slot < sc->amr_maxio; slot++) {
922 if (sc->amr_busycmd[slot] == NULL) {
923 sc->amr_busycmd[slot] = ac;
924 sc->amr_busyslots++;
925 ac->ac_slot = slot;
926 error = 0;
927 break;
928 }
929 }
930 splx(s);
931
932 return(error);
933}
934
935/********************************************************************************
936 * Map/unmap (ac)'s data in the controller's addressable space as required.
937 *
938 * These functions may be safely called multiple times on a given command.
939 */
940static void
941amr_setup_dmamap(void *arg, bus_dma_segment_t *segs, int nsegments, int error)
942{
943 struct amr_command *ac = (struct amr_command *)arg;
944 struct amr_softc *sc = ac->ac_sc;
945 struct amr_sgentry *sg;
946 int i;
947
948 debug_called(3);
949
950 /* get base address of s/g table */
951 sg = sc->amr_sgtable + (ac->ac_slot * AMR_NSEG);
952
953 /* save data physical address */
954 ac->ac_dataphys = segs[0].ds_addr;
955
956 /* decide whether we need to populate the s/g table */
957 if (nsegments < 2) {
958 ac->ac_mailbox.mb_nsgelem = 0;
959 ac->ac_mailbox.mb_physaddr = ac->ac_dataphys;
960 } else {
961 ac->ac_mailbox.mb_nsgelem = nsegments;
962 ac->ac_mailbox.mb_physaddr = sc->amr_sgbusaddr + (ac->ac_slot * AMR_NSEG * sizeof(struct amr_sgentry));
963 for (i = 0; i < nsegments; i++, sg++) {
964 sg->sg_addr = segs[i].ds_addr;
965 sg->sg_count = segs[i].ds_len;
966 }
967 }
968}
969
970static void
971amr_setup_ccbmap(void *arg, bus_dma_segment_t *segs, int nsegments, int error)
972{
973 struct amr_command *ac = (struct amr_command *)arg;
974 struct amr_softc *sc = ac->ac_sc;
975 struct amr_sgentry *sg;
976 struct amr_passthrough *ap = (struct amr_passthrough *)ac->ac_data;
977 int i;
978
979 /* get base address of s/g table */
980 sg = sc->amr_sgtable + (ac->ac_slot * AMR_NSEG);
981
982 /* save s/g table information in passthrough */
983 ap->ap_no_sg_elements = nsegments;
984 ap->ap_data_transfer_address = sc->amr_sgbusaddr + (ac->ac_slot * AMR_NSEG * sizeof(struct amr_sgentry));
985
986 /* save pointer to passthrough in command XXX is this already done above? */
987 ac->ac_mailbox.mb_physaddr = ac->ac_dataphys;
988
989 debug(2, "slot %d %d segments at 0x%x, passthrough at 0x%x", ac->ac_slot,
990 ap->ap_no_sg_elements, ap->ap_data_transfer_address, ac->ac_dataphys);
991
992 /* populate s/g table (overwrites previous call which mapped the passthrough) */
993 for (i = 0; i < nsegments; i++, sg++) {
994 sg->sg_addr = segs[i].ds_addr;
995 sg->sg_count = segs[i].ds_len;
996 debug(2, " %d: 0x%x/%d", i, sg->sg_addr, sg->sg_count);
997 }
998}
999
1000static void
1001amr_mapcmd(struct amr_command *ac)
1002{
1003 struct amr_softc *sc = ac->ac_sc;
1004
1005 debug_called(2);
1006
1007 /* if the command involves data at all, and hasn't been mapped */
1008 if (!(ac->ac_flags & AMR_CMD_MAPPED)) {
1009
1010 if (ac->ac_data != NULL) {
1011 /* map the data buffers into bus space and build the s/g list */
1012 bus_dmamap_load(sc->amr_buffer_dmat, ac->ac_dmamap, ac->ac_data, ac->ac_length,
1013 amr_setup_dmamap, ac, 0);
1014 if (ac->ac_flags & AMR_CMD_DATAIN)
1015 bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_dmamap, BUS_DMASYNC_PREREAD);
1016 if (ac->ac_flags & AMR_CMD_DATAOUT)
1017 bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_dmamap, BUS_DMASYNC_PREWRITE);
1018 }
1019
1020 if (ac->ac_ccb_data != NULL) {
1021 bus_dmamap_load(sc->amr_buffer_dmat, ac->ac_ccb_dmamap, ac->ac_ccb_data, ac->ac_ccb_length,
1022 amr_setup_ccbmap, ac, 0);
1023 if (ac->ac_flags & AMR_CMD_CCB_DATAIN)
1024 bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_ccb_dmamap, BUS_DMASYNC_PREREAD);
1025 if (ac->ac_flags & AMR_CMD_CCB_DATAOUT)
1026 bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_ccb_dmamap, BUS_DMASYNC_PREWRITE);
1027 }
1028 ac->ac_flags |= AMR_CMD_MAPPED;
1029 }
1030}
1031
1032static void
1033amr_unmapcmd(struct amr_command *ac)
1034{
1035 struct amr_softc *sc = ac->ac_sc;
1036
1037 debug_called(2);
1038
1039 /* if the command involved data at all and was mapped */
1040 if (ac->ac_flags & AMR_CMD_MAPPED) {
1041
1042 if (ac->ac_data != NULL) {
1043 if (ac->ac_flags & AMR_CMD_DATAIN)
1044 bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_dmamap, BUS_DMASYNC_POSTREAD);
1045 if (ac->ac_flags & AMR_CMD_DATAOUT)
1046 bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_dmamap, BUS_DMASYNC_POSTWRITE);
1047 bus_dmamap_unload(sc->amr_buffer_dmat, ac->ac_dmamap);
1048 }
1049
1050 if (ac->ac_ccb_data != NULL) {
1051 if (ac->ac_flags & AMR_CMD_CCB_DATAIN)
1052 bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_ccb_dmamap, BUS_DMASYNC_POSTREAD);
1053 if (ac->ac_flags & AMR_CMD_CCB_DATAOUT)
1054 bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_ccb_dmamap, BUS_DMASYNC_POSTWRITE);
1055 bus_dmamap_unload(sc->amr_buffer_dmat, ac->ac_ccb_dmamap);
1056 }
1057 ac->ac_flags &= ~AMR_CMD_MAPPED;
1058 }
1059}
1060
1061/********************************************************************************
1062 * Take a command and give it to the controller, returns 0 if successful, or
1063 * EBUSY if the command should be retried later.
1064 */
1065static int
1066amr_start(struct amr_command *ac)
1067{
1068 struct amr_softc *sc = ac->ac_sc;
1069 int done, s, i;
1070
1071 debug_called(2);
1072
1073 /* mark command as busy so that polling consumer can tell */
1074 ac->ac_flags |= AMR_CMD_BUSY;
1075
1076 /* get a command slot (freed in amr_done) */
1077 if (amr_getslot(ac))
1078 return(EBUSY);
1079
1080 /* now we have a slot, we can map the command (unmapped in amr_complete) */
1081 amr_mapcmd(ac);
1082
1083 /* mark the new mailbox we are going to copy in as busy */
1084 ac->ac_mailbox.mb_busy = 1;
1085
1086 /* clear the poll/ack fields in the mailbox */
1087 sc->amr_mailbox->mb_poll = 0;
1088 sc->amr_mailbox->mb_ack = 0;
1089
1090 /*
1091 * Save the slot number so that we can locate this command when complete.
1092 * Note that ident = 0 seems to be special, so we don't use it.
1093 */
1094 ac->ac_mailbox.mb_ident = ac->ac_slot + 1;
1095
1096 /*
1097 * Spin waiting for the mailbox, give up after ~1 second. We expect the
1098 * controller to be able to handle our I/O.
1099 *
1100 * XXX perhaps we should wait for less time, and count on the deferred command
1101 * handling to deal with retries?
1102 */
1103 debug(2, "wait for mailbox");
1104 for (i = 10000, done = 0; (i > 0) && !done; i--) {
1105 s = splbio();
1106
1107 /* is the mailbox free? */
1108 if (sc->amr_mailbox->mb_busy == 0) {
1109 debug(2, "got mailbox");
1110 sc->amr_mailbox64->mb64_segment = 0;
1111 bcopy(&ac->ac_mailbox, (void *)(uintptr_t)(volatile void *)sc->amr_mailbox, AMR_MBOX_CMDSIZE);
1112 done = 1;
1113
1114 /* not free, spin waiting */
1115 } else {
1116 debug(3, "busy flag %x\n", sc->amr_mailbox->mb_busy);
1117 /* this is somewhat ugly */
1118 DELAY(100);
1119 }
1120 splx(s); /* drop spl to allow completion interrupts */
1121 }
1122
1123 /*
1124 * Now give the command to the controller
1125 */
1126 if (done) {
1127 if (sc->amr_submit_command(sc)) {
1128 /* the controller wasn't ready to take the command, forget that we tried to post it */
1129 sc->amr_mailbox->mb_busy = 0;
1130 return(EBUSY);
1131 }
1132 debug(2, "posted command");
1133 return(0);
1134 }
1135
1136 /*
1137 * The controller wouldn't take the command. Return the command as busy
1138 * so that it is retried later.
1139 */
1140 return(EBUSY);
1141}
1142
1143/********************************************************************************
1144 * Extract one or more completed commands from the controller (sc)
1145 *
1146 * Returns nonzero if any commands on the work queue were marked as completed.
1147 */
1148int
1149amr_done(struct amr_softc *sc)
1150{
1151 struct amr_command *ac;
1152 struct amr_mailbox mbox;
1153 int i, idx, result;
1154
1155 debug_called(2);
1156
1157 /* See if there's anything for us to do */
1158 result = 0;
1159
1160 /* loop collecting completed commands */
1161 for (;;) {
1162 /* poll for a completed command's identifier and status */
1163 if (sc->amr_get_work(sc, &mbox)) {
1164 result = 1;
1165
1166 /* iterate over completed commands in this result */
1167 for (i = 0; i < mbox.mb_nstatus; i++) {
1168 /* get pointer to busy command */
1169 idx = mbox.mb_completed[i] - 1;
1170 ac = sc->amr_busycmd[idx];
1171
1172 /* really a busy command? */
1173 if (ac != NULL) {
1174
1175 /* pull the command from the busy index */
1176 sc->amr_busycmd[idx] = NULL;
1177 sc->amr_busyslots--;
1178
1179 /* save status for later use */
1180 ac->ac_status = mbox.mb_status;
1181 amr_enqueue_completed(ac);
1182 debug(3, "completed command with status %x", mbox.mb_status);
1183 } else {
1184 device_printf(sc->amr_dev, "bad slot %d completed\n", idx);
1185 }
1186 }
1187 } else {
1188 break; /* no work */
1189 }
1190 }
1191
1192 /* if we've completed any commands, try posting some more */
1193 if (result)
1194 amr_startio(sc);
1195
1196 /* handle completion and timeouts */
1197#if __FreeBSD_version >= 500005
1198 if (sc->amr_state & AMR_STATE_INTEN)
1199 taskqueue_enqueue(taskqueue_swi, &sc->amr_task_complete);
1200 else
1201#endif
1202 amr_complete(sc, 0);
1203
1204 return(result);
1205}
1206
1207/********************************************************************************
1208 * Do completion processing on done commands on (sc)
1209 */
1210static void
1211amr_complete(void *context, int pending)
1212{
1213 struct amr_softc *sc = (struct amr_softc *)context;
1214 struct amr_command *ac;
1215
1216 debug_called(2);
1217
1218 /* pull completed commands off the queue */
1219 for (;;) {
1220 ac = amr_dequeue_completed(sc);
1221 if (ac == NULL)
1222 break;
1223
1224 /* unmap the command's data buffer */
1225 amr_unmapcmd(ac);
1226
1227 /* unbusy the command */
1228 ac->ac_flags &= ~AMR_CMD_BUSY;
1229
1230 /*
1231 * Is there a completion handler?
1232 */
1233 if (ac->ac_complete != NULL) {
1234 ac->ac_complete(ac);
1235
1236 /*
1237 * Is someone sleeping on this one?
1238 */
1239 } else if (ac->ac_flags & AMR_CMD_SLEEP) {
1240 wakeup(ac);
1241 }
1242 }
1243}
1244
1245/********************************************************************************
1246 ********************************************************************************
1247 Command Buffer Management
1248 ********************************************************************************
1249 ********************************************************************************/
1250
1251/********************************************************************************
1252 * Get a new command buffer.
1253 *
1254 * This may return NULL in low-memory cases.
1255 *
1256 * If possible, we recycle a command buffer that's been used before.
1257 */
1258struct amr_command *
1259amr_alloccmd(struct amr_softc *sc)
1260{
1261 struct amr_command *ac;
1262
1263 debug_called(3);
1264
1265 ac = amr_dequeue_free(sc);
1266 if (ac == NULL) {
1267 amr_alloccmd_cluster(sc);
1268 ac = amr_dequeue_free(sc);
1269 }
1270 if (ac == NULL)
1271 return(NULL);
1272
1273 /* clear out significant fields */
1274 ac->ac_slot = 0;
1275 ac->ac_status = 0;
1276 bzero(&ac->ac_mailbox, sizeof(struct amr_mailbox));
1277 ac->ac_flags = 0;
1278 ac->ac_bio = NULL;
1279 ac->ac_data = NULL;
1280 ac->ac_ccb_data = NULL;
1281 ac->ac_complete = NULL;
1282 return(ac);
1283}
1284
1285/********************************************************************************
1286 * Release a command buffer for recycling.
1287 */
1288void
1289amr_releasecmd(struct amr_command *ac)
1290{
1291 debug_called(3);
1292
1293 amr_enqueue_free(ac);
1294}
1295
1296/********************************************************************************
1297 * Allocate a new command cluster and initialise it.
1298 */
1299void
1300amr_alloccmd_cluster(struct amr_softc *sc)
1301{
1302 struct amr_command_cluster *acc;
1303 struct amr_command *ac;
1304 int s, i;
1305
1306 acc = malloc(AMR_CMD_CLUSTERSIZE, M_DEVBUF, M_NOWAIT);
1307 if (acc != NULL) {
1308 s = splbio();
1309 TAILQ_INSERT_TAIL(&sc->amr_cmd_clusters, acc, acc_link);
1310 splx(s);
1311 for (i = 0; i < AMR_CMD_CLUSTERCOUNT; i++) {
1312 ac = &acc->acc_command[i];
1313 bzero(ac, sizeof(*ac));
1314 ac->ac_sc = sc;
1315 if (!bus_dmamap_create(sc->amr_buffer_dmat, 0, &ac->ac_dmamap) &&
1316 !bus_dmamap_create(sc->amr_buffer_dmat, 0, &ac->ac_ccb_dmamap))
1317 amr_releasecmd(ac);
1318 }
1319 }
1320}
1321
1322/********************************************************************************
1323 * Free a command cluster
1324 */
1325void
1326amr_freecmd_cluster(struct amr_command_cluster *acc)
1327{
1328 struct amr_softc *sc = acc->acc_command[0].ac_sc;
1329 int i;
1330
1331 for (i = 0; i < AMR_CMD_CLUSTERCOUNT; i++)
1332 bus_dmamap_destroy(sc->amr_buffer_dmat, acc->acc_command[i].ac_dmamap);
1333 free(acc, M_DEVBUF);
1334}
1335
1336/********************************************************************************
1337 ********************************************************************************
1338 Interface-specific Shims
1339 ********************************************************************************
1340 ********************************************************************************/
1341
1342/********************************************************************************
1343 * Tell the controller that the mailbox contains a valid command
1344 */
1345static int
1346amr_quartz_submit_command(struct amr_softc *sc)
1347{
1348 debug_called(3);
1349
1350 if (AMR_QGET_IDB(sc) & AMR_QIDB_SUBMIT)
1351 return(EBUSY);
1352 AMR_QPUT_IDB(sc, sc->amr_mailboxphys | AMR_QIDB_SUBMIT);
1353 return(0);
1354}
1355
1356static int
1357amr_std_submit_command(struct amr_softc *sc)
1358{
1359 debug_called(3);
1360
1361 if (AMR_SGET_MBSTAT(sc) & AMR_SMBOX_BUSYFLAG)
1362 return(EBUSY);
1363 AMR_SPOST_COMMAND(sc);
1364 return(0);
1365}
1366
1367/********************************************************************************
1368 * Claim any work that the controller has completed; acknowledge completion,
1369 * save details of the completion in (mbsave)
1370 */
1371static int
1372amr_quartz_get_work(struct amr_softc *sc, struct amr_mailbox *mbsave)
1373{
1374 int s, worked;
1375 u_int32_t outd;
1376
1377 debug_called(3);
1378
1379 worked = 0;
1380 s = splbio();
1381
1382 /* work waiting for us? */
1383 if ((outd = AMR_QGET_ODB(sc)) == AMR_QODB_READY) {
1384
1385 /* save mailbox, which contains a list of completed commands */
1386 bcopy((void *)(uintptr_t)(volatile void *)sc->amr_mailbox, mbsave, sizeof(*mbsave));
1387
1388 /* acknowledge interrupt */
1389 AMR_QPUT_ODB(sc, AMR_QODB_READY);
1390
1391 /* acknowledge that we have the commands */
1392 AMR_QPUT_IDB(sc, sc->amr_mailboxphys | AMR_QIDB_ACK);
1393
1394#if AMR_QUARTZ_GOFASTER
1394#ifndef AMR_QUARTZ_GOFASTER
1395 /*
1396 * This waits for the controller to notice that we've taken the
1397 * command from it. It's very inefficient, and we shouldn't do it,
1398 * but if we remove this code, we stop completing commands under
1399 * load.
1400 *
1401 * Peter J says we shouldn't do this. The documentation says we
1402 * should. Who is right?
1403 */
1404 while(AMR_QGET_IDB(sc) & AMR_QIDB_ACK)
1405 ; /* XXX aiee! what if it dies? */
1406#endif
1407
1408 worked = 1; /* got some work */
1409 }
1410
1411 splx(s);
1412 return(worked);
1413}
1414
1415static int
1416amr_std_get_work(struct amr_softc *sc, struct amr_mailbox *mbsave)
1417{
1418 int s, worked;
1419 u_int8_t istat;
1420
1421 debug_called(3);
1422
1423 worked = 0;
1424 s = splbio();
1425
1426 /* check for valid interrupt status */
1427 istat = AMR_SGET_ISTAT(sc);
1428 if ((istat & AMR_SINTR_VALID) != 0) {
1429 AMR_SPUT_ISTAT(sc, istat); /* ack interrupt status */
1430
1431 /* save mailbox, which contains a list of completed commands */
1432 bcopy((void *)(uintptr_t)(volatile void *)sc->amr_mailbox, mbsave, sizeof(*mbsave));
1433
1434 AMR_SACK_INTERRUPT(sc); /* acknowledge we have the mailbox */
1435 worked = 1;
1436 }
1437
1438 splx(s);
1439 return(worked);
1440}
1441
1442/********************************************************************************
1443 * Notify the controller of the mailbox location.
1444 */
1445static void
1446amr_std_attach_mailbox(struct amr_softc *sc)
1447{
1448
1449 /* program the mailbox physical address */
1450 AMR_SBYTE_SET(sc, AMR_SMBOX_0, sc->amr_mailboxphys & 0xff);
1451 AMR_SBYTE_SET(sc, AMR_SMBOX_1, (sc->amr_mailboxphys >> 8) & 0xff);
1452 AMR_SBYTE_SET(sc, AMR_SMBOX_2, (sc->amr_mailboxphys >> 16) & 0xff);
1453 AMR_SBYTE_SET(sc, AMR_SMBOX_3, (sc->amr_mailboxphys >> 24) & 0xff);
1454 AMR_SBYTE_SET(sc, AMR_SMBOX_ENABLE, AMR_SMBOX_ADDR);
1455
1456 /* clear any outstanding interrupt and enable interrupts proper */
1457 AMR_SACK_INTERRUPT(sc);
1458 AMR_SENABLE_INTR(sc);
1459}
1460
1461#ifdef AMR_BOARD_INIT
1462/********************************************************************************
1463 * Initialise the controller
1464 */
1465static int
1466amr_quartz_init(struct amr_softc *sc)
1467{
1468 int status, ostatus;
1469
1470 device_printf(sc->amr_dev, "initial init status %x\n", AMR_QGET_INITSTATUS(sc));
1471
1472 AMR_QRESET(sc);
1473
1474 ostatus = 0xff;
1475 while ((status = AMR_QGET_INITSTATUS(sc)) != AMR_QINIT_DONE) {
1476 if (status != ostatus) {
1477 device_printf(sc->amr_dev, "(%x) %s\n", status, amr_describe_code(amr_table_qinit, status));
1478 ostatus = status;
1479 }
1480 switch (status) {
1481 case AMR_QINIT_NOMEM:
1482 return(ENOMEM);
1483
1484 case AMR_QINIT_SCAN:
1485 /* XXX we could print channel/target here */
1486 break;
1487 }
1488 }
1489 return(0);
1490}
1491
1492static int
1493amr_std_init(struct amr_softc *sc)
1494{
1495 int status, ostatus;
1496
1497 device_printf(sc->amr_dev, "initial init status %x\n", AMR_SGET_INITSTATUS(sc));
1498
1499 AMR_SRESET(sc);
1500
1501 ostatus = 0xff;
1502 while ((status = AMR_SGET_INITSTATUS(sc)) != AMR_SINIT_DONE) {
1503 if (status != ostatus) {
1504 device_printf(sc->amr_dev, "(%x) %s\n", status, amr_describe_code(amr_table_sinit, status));
1505 ostatus = status;
1506 }
1507 switch (status) {
1508 case AMR_SINIT_NOMEM:
1509 return(ENOMEM);
1510
1511 case AMR_SINIT_INPROG:
1512 /* XXX we could print channel/target here? */
1513 break;
1514 }
1515 }
1516 return(0);
1517}
1518#endif
1519
1520/********************************************************************************
1521 ********************************************************************************
1522 Debugging
1523 ********************************************************************************
1524 ********************************************************************************/
1525
1526/********************************************************************************
1527 * Identify the controller and print some information about it.
1528 */
1529static void
1530amr_describe_controller(struct amr_softc *sc)
1531{
1532 struct amr_prodinfo *ap;
1533 struct amr_enquiry *ae;
1534 char *prod;
1535
1536 /*
1537 * Try to get 40LD product info, which tells us what the card is labelled as.
1538 */
1539 if ((ap = amr_enquiry(sc, 2048, AMR_CMD_CONFIG, AMR_CONFIG_PRODUCT_INFO, 0)) != NULL) {
1540 device_printf(sc->amr_dev, "<%.80s> Firmware %.16s, BIOS %.16s, %dMB RAM\n",
1541 ap->ap_product, ap->ap_firmware, ap->ap_bios,
1542 ap->ap_memsize);
1543
1544 free(ap, M_DEVBUF);
1545 return;
1546 }
1547
1548 /*
1549 * Try 8LD extended ENQUIRY to get controller signature, and use lookup table.
1550 */
1551 if ((ae = (struct amr_enquiry *)amr_enquiry(sc, 2048, AMR_CMD_EXT_ENQUIRY2, 0, 0)) != NULL) {
1552 prod = amr_describe_code(amr_table_adaptertype, ae->ae_signature);
1553
1554 } else if ((ae = (struct amr_enquiry *)amr_enquiry(sc, 2048, AMR_CMD_ENQUIRY, 0, 0)) != NULL) {
1555
1556 /*
1557 * Try to work it out based on the PCI signatures.
1558 */
1559 switch (pci_get_device(sc->amr_dev)) {
1560 case 0x9010:
1561 prod = "Series 428";
1562 break;
1563 case 0x9060:
1564 prod = "Series 434";
1565 break;
1566 default:
1567 prod = "unknown controller";
1568 break;
1569 }
1570 } else {
1571 prod = "unsupported controller";
1572 }
1573 device_printf(sc->amr_dev, "<%s> Firmware %.4s, BIOS %.4s, %dMB RAM\n",
1574 prod, ae->ae_adapter.aa_firmware, ae->ae_adapter.aa_bios,
1575 ae->ae_adapter.aa_memorysize);
1576 free(ae, M_DEVBUF);
1577}
1578
1579#ifdef AMR_DEBUG
1580/********************************************************************************
1581 * Print the command (ac) in human-readable format
1582 */
1583static void
1584amr_printcommand(struct amr_command *ac)
1585{
1586 struct amr_softc *sc = ac->ac_sc;
1587 struct amr_sgentry *sg;
1588 int i;
1589
1590 device_printf(sc->amr_dev, "cmd %x ident %d drive %d\n",
1591 ac->ac_mailbox.mb_command, ac->ac_mailbox.mb_ident, ac->ac_mailbox.mb_drive);
1592 device_printf(sc->amr_dev, "blkcount %d lba %d\n",
1593 ac->ac_mailbox.mb_blkcount, ac->ac_mailbox.mb_lba);
1594 device_printf(sc->amr_dev, "virtaddr %p length %lu\n", ac->ac_data, (unsigned long)ac->ac_length);
1595 device_printf(sc->amr_dev, "sg physaddr %08x nsg %d\n",
1596 ac->ac_mailbox.mb_physaddr, ac->ac_mailbox.mb_nsgelem);
1597 device_printf(sc->amr_dev, "ccb %p bio %p\n", ac->ac_ccb_data, ac->ac_bio);
1598
1599 /* get base address of s/g table */
1600 sg = sc->amr_sgtable + (ac->ac_slot * AMR_NSEG);
1601 for (i = 0; i < ac->ac_mailbox.mb_nsgelem; i++, sg++)
1602 device_printf(sc->amr_dev, " %x/%d\n", sg->sg_addr, sg->sg_count);
1603}
1604#endif
1395 /*
1396 * This waits for the controller to notice that we've taken the
1397 * command from it. It's very inefficient, and we shouldn't do it,
1398 * but if we remove this code, we stop completing commands under
1399 * load.
1400 *
1401 * Peter J says we shouldn't do this. The documentation says we
1402 * should. Who is right?
1403 */
1404 while(AMR_QGET_IDB(sc) & AMR_QIDB_ACK)
1405 ; /* XXX aiee! what if it dies? */
1406#endif
1407
1408 worked = 1; /* got some work */
1409 }
1410
1411 splx(s);
1412 return(worked);
1413}
1414
1415static int
1416amr_std_get_work(struct amr_softc *sc, struct amr_mailbox *mbsave)
1417{
1418 int s, worked;
1419 u_int8_t istat;
1420
1421 debug_called(3);
1422
1423 worked = 0;
1424 s = splbio();
1425
1426 /* check for valid interrupt status */
1427 istat = AMR_SGET_ISTAT(sc);
1428 if ((istat & AMR_SINTR_VALID) != 0) {
1429 AMR_SPUT_ISTAT(sc, istat); /* ack interrupt status */
1430
1431 /* save mailbox, which contains a list of completed commands */
1432 bcopy((void *)(uintptr_t)(volatile void *)sc->amr_mailbox, mbsave, sizeof(*mbsave));
1433
1434 AMR_SACK_INTERRUPT(sc); /* acknowledge we have the mailbox */
1435 worked = 1;
1436 }
1437
1438 splx(s);
1439 return(worked);
1440}
1441
1442/********************************************************************************
1443 * Notify the controller of the mailbox location.
1444 */
1445static void
1446amr_std_attach_mailbox(struct amr_softc *sc)
1447{
1448
1449 /* program the mailbox physical address */
1450 AMR_SBYTE_SET(sc, AMR_SMBOX_0, sc->amr_mailboxphys & 0xff);
1451 AMR_SBYTE_SET(sc, AMR_SMBOX_1, (sc->amr_mailboxphys >> 8) & 0xff);
1452 AMR_SBYTE_SET(sc, AMR_SMBOX_2, (sc->amr_mailboxphys >> 16) & 0xff);
1453 AMR_SBYTE_SET(sc, AMR_SMBOX_3, (sc->amr_mailboxphys >> 24) & 0xff);
1454 AMR_SBYTE_SET(sc, AMR_SMBOX_ENABLE, AMR_SMBOX_ADDR);
1455
1456 /* clear any outstanding interrupt and enable interrupts proper */
1457 AMR_SACK_INTERRUPT(sc);
1458 AMR_SENABLE_INTR(sc);
1459}
1460
1461#ifdef AMR_BOARD_INIT
1462/********************************************************************************
1463 * Initialise the controller
1464 */
1465static int
1466amr_quartz_init(struct amr_softc *sc)
1467{
1468 int status, ostatus;
1469
1470 device_printf(sc->amr_dev, "initial init status %x\n", AMR_QGET_INITSTATUS(sc));
1471
1472 AMR_QRESET(sc);
1473
1474 ostatus = 0xff;
1475 while ((status = AMR_QGET_INITSTATUS(sc)) != AMR_QINIT_DONE) {
1476 if (status != ostatus) {
1477 device_printf(sc->amr_dev, "(%x) %s\n", status, amr_describe_code(amr_table_qinit, status));
1478 ostatus = status;
1479 }
1480 switch (status) {
1481 case AMR_QINIT_NOMEM:
1482 return(ENOMEM);
1483
1484 case AMR_QINIT_SCAN:
1485 /* XXX we could print channel/target here */
1486 break;
1487 }
1488 }
1489 return(0);
1490}
1491
1492static int
1493amr_std_init(struct amr_softc *sc)
1494{
1495 int status, ostatus;
1496
1497 device_printf(sc->amr_dev, "initial init status %x\n", AMR_SGET_INITSTATUS(sc));
1498
1499 AMR_SRESET(sc);
1500
1501 ostatus = 0xff;
1502 while ((status = AMR_SGET_INITSTATUS(sc)) != AMR_SINIT_DONE) {
1503 if (status != ostatus) {
1504 device_printf(sc->amr_dev, "(%x) %s\n", status, amr_describe_code(amr_table_sinit, status));
1505 ostatus = status;
1506 }
1507 switch (status) {
1508 case AMR_SINIT_NOMEM:
1509 return(ENOMEM);
1510
1511 case AMR_SINIT_INPROG:
1512 /* XXX we could print channel/target here? */
1513 break;
1514 }
1515 }
1516 return(0);
1517}
1518#endif
1519
1520/********************************************************************************
1521 ********************************************************************************
1522 Debugging
1523 ********************************************************************************
1524 ********************************************************************************/
1525
1526/********************************************************************************
1527 * Identify the controller and print some information about it.
1528 */
1529static void
1530amr_describe_controller(struct amr_softc *sc)
1531{
1532 struct amr_prodinfo *ap;
1533 struct amr_enquiry *ae;
1534 char *prod;
1535
1536 /*
1537 * Try to get 40LD product info, which tells us what the card is labelled as.
1538 */
1539 if ((ap = amr_enquiry(sc, 2048, AMR_CMD_CONFIG, AMR_CONFIG_PRODUCT_INFO, 0)) != NULL) {
1540 device_printf(sc->amr_dev, "<%.80s> Firmware %.16s, BIOS %.16s, %dMB RAM\n",
1541 ap->ap_product, ap->ap_firmware, ap->ap_bios,
1542 ap->ap_memsize);
1543
1544 free(ap, M_DEVBUF);
1545 return;
1546 }
1547
1548 /*
1549 * Try 8LD extended ENQUIRY to get controller signature, and use lookup table.
1550 */
1551 if ((ae = (struct amr_enquiry *)amr_enquiry(sc, 2048, AMR_CMD_EXT_ENQUIRY2, 0, 0)) != NULL) {
1552 prod = amr_describe_code(amr_table_adaptertype, ae->ae_signature);
1553
1554 } else if ((ae = (struct amr_enquiry *)amr_enquiry(sc, 2048, AMR_CMD_ENQUIRY, 0, 0)) != NULL) {
1555
1556 /*
1557 * Try to work it out based on the PCI signatures.
1558 */
1559 switch (pci_get_device(sc->amr_dev)) {
1560 case 0x9010:
1561 prod = "Series 428";
1562 break;
1563 case 0x9060:
1564 prod = "Series 434";
1565 break;
1566 default:
1567 prod = "unknown controller";
1568 break;
1569 }
1570 } else {
1571 prod = "unsupported controller";
1572 }
1573 device_printf(sc->amr_dev, "<%s> Firmware %.4s, BIOS %.4s, %dMB RAM\n",
1574 prod, ae->ae_adapter.aa_firmware, ae->ae_adapter.aa_bios,
1575 ae->ae_adapter.aa_memorysize);
1576 free(ae, M_DEVBUF);
1577}
1578
1579#ifdef AMR_DEBUG
1580/********************************************************************************
1581 * Print the command (ac) in human-readable format
1582 */
1583static void
1584amr_printcommand(struct amr_command *ac)
1585{
1586 struct amr_softc *sc = ac->ac_sc;
1587 struct amr_sgentry *sg;
1588 int i;
1589
1590 device_printf(sc->amr_dev, "cmd %x ident %d drive %d\n",
1591 ac->ac_mailbox.mb_command, ac->ac_mailbox.mb_ident, ac->ac_mailbox.mb_drive);
1592 device_printf(sc->amr_dev, "blkcount %d lba %d\n",
1593 ac->ac_mailbox.mb_blkcount, ac->ac_mailbox.mb_lba);
1594 device_printf(sc->amr_dev, "virtaddr %p length %lu\n", ac->ac_data, (unsigned long)ac->ac_length);
1595 device_printf(sc->amr_dev, "sg physaddr %08x nsg %d\n",
1596 ac->ac_mailbox.mb_physaddr, ac->ac_mailbox.mb_nsgelem);
1597 device_printf(sc->amr_dev, "ccb %p bio %p\n", ac->ac_ccb_data, ac->ac_bio);
1598
1599 /* get base address of s/g table */
1600 sg = sc->amr_sgtable + (ac->ac_slot * AMR_NSEG);
1601 for (i = 0; i < ac->ac_mailbox.mb_nsgelem; i++, sg++)
1602 device_printf(sc->amr_dev, " %x/%d\n", sg->sg_addr, sg->sg_count);
1603}
1604#endif