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