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