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 *) 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 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 &sc->command_dmatag) != 0) { 340 device_printf(sc->dev, "can't alloc command dma tag\n"); 341 goto error; 342 } 343 if (bus_dma_tag_create( /* parent */ sc->adapter_dmatag, 344 /* alignemnt */ 1, 345 /* boundary */ 0, 346 /* lowaddr */ BUS_SPACE_MAXADDR_32BIT, 347 /* highaddr */ BUS_SPACE_MAXADDR, 348 /* filter */ NULL, 349 /* filterarg */ NULL, 350 /* maxsize */ IPS_MAX_IOBUF_SIZE, 351 /* numsegs */ IPS_MAX_SG_ELEMENTS, 352 /* maxsegsize*/ IPS_MAX_IOBUF_SIZE, 353 /* flags */ 0, 354 &sc->sg_dmatag) != 0) { 355 device_printf(sc->dev, "can't alloc SG dma tag\n"); 356 goto error; 357 } 358 /* create one command buffer until we know how many commands this card 359 can handle */ 360 sc->max_cmds = 1; 361 ips_cmdqueue_init(sc); 362 363 if(sc->ips_adapter_reinit(sc, 0)) 364 goto error; 365 366 mtx_init(&sc->cmd_mtx, "ips command mutex", NULL, MTX_DEF); 367 if(ips_get_adapter_info(sc) || ips_get_drive_info(sc)){ 368 device_printf(sc->dev, "failed to get configuration data from device\n"); 369 goto error; 370 } 371 ips_update_nvram(sc); /* no error check as failure doesn't matter */ 372 373 ips_cmdqueue_free(sc); 374 if(sc->adapter_info.max_concurrent_cmds) 375 sc->max_cmds = min(128, sc->adapter_info.max_concurrent_cmds); 376 else 377 sc->max_cmds = 32; 378 if(ips_cmdqueue_init(sc)){ 379 device_printf(sc->dev, "failed to initialize command buffers\n"); 380 goto error; 381 } 382 sc->device_file = make_dev(&ips_cdevsw, device_get_unit(sc->dev), UID_ROOT, GID_OPERATOR, 383 S_IRUSR | S_IWUSR, "ips%d", device_get_unit(sc->dev)); 384 sc->device_file->si_drv1 = sc; 385 ips_diskdev_init(sc); 386 sc->timer = timeout(ips_timeout, sc, 10*hz); 387 return 0; 388 389 error: 390 ips_adapter_free(sc); 391 return ENXIO; 392 } 393 394 /* see if we should reinitialize the card and wait for it to timeout or complete initialization */ 395 int ips_morpheus_reinit(ips_softc_t *sc, int force) 396 { 397 u_int32_t tmp; 398 int i; 399 400 tmp = ips_read_4(sc, MORPHEUS_REG_OISR); 401 if(!force && (ips_read_4(sc, MORPHEUS_REG_OMR0) >= IPS_POST1_OK) && 402 (ips_read_4(sc, MORPHEUS_REG_OMR1) != 0xdeadbeef) && !tmp){ 403 ips_write_4(sc, MORPHEUS_REG_OIMR, 0); 404 return 0; 405 } 406 ips_write_4(sc, MORPHEUS_REG_OIMR, 0xff); 407 ips_read_4(sc, MORPHEUS_REG_OIMR); 408 409 device_printf(sc->dev, "resetting adapter, this may take up to 5 minutes\n"); 410 ips_write_4(sc, MORPHEUS_REG_IDR, 0x80000000); 411 DELAY(5000000); 412 pci_read_config(sc->dev, 0, 4); 413 414 tmp = ips_read_4(sc, MORPHEUS_REG_OISR); 415 for(i = 0; i < 45 && !(tmp & MORPHEUS_BIT_POST1); i++){ 416 DELAY(1000000); 417 DEVICE_PRINTF(2, sc->dev, "post1: %d\n", i); 418 tmp = ips_read_4(sc, MORPHEUS_REG_OISR); 419 } 420 if(tmp & MORPHEUS_BIT_POST1) 421 ips_write_4(sc, MORPHEUS_REG_OISR, MORPHEUS_BIT_POST1); 422 423 if( i == 45 || ips_read_4(sc, MORPHEUS_REG_OMR0) < IPS_POST1_OK){ 424 device_printf(sc->dev,"Adapter error during initialization.\n"); 425 return 1; 426 } 427 for(i = 0; i < 240 && !(tmp & MORPHEUS_BIT_POST2); i++){ 428 DELAY(1000000); 429 DEVICE_PRINTF(2, sc->dev, "post2: %d\n", i); 430 tmp = ips_read_4(sc, MORPHEUS_REG_OISR); 431 } 432 if(tmp & MORPHEUS_BIT_POST2) 433 ips_write_4(sc, MORPHEUS_REG_OISR, MORPHEUS_BIT_POST2); 434 435 if(i == 240 || !ips_read_4(sc, MORPHEUS_REG_OMR1)){ 436 device_printf(sc->dev, "adapter failed config check\n"); 437 return 1; 438 } 439 ips_write_4(sc, MORPHEUS_REG_OIMR, 0); 440 if(force && ips_clear_adapter(sc)){ 441 device_printf(sc->dev, "adapter clear failed\n"); 442 return 1; 443 } 444 return 0; 445 } 446 447 /* clean up so we can unload the driver. */ 448 int ips_adapter_free(ips_softc_t *sc) 449 { 450 int error = 0; 451 intrmask_t mask; 452 if(sc->state & IPS_DEV_OPEN) 453 return EBUSY; 454 if((error = ips_diskdev_free(sc))) 455 return error; 456 if(ips_cmdqueue_free(sc)){ 457 device_printf(sc->dev, 458 "trying to exit when command queue is not empty!\n"); 459 return EBUSY; 460 } 461 DEVICE_PRINTF(1, sc->dev, "free\n"); 462 mask = splbio(); 463 untimeout(ips_timeout, sc, sc->timer); 464 splx(mask); 465 if (mtx_initialized(&sc->cmd_mtx)) 466 mtx_destroy(&sc->cmd_mtx); 467 468 if(sc->sg_dmatag) 469 bus_dma_tag_destroy(sc->sg_dmatag); 470 if(sc->command_dmatag) 471 bus_dma_tag_destroy(sc->command_dmatag); 472 if(sc->device_file) 473 destroy_dev(sc->device_file); 474 return 0; 475 } 476 477 void ips_morpheus_intr(void *void_sc) 478 { 479 ips_softc_t *sc = (ips_softc_t *)void_sc; 480 u_int32_t oisr, iisr; 481 int cmdnumber; 482 ips_cmd_status_t status; 483 484 iisr =ips_read_4(sc, MORPHEUS_REG_IISR); 485 oisr =ips_read_4(sc, MORPHEUS_REG_OISR); 486 PRINTF(9,"interrupt registers in:%x out:%x\n",iisr, oisr); 487 if(!(oisr & MORPHEUS_BIT_CMD_IRQ)){ 488 DEVICE_PRINTF(2,sc->dev, "got a non-command irq\n"); 489 return; 490 } 491 while((status.value = ips_read_4(sc, MORPHEUS_REG_OQPR)) != 0xffffffff){ 492 cmdnumber = status.fields.command_id; 493 sc->commandarray[cmdnumber].status.value = status.value; 494 sc->commandarray[cmdnumber].timeout = 0; 495 sc->commandarray[cmdnumber].callback(&(sc->commandarray[cmdnumber])); 496 497 498 DEVICE_PRINTF(9,sc->dev, "got command %d\n", cmdnumber); 499 } 500 return; 501 } 502 503 void ips_issue_morpheus_cmd(ips_command_t *command) 504 { 505 intrmask_t mask = splbio(); 506 /* hmmm, is there a cleaner way to do this? */ 507 if(command->sc->state & IPS_OFFLINE){ 508 splx(mask); 509 command->status.value = IPS_ERROR_STATUS; 510 command->callback(command); 511 return; 512 } 513 command->timeout = 10; 514 ips_write_4(command->sc, MORPHEUS_REG_IQPR, command->command_phys_addr); 515 splx(mask); 516 } 517 518 static void ips_copperhead_queue_callback(void *queueptr, bus_dma_segment_t *segments,int segnum, int error) 519 { 520 ips_copper_queue_t *queue = queueptr; 521 if(error){ 522 return; 523 } 524 queue->base_phys_addr = segments[0].ds_addr; 525 } 526 527 static int ips_copperhead_queue_init(ips_softc_t *sc) 528 { 529 int error; 530 bus_dma_tag_t dmatag; 531 bus_dmamap_t dmamap; 532 if (bus_dma_tag_create( /* parent */ sc->adapter_dmatag, 533 /* alignemnt */ 1, 534 /* boundary */ 0, 535 /* lowaddr */ BUS_SPACE_MAXADDR_32BIT, 536 /* highaddr */ BUS_SPACE_MAXADDR, 537 /* filter */ NULL, 538 /* filterarg */ NULL, 539 /* maxsize */ sizeof(ips_copper_queue_t), 540 /* numsegs */ 1, 541 /* maxsegsize*/ sizeof(ips_copper_queue_t), 542 /* flags */ 0, 543 &dmatag) != 0) { 544 device_printf(sc->dev, "can't alloc dma tag for statue queue\n"); 545 error = ENOMEM; 546 goto exit; 547 } 548 if(bus_dmamem_alloc(dmatag, (void *)&(sc->copper_queue), 549 BUS_DMA_NOWAIT, &dmamap)){ 550 error = ENOMEM; 551 goto exit; 552 } 553 bzero(sc->copper_queue, sizeof(ips_copper_queue_t)); 554 sc->copper_queue->dmatag = dmatag; 555 sc->copper_queue->dmamap = dmamap; 556 sc->copper_queue->nextstatus = 1; 557 bus_dmamap_load(dmatag, dmamap, 558 &(sc->copper_queue->status[0]), IPS_MAX_CMD_NUM * 4, 559 ips_copperhead_queue_callback, sc->copper_queue, 560 BUS_DMA_NOWAIT); 561 if(sc->copper_queue->base_phys_addr == 0){ 562 error = ENOMEM; 563 goto exit; 564 } 565 ips_write_4(sc, COPPER_REG_SQSR, sc->copper_queue->base_phys_addr); 566 ips_write_4(sc, COPPER_REG_SQER, sc->copper_queue->base_phys_addr + 567 IPS_MAX_CMD_NUM * 4); 568 ips_write_4(sc, COPPER_REG_SQHR, sc->copper_queue->base_phys_addr + 4); 569 ips_write_4(sc, COPPER_REG_SQTR, sc->copper_queue->base_phys_addr); 570 571 572 return 0; 573 exit: 574 bus_dmamem_free(dmatag, sc->copper_queue, dmamap); 575 bus_dma_tag_destroy(dmatag); 576 return error; 577 } 578 579 /* see if we should reinitialize the card and wait for it to timeout or complete initialization FIXME */ 580 int ips_copperhead_reinit(ips_softc_t *sc, int force) 581 { 582 int i, j; 583 u_int32_t postcode = 0, configstatus = 0; 584 ips_write_1(sc, COPPER_REG_SCPR, 0x80); 585 ips_write_1(sc, COPPER_REG_SCPR, 0); 586 device_printf(sc->dev, "reinitializing adapter, this could take several minutes.\n"); 587 for(j = 0; j < 2; j++){ 588 postcode <<= 8; 589 for(i = 0; i < 45; i++){ 590 if(ips_read_1(sc, COPPER_REG_HISR) & COPPER_GHI_BIT){ 591 postcode |= ips_read_1(sc, COPPER_REG_ISPR); 592 ips_write_1(sc, COPPER_REG_HISR, 593 COPPER_GHI_BIT); 594 break; 595 } else 596 DELAY(1000000); 597 } 598 if(i == 45) 599 return 1; 600 } 601 for(j = 0; j < 2; j++){ 602 configstatus <<= 8; 603 for(i = 0; i < 240; i++){ 604 if(ips_read_1(sc, COPPER_REG_HISR) & COPPER_GHI_BIT){ 605 configstatus |= ips_read_1(sc, COPPER_REG_ISPR); 606 ips_write_1(sc, COPPER_REG_HISR, 607 COPPER_GHI_BIT); 608 break; 609 } else 610 DELAY(1000000); 611 } 612 if(i == 240) 613 return 1; 614 } 615 for(i = 0; i < 240; i++){ 616 if(!(ips_read_1(sc, COPPER_REG_CBSP) & COPPER_OP_BIT)){ 617 break; 618 } else 619 DELAY(1000000); 620 } 621 if(i == 240) 622 return 1; 623 ips_write_2(sc, COPPER_REG_CCCR, 0x1000 | COPPER_ILE_BIT); 624 ips_write_1(sc, COPPER_REG_SCPR, COPPER_EBM_BIT); 625 ips_copperhead_queue_init(sc); 626 ips_write_1(sc, COPPER_REG_HISR, COPPER_GHI_BIT); 627 i = ips_read_1(sc, COPPER_REG_SCPR); 628 ips_write_1(sc, COPPER_REG_HISR, COPPER_EI_BIT); 629 if(!configstatus){ 630 device_printf(sc->dev, "adapter initialization failed\n"); 631 return 1; 632 } 633 if(force && ips_clear_adapter(sc)){ 634 device_printf(sc->dev, "adapter clear failed\n"); 635 return 1; 636 } 637 return 0; 638 } 639 static u_int32_t ips_copperhead_cmd_status(ips_softc_t *sc) 640 { 641 intrmask_t mask; 642 u_int32_t value; 643 int statnum = sc->copper_queue->nextstatus++; 644 if(sc->copper_queue->nextstatus == IPS_MAX_CMD_NUM) 645 sc->copper_queue->nextstatus = 0; 646 mask = splbio(); 647 value = sc->copper_queue->status[statnum]; 648 ips_write_4(sc, COPPER_REG_SQTR, sc->copper_queue->base_phys_addr + 649 4 * statnum); 650 splx(mask); 651 return value; 652 } 653 654 655 void ips_copperhead_intr(void *void_sc) 656 { 657 ips_softc_t *sc = (ips_softc_t *)void_sc; 658 int cmdnumber; 659 ips_cmd_status_t status; 660 661 while(ips_read_1(sc, COPPER_REG_HISR) & COPPER_SCE_BIT){ 662 status.value = ips_copperhead_cmd_status(sc); 663 cmdnumber = status.fields.command_id; 664 sc->commandarray[cmdnumber].status.value = status.value; 665 sc->commandarray[cmdnumber].timeout = 0; 666 sc->commandarray[cmdnumber].callback(&(sc->commandarray[cmdnumber])); 667 PRINTF(9, "ips: got command %d\n", cmdnumber); 668 } 669 return; 670 } 671 672 void ips_issue_copperhead_cmd(ips_command_t *command) 673 { 674 int i; 675 intrmask_t mask = splbio(); 676 /* hmmm, is there a cleaner way to do this? */ 677 if(command->sc->state & IPS_OFFLINE){ 678 splx(mask); 679 command->status.value = IPS_ERROR_STATUS; 680 command->callback(command); 681 return; 682 } 683 command->timeout = 10; 684 for(i = 0; ips_read_4(command->sc, COPPER_REG_CCCR) & COPPER_SEM_BIT; 685 i++ ){ 686 if( i == 20){ 687 printf("sem bit still set, can't send a command\n"); 688 splx(mask); 689 return; 690 } 691 DELAY(500);/* need to do a delay here */ 692 } 693 ips_write_4(command->sc, COPPER_REG_CCSAR, command->command_phys_addr); 694 ips_write_2(command->sc, COPPER_REG_CCCR, COPPER_CMD_START); 695 splx(mask); 696 } 697 698