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