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