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