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