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