1 /*- 2 * Written by: David Jeffery 3 * Copyright (c) 2002 Adaptec Inc. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 28 #include <sys/cdefs.h> 29 __FBSDID("$FreeBSD$"); 30 31 #include <dev/ips/ips.h> 32 #include <sys/stat.h> 33 #include <sys/time.h> 34 #include <machine/clock.h> 35 36 static d_open_t ips_open; 37 static d_close_t ips_close; 38 static d_ioctl_t ips_ioctl; 39 40 #define IPS_CDEV_MAJOR 175 41 static struct cdevsw ips_cdevsw = { 42 .d_open = ips_open, 43 .d_close = ips_close, 44 .d_ioctl = ips_ioctl, 45 .d_name = "ips", 46 .d_maj = IPS_CDEV_MAJOR, 47 }; 48 49 50 static int ips_open(dev_t dev, int flags, int fmt, struct thread *td) 51 { 52 ips_softc_t *sc = dev->si_drv1; 53 sc->state |= IPS_DEV_OPEN; 54 return 0; 55 } 56 57 static int ips_close(dev_t dev, int flags, int fmt, struct thread *td) 58 { 59 ips_softc_t *sc = dev->si_drv1; 60 sc->state &= ~IPS_DEV_OPEN; 61 62 return 0; 63 } 64 65 static int ips_ioctl(dev_t dev, u_long command, caddr_t addr, int32_t flags, struct thread *td) 66 { 67 ips_softc_t *sc; 68 69 sc = dev->si_drv1; 70 return ips_ioctl_request(sc, command, addr, flags); 71 } 72 73 static void ips_cmd_dmaload(void *cmdptr, bus_dma_segment_t *segments,int segnum, int error) 74 { 75 ips_command_t *command = cmdptr; 76 PRINTF(10, "ips: in ips_cmd_dmaload\n"); 77 if(!error) 78 command->command_phys_addr = segments[0].ds_addr; 79 80 } 81 82 /* is locking needed? what locking guarentees are there on removal? */ 83 static __inline__ int ips_cmdqueue_free(ips_softc_t *sc) 84 { 85 int i, error = -1; 86 intrmask_t mask = splbio(); 87 if(!sc->used_commands){ 88 for(i = 0; i < sc->max_cmds; i++){ 89 if(!(sc->commandarray[i].command_phys_addr)) 90 continue; 91 bus_dmamap_unload(sc->command_dmatag, 92 sc->commandarray[i].command_dmamap); 93 bus_dmamem_free(sc->command_dmatag, 94 sc->commandarray[i].command_buffer, 95 sc->commandarray[i].command_dmamap); 96 } 97 error = 0; 98 sc->state |= IPS_OFFLINE; 99 } 100 splx(mask); 101 return error; 102 } 103 104 /* places all ips command structs on the free command queue. No locking as if someone else tries 105 * to access this during init, we have bigger problems */ 106 static __inline__ int ips_cmdqueue_init(ips_softc_t *sc) 107 { 108 int i; 109 ips_command_t *command; 110 SLIST_INIT(&sc->free_cmd_list); 111 STAILQ_INIT(&sc->cmd_wait_list); 112 for(i = 0; i < sc->max_cmds; i++){ 113 sc->commandarray[i].id = i; 114 sc->commandarray[i].sc = sc; 115 SLIST_INSERT_HEAD(&sc->free_cmd_list, &sc->commandarray[i], 116 next); 117 } 118 for(i = 0; i < sc->max_cmds; i++){ 119 command = &sc->commandarray[i]; 120 if(bus_dmamem_alloc(sc->command_dmatag,&command->command_buffer, 121 BUS_DMA_NOWAIT, &command->command_dmamap)) 122 goto error; 123 bus_dmamap_load(sc->command_dmatag, command->command_dmamap, 124 command->command_buffer,IPS_COMMAND_LEN, 125 ips_cmd_dmaload, command, BUS_DMA_NOWAIT); 126 if(!command->command_phys_addr){ 127 bus_dmamem_free(sc->command_dmatag, 128 command->command_buffer, command->command_dmamap); 129 goto error; 130 } 131 } 132 sc->state &= ~IPS_OFFLINE; 133 return 0; 134 error: 135 ips_cmdqueue_free(sc); 136 return ENOMEM; 137 } 138 139 static int ips_add_waiting_command(ips_softc_t *sc, int (*callback)(ips_command_t *), void *data, unsigned long flags) 140 { 141 intrmask_t mask; 142 ips_command_t *command; 143 ips_wait_list_t *waiter; 144 unsigned long memflags = 0; 145 if(IPS_NOWAIT_FLAG & flags) 146 memflags = M_NOWAIT; 147 waiter = malloc(sizeof(ips_wait_list_t), M_DEVBUF, memflags); 148 if(!waiter) 149 return ENOMEM; 150 mask = splbio(); 151 if(sc->state & IPS_OFFLINE){ 152 splx(mask); 153 return EIO; 154 } 155 command = SLIST_FIRST(&sc->free_cmd_list); 156 if(command && !(sc->state & IPS_TIMEOUT)){ 157 SLIST_REMOVE_HEAD(&sc->free_cmd_list, next); 158 (sc->used_commands)++; 159 splx(mask); 160 clear_ips_command(command); 161 bzero(command->command_buffer, IPS_COMMAND_LEN); 162 free(waiter, M_DEVBUF); 163 command->arg = data; 164 return callback(command); 165 } 166 DEVICE_PRINTF(1, sc->dev, "adding command to the wait queue\n"); 167 waiter->callback = callback; 168 waiter->data = data; 169 STAILQ_INSERT_TAIL(&sc->cmd_wait_list, waiter, next); 170 splx(mask); 171 return 0; 172 } 173 174 static void ips_run_waiting_command(ips_softc_t *sc) 175 { 176 ips_wait_list_t *waiter; 177 ips_command_t *command; 178 int (*callback)(ips_command_t*); 179 intrmask_t mask; 180 181 mask = splbio(); 182 waiter = STAILQ_FIRST(&sc->cmd_wait_list); 183 command = SLIST_FIRST(&sc->free_cmd_list); 184 if(!waiter || !command){ 185 splx(mask); 186 return; 187 } 188 DEVICE_PRINTF(1, sc->dev, "removing command from wait queue\n"); 189 SLIST_REMOVE_HEAD(&sc->free_cmd_list, next); 190 STAILQ_REMOVE_HEAD(&sc->cmd_wait_list, next); 191 (sc->used_commands)++; 192 splx(mask); 193 clear_ips_command(command); 194 bzero(command->command_buffer, IPS_COMMAND_LEN); 195 command->arg = waiter->data; 196 callback = waiter->callback; 197 free(waiter, M_DEVBUF); 198 callback(command); 199 return; 200 } 201 /* returns a free command struct if one is available. 202 * It also blanks out anything that may be a wild pointer/value. 203 * Also, command buffers are not freed. They are 204 * small so they are saved and kept dmamapped and loaded. 205 */ 206 int ips_get_free_cmd(ips_softc_t *sc, int (*callback)(ips_command_t *), void *data, unsigned long flags) 207 { 208 intrmask_t mask; 209 ips_command_t *command; 210 mask = splbio(); 211 212 if(sc->state & IPS_OFFLINE){ 213 splx(mask); 214 return EIO; 215 } 216 command = SLIST_FIRST(&sc->free_cmd_list); 217 if(!command || (sc->state & IPS_TIMEOUT)){ 218 splx(mask); 219 if(flags & IPS_NOWAIT_FLAG) 220 return EAGAIN; 221 return ips_add_waiting_command(sc, callback, data, flags); 222 } 223 SLIST_REMOVE_HEAD(&sc->free_cmd_list, next); 224 (sc->used_commands)++; 225 splx(mask); 226 clear_ips_command(command); 227 bzero(command->command_buffer, IPS_COMMAND_LEN); 228 command->arg = data; 229 return callback(command); 230 } 231 232 /* adds a command back to the free command queue */ 233 void ips_insert_free_cmd(ips_softc_t *sc, ips_command_t *command) 234 { 235 intrmask_t mask; 236 mask = splbio(); 237 SLIST_INSERT_HEAD(&sc->free_cmd_list, command, next); 238 (sc->used_commands)--; 239 splx(mask); 240 if(!(sc->state & IPS_TIMEOUT)) 241 ips_run_waiting_command(sc); 242 } 243 244 static int ips_diskdev_init(ips_softc_t *sc) 245 { 246 int i; 247 for(i=0; i < IPS_MAX_NUM_DRIVES; i++){ 248 if(sc->drives[i].state & IPS_LD_OKAY){ 249 sc->diskdev[i] = device_add_child(sc->dev, NULL, -1); 250 device_set_ivars(sc->diskdev[i],(void *)(uintptr_t) i); 251 } 252 } 253 if(bus_generic_attach(sc->dev)){ 254 device_printf(sc->dev, "Attaching bus failed\n"); 255 } 256 return 0; 257 } 258 259 static int ips_diskdev_free(ips_softc_t *sc) 260 { 261 int i; 262 int error = 0; 263 for(i = 0; i < IPS_MAX_NUM_DRIVES; i++){ 264 if(sc->diskdev[i]) 265 error = device_delete_child(sc->dev, sc->diskdev[i]); 266 if(error) 267 return error; 268 } 269 bus_generic_detach(sc->dev); 270 return 0; 271 } 272 273 /* ips_timeout is periodically called to make sure no commands sent 274 * to the card have become stuck. If it finds a stuck command, it 275 * sets a flag so the driver won't start any more commands and then 276 * is periodically called to see if all outstanding commands have 277 * either finished or timed out. Once timed out, an attempt to 278 * reinitialize the card is made. If that fails, the driver gives 279 * up and declares the card dead. */ 280 static void ips_timeout(void *arg) 281 { 282 intrmask_t mask; 283 ips_softc_t *sc = arg; 284 int i, state = 0; 285 ips_command_t *command; 286 command = &sc->commandarray[0]; 287 mask = splbio(); 288 for(i = 0; i < sc->max_cmds; i++){ 289 if(!command[i].timeout){ 290 continue; 291 } 292 command[i].timeout--; 293 if(!command[i].timeout){ 294 if(!(sc->state & IPS_TIMEOUT)){ 295 sc->state |= IPS_TIMEOUT; 296 device_printf(sc->dev, "WARNING: command timeout. Adapter is in toaster mode, resetting to known state\n"); 297 } 298 command[i].status.value = IPS_ERROR_STATUS; 299 command[i].callback(&command[i]); 300 /* hmm, this should be enough cleanup */ 301 } else 302 state = 1; 303 } 304 if(!state && (sc->state & IPS_TIMEOUT)){ 305 if(sc->ips_adapter_reinit(sc, 1)){ 306 device_printf(sc->dev, "AIEE! adapter reset failed, giving up and going home! Have a nice day.\n"); 307 sc->state |= IPS_OFFLINE; 308 sc->state &= ~IPS_TIMEOUT; 309 /* Grr, I hate this solution. I run waiting commands 310 one at a time and error them out just before they 311 would go to the card. This sucks. */ 312 } else 313 sc->state &= ~IPS_TIMEOUT; 314 ips_run_waiting_command(sc); 315 } 316 if (sc->state != IPS_OFFLINE) 317 sc->timer = timeout(ips_timeout, sc, 10*hz); 318 splx(mask); 319 } 320 321 /* check card and initialize it */ 322 int ips_adapter_init(ips_softc_t *sc) 323 { 324 int i; 325 DEVICE_PRINTF(1,sc->dev, "initializing\n"); 326 if (bus_dma_tag_create( /* parent */ sc->adapter_dmatag, 327 /* alignemnt */ 1, 328 /* boundary */ 0, 329 /* lowaddr */ BUS_SPACE_MAXADDR_32BIT, 330 /* highaddr */ BUS_SPACE_MAXADDR, 331 /* filter */ NULL, 332 /* filterarg */ NULL, 333 /* maxsize */ IPS_COMMAND_LEN + 334 IPS_MAX_SG_LEN, 335 /* numsegs */ 1, 336 /* maxsegsize*/ IPS_COMMAND_LEN + 337 IPS_MAX_SG_LEN, 338 /* flags */ 0, 339 /* lockfunc */ busdma_lock_mutex, 340 /* lockarg */ &Giant, 341 &sc->command_dmatag) != 0) { 342 device_printf(sc->dev, "can't alloc command dma tag\n"); 343 goto error; 344 } 345 if (bus_dma_tag_create( /* parent */ sc->adapter_dmatag, 346 /* alignemnt */ 1, 347 /* boundary */ 0, 348 /* lowaddr */ BUS_SPACE_MAXADDR_32BIT, 349 /* highaddr */ BUS_SPACE_MAXADDR, 350 /* filter */ NULL, 351 /* filterarg */ NULL, 352 /* maxsize */ IPS_MAX_IOBUF_SIZE, 353 /* numsegs */ IPS_MAX_SG_ELEMENTS, 354 /* maxsegsize*/ IPS_MAX_IOBUF_SIZE, 355 /* flags */ 0, 356 /* lockfunc */ busdma_lock_mutex, 357 /* lockarg */ &Giant, 358 &sc->sg_dmatag) != 0) { 359 device_printf(sc->dev, "can't alloc SG dma tag\n"); 360 goto error; 361 } 362 /* create one command buffer until we know how many commands this card 363 can handle */ 364 sc->max_cmds = 1; 365 ips_cmdqueue_init(sc); 366 callout_handle_init(&sc->timer); 367 368 if(sc->ips_adapter_reinit(sc, 0)) 369 goto error; 370 371 mtx_init(&sc->cmd_mtx, "ips command mutex", NULL, MTX_DEF); 372 if ((i = ips_get_adapter_info(sc)) != 0) { 373 device_printf(sc->dev, "failed to get adapter configuration data from device (%d)\n", i); 374 goto error; 375 } 376 if ((i = ips_get_drive_info(sc)) != 0) { 377 device_printf(sc->dev, "failed to get drive configuration data from device (%d)\n", i); 378 goto error; 379 } 380 ips_update_nvram(sc); /* no error check as failure doesn't matter */ 381 382 ips_cmdqueue_free(sc); 383 if(sc->adapter_info.max_concurrent_cmds) 384 sc->max_cmds = min(128, sc->adapter_info.max_concurrent_cmds); 385 else 386 sc->max_cmds = 32; 387 if(ips_cmdqueue_init(sc)){ 388 device_printf(sc->dev, "failed to initialize command buffers\n"); 389 goto error; 390 } 391 sc->device_file = make_dev(&ips_cdevsw, device_get_unit(sc->dev), UID_ROOT, GID_OPERATOR, 392 S_IRUSR | S_IWUSR, "ips%d", device_get_unit(sc->dev)); 393 sc->device_file->si_drv1 = sc; 394 ips_diskdev_init(sc); 395 sc->timer = timeout(ips_timeout, sc, 10*hz); 396 return 0; 397 398 error: 399 ips_adapter_free(sc); 400 return ENXIO; 401 } 402 403 /* see if we should reinitialize the card and wait for it to timeout or complete initialization */ 404 int ips_morpheus_reinit(ips_softc_t *sc, int force) 405 { 406 u_int32_t tmp; 407 int i; 408 409 tmp = ips_read_4(sc, MORPHEUS_REG_OISR); 410 if(!force && (ips_read_4(sc, MORPHEUS_REG_OMR0) >= IPS_POST1_OK) && 411 (ips_read_4(sc, MORPHEUS_REG_OMR1) != 0xdeadbeef) && !tmp){ 412 ips_write_4(sc, MORPHEUS_REG_OIMR, 0); 413 return 0; 414 } 415 ips_write_4(sc, MORPHEUS_REG_OIMR, 0xff); 416 ips_read_4(sc, MORPHEUS_REG_OIMR); 417 418 device_printf(sc->dev, "resetting adapter, this may take up to 5 minutes\n"); 419 ips_write_4(sc, MORPHEUS_REG_IDR, 0x80000000); 420 DELAY(5000000); 421 pci_read_config(sc->dev, 0, 4); 422 423 tmp = ips_read_4(sc, MORPHEUS_REG_OISR); 424 for(i = 0; i < 45 && !(tmp & MORPHEUS_BIT_POST1); i++){ 425 DELAY(1000000); 426 DEVICE_PRINTF(2, sc->dev, "post1: %d\n", i); 427 tmp = ips_read_4(sc, MORPHEUS_REG_OISR); 428 } 429 if(tmp & MORPHEUS_BIT_POST1) 430 ips_write_4(sc, MORPHEUS_REG_OISR, MORPHEUS_BIT_POST1); 431 432 if( i == 45 || ips_read_4(sc, MORPHEUS_REG_OMR0) < IPS_POST1_OK){ 433 device_printf(sc->dev,"Adapter error during initialization.\n"); 434 return 1; 435 } 436 for(i = 0; i < 240 && !(tmp & MORPHEUS_BIT_POST2); i++){ 437 DELAY(1000000); 438 DEVICE_PRINTF(2, sc->dev, "post2: %d\n", i); 439 tmp = ips_read_4(sc, MORPHEUS_REG_OISR); 440 } 441 if(tmp & MORPHEUS_BIT_POST2) 442 ips_write_4(sc, MORPHEUS_REG_OISR, MORPHEUS_BIT_POST2); 443 444 if(i == 240 || !ips_read_4(sc, MORPHEUS_REG_OMR1)){ 445 device_printf(sc->dev, "adapter failed config check\n"); 446 return 1; 447 } 448 ips_write_4(sc, MORPHEUS_REG_OIMR, 0); 449 if(force && ips_clear_adapter(sc)){ 450 device_printf(sc->dev, "adapter clear failed\n"); 451 return 1; 452 } 453 return 0; 454 } 455 456 /* clean up so we can unload the driver. */ 457 int ips_adapter_free(ips_softc_t *sc) 458 { 459 int error = 0; 460 intrmask_t mask; 461 if(sc->state & IPS_DEV_OPEN) 462 return EBUSY; 463 if((error = ips_diskdev_free(sc))) 464 return error; 465 if(ips_cmdqueue_free(sc)){ 466 device_printf(sc->dev, 467 "trying to exit when command queue is not empty!\n"); 468 return EBUSY; 469 } 470 DEVICE_PRINTF(1, sc->dev, "free\n"); 471 mask = splbio(); 472 untimeout(ips_timeout, sc, sc->timer); 473 splx(mask); 474 if (mtx_initialized(&sc->cmd_mtx)) 475 mtx_destroy(&sc->cmd_mtx); 476 477 if(sc->sg_dmatag) 478 bus_dma_tag_destroy(sc->sg_dmatag); 479 if(sc->command_dmatag) 480 bus_dma_tag_destroy(sc->command_dmatag); 481 if(sc->device_file) 482 destroy_dev(sc->device_file); 483 return 0; 484 } 485 486 void ips_morpheus_intr(void *void_sc) 487 { 488 ips_softc_t *sc = (ips_softc_t *)void_sc; 489 u_int32_t oisr, iisr; 490 int cmdnumber; 491 ips_cmd_status_t status; 492 493 iisr =ips_read_4(sc, MORPHEUS_REG_IISR); 494 oisr =ips_read_4(sc, MORPHEUS_REG_OISR); 495 PRINTF(9,"interrupt registers in:%x out:%x\n",iisr, oisr); 496 if(!(oisr & MORPHEUS_BIT_CMD_IRQ)){ 497 DEVICE_PRINTF(2,sc->dev, "got a non-command irq\n"); 498 return; 499 } 500 while((status.value = ips_read_4(sc, MORPHEUS_REG_OQPR)) != 0xffffffff){ 501 cmdnumber = status.fields.command_id; 502 sc->commandarray[cmdnumber].status.value = status.value; 503 sc->commandarray[cmdnumber].timeout = 0; 504 sc->commandarray[cmdnumber].callback(&(sc->commandarray[cmdnumber])); 505 506 507 DEVICE_PRINTF(9,sc->dev, "got command %d\n", cmdnumber); 508 } 509 return; 510 } 511 512 void ips_issue_morpheus_cmd(ips_command_t *command) 513 { 514 intrmask_t mask = splbio(); 515 /* hmmm, is there a cleaner way to do this? */ 516 if(command->sc->state & IPS_OFFLINE){ 517 splx(mask); 518 command->status.value = IPS_ERROR_STATUS; 519 command->callback(command); 520 return; 521 } 522 command->timeout = 10; 523 ips_write_4(command->sc, MORPHEUS_REG_IQPR, command->command_phys_addr); 524 splx(mask); 525 } 526 527 static void ips_copperhead_queue_callback(void *queueptr, bus_dma_segment_t *segments,int segnum, int error) 528 { 529 ips_copper_queue_t *queue = queueptr; 530 if(error){ 531 return; 532 } 533 queue->base_phys_addr = segments[0].ds_addr; 534 } 535 536 static int ips_copperhead_queue_init(ips_softc_t *sc) 537 { 538 int error; 539 bus_dma_tag_t dmatag; 540 bus_dmamap_t dmamap; 541 if (bus_dma_tag_create( /* parent */ sc->adapter_dmatag, 542 /* alignemnt */ 1, 543 /* boundary */ 0, 544 /* lowaddr */ BUS_SPACE_MAXADDR_32BIT, 545 /* highaddr */ BUS_SPACE_MAXADDR, 546 /* filter */ NULL, 547 /* filterarg */ NULL, 548 /* maxsize */ sizeof(ips_copper_queue_t), 549 /* numsegs */ 1, 550 /* maxsegsize*/ sizeof(ips_copper_queue_t), 551 /* flags */ 0, 552 /* lockfunc */ busdma_lock_mutex, 553 /* lockarg */ &Giant, 554 &dmatag) != 0) { 555 device_printf(sc->dev, "can't alloc dma tag for statue queue\n"); 556 error = ENOMEM; 557 goto exit; 558 } 559 if(bus_dmamem_alloc(dmatag, (void *)&(sc->copper_queue), 560 BUS_DMA_NOWAIT, &dmamap)){ 561 error = ENOMEM; 562 goto exit; 563 } 564 bzero(sc->copper_queue, sizeof(ips_copper_queue_t)); 565 sc->copper_queue->dmatag = dmatag; 566 sc->copper_queue->dmamap = dmamap; 567 sc->copper_queue->nextstatus = 1; 568 bus_dmamap_load(dmatag, dmamap, 569 &(sc->copper_queue->status[0]), IPS_MAX_CMD_NUM * 4, 570 ips_copperhead_queue_callback, sc->copper_queue, 571 BUS_DMA_NOWAIT); 572 if(sc->copper_queue->base_phys_addr == 0){ 573 error = ENOMEM; 574 goto exit; 575 } 576 ips_write_4(sc, COPPER_REG_SQSR, sc->copper_queue->base_phys_addr); 577 ips_write_4(sc, COPPER_REG_SQER, sc->copper_queue->base_phys_addr + 578 IPS_MAX_CMD_NUM * 4); 579 ips_write_4(sc, COPPER_REG_SQHR, sc->copper_queue->base_phys_addr + 4); 580 ips_write_4(sc, COPPER_REG_SQTR, sc->copper_queue->base_phys_addr); 581 582 583 return 0; 584 exit: 585 bus_dmamem_free(dmatag, sc->copper_queue, dmamap); 586 bus_dma_tag_destroy(dmatag); 587 return error; 588 } 589 590 /* see if we should reinitialize the card and wait for it to timeout or complete initialization FIXME */ 591 int ips_copperhead_reinit(ips_softc_t *sc, int force) 592 { 593 int i, j; 594 u_int32_t postcode = 0, configstatus = 0; 595 ips_write_1(sc, COPPER_REG_SCPR, 0x80); 596 ips_write_1(sc, COPPER_REG_SCPR, 0); 597 device_printf(sc->dev, "reinitializing adapter, this could take several minutes.\n"); 598 for(j = 0; j < 2; j++){ 599 postcode <<= 8; 600 for(i = 0; i < 45; i++){ 601 if(ips_read_1(sc, COPPER_REG_HISR) & COPPER_GHI_BIT){ 602 postcode |= ips_read_1(sc, COPPER_REG_ISPR); 603 ips_write_1(sc, COPPER_REG_HISR, 604 COPPER_GHI_BIT); 605 break; 606 } else 607 DELAY(1000000); 608 } 609 if(i == 45) 610 return 1; 611 } 612 for(j = 0; j < 2; j++){ 613 configstatus <<= 8; 614 for(i = 0; i < 240; i++){ 615 if(ips_read_1(sc, COPPER_REG_HISR) & COPPER_GHI_BIT){ 616 configstatus |= ips_read_1(sc, COPPER_REG_ISPR); 617 ips_write_1(sc, COPPER_REG_HISR, 618 COPPER_GHI_BIT); 619 break; 620 } else 621 DELAY(1000000); 622 } 623 if(i == 240) 624 return 1; 625 } 626 for(i = 0; i < 240; i++){ 627 if(!(ips_read_1(sc, COPPER_REG_CBSP) & COPPER_OP_BIT)){ 628 break; 629 } else 630 DELAY(1000000); 631 } 632 if(i == 240) 633 return 1; 634 ips_write_2(sc, COPPER_REG_CCCR, 0x1000 | COPPER_ILE_BIT); 635 ips_write_1(sc, COPPER_REG_SCPR, COPPER_EBM_BIT); 636 ips_copperhead_queue_init(sc); 637 ips_write_1(sc, COPPER_REG_HISR, COPPER_GHI_BIT); 638 i = ips_read_1(sc, COPPER_REG_SCPR); 639 ips_write_1(sc, COPPER_REG_HISR, COPPER_EI_BIT); 640 if(!configstatus){ 641 device_printf(sc->dev, "adapter initialization failed\n"); 642 return 1; 643 } 644 if(force && ips_clear_adapter(sc)){ 645 device_printf(sc->dev, "adapter clear failed\n"); 646 return 1; 647 } 648 return 0; 649 } 650 static u_int32_t ips_copperhead_cmd_status(ips_softc_t *sc) 651 { 652 intrmask_t mask; 653 u_int32_t value; 654 int statnum = sc->copper_queue->nextstatus++; 655 if(sc->copper_queue->nextstatus == IPS_MAX_CMD_NUM) 656 sc->copper_queue->nextstatus = 0; 657 mask = splbio(); 658 value = sc->copper_queue->status[statnum]; 659 ips_write_4(sc, COPPER_REG_SQTR, sc->copper_queue->base_phys_addr + 660 4 * statnum); 661 splx(mask); 662 return value; 663 } 664 665 666 void ips_copperhead_intr(void *void_sc) 667 { 668 ips_softc_t *sc = (ips_softc_t *)void_sc; 669 int cmdnumber; 670 ips_cmd_status_t status; 671 672 while(ips_read_1(sc, COPPER_REG_HISR) & COPPER_SCE_BIT){ 673 status.value = ips_copperhead_cmd_status(sc); 674 cmdnumber = status.fields.command_id; 675 sc->commandarray[cmdnumber].status.value = status.value; 676 sc->commandarray[cmdnumber].timeout = 0; 677 sc->commandarray[cmdnumber].callback(&(sc->commandarray[cmdnumber])); 678 PRINTF(9, "ips: got command %d\n", cmdnumber); 679 } 680 return; 681 } 682 683 void ips_issue_copperhead_cmd(ips_command_t *command) 684 { 685 int i; 686 intrmask_t mask = splbio(); 687 /* hmmm, is there a cleaner way to do this? */ 688 if(command->sc->state & IPS_OFFLINE){ 689 splx(mask); 690 command->status.value = IPS_ERROR_STATUS; 691 command->callback(command); 692 return; 693 } 694 command->timeout = 10; 695 for(i = 0; ips_read_4(command->sc, COPPER_REG_CCCR) & COPPER_SEM_BIT; 696 i++ ){ 697 if( i == 20){ 698 printf("sem bit still set, can't send a command\n"); 699 splx(mask); 700 return; 701 } 702 DELAY(500);/* need to do a delay here */ 703 } 704 ips_write_4(command->sc, COPPER_REG_CCSAR, command->command_phys_addr); 705 ips_write_2(command->sc, COPPER_REG_CCCR, COPPER_CMD_START); 706 splx(mask); 707 } 708 709