2 * Written by: David Jeffery
3 * Copyright (c) 2002 Adaptec Inc.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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.
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
27 * $FreeBSD: src/sys/dev/ips/ips.c,v 1.12 2004/05/30 04:01:29 scottl Exp $
28 * $DragonFly: src/sys/dev/raid/ips/ips.c,v 1.19 2006/12/22 23:26:23 swildner Exp $
31 #include <dev/raid/ips/ips.h>
34 #include <sys/thread2.h>
35 #include <machine/clock.h>
37 static d_open_t ips_open;
38 static d_close_t ips_close;
39 static d_ioctl_t ips_ioctl;
41 MALLOC_DEFINE(M_IPSBUF, "ipsbuf", "IPS driver buffer");
43 static struct dev_ops ips_ops = {
44 { "ips", IPS_CDEV_MAJOR, D_DISK },
50 static const char *ips_adapter_name[] = {
52 "ServeRAID (copperhead)",
53 "ServeRAID II (copperhead refresh)",
54 "ServeRAID onboard (copperhead)",
55 "ServeRAID onboard (copperhead)",
56 "ServeRAID 3H (clarinet)",
57 "ServeRAID 3L (clarinet lite)",
58 "ServeRAID 4H (trombone)",
59 "ServeRAID 4M (morpheus)",
60 "ServeRAID 4L (morpheus lite)",
61 "ServeRAID 4Mx (neo)",
62 "ServeRAID 4Lx (neo lite)",
63 "ServeRAID 5i II (sarasota)",
64 "ServeRAID 5i (sarasota)",
65 "ServeRAID 6M (marco)",
66 "ServeRAID 6i (sebring)"
71 ips_open(struct dev_open_args *ap)
73 cdev_t dev = ap->a_head.a_dev;
74 ips_softc_t *sc = dev->si_drv1;
76 sc->state |= IPS_DEV_OPEN;
81 ips_close(struct dev_close_args *ap)
83 cdev_t dev = ap->a_head.a_dev;
84 ips_softc_t *sc = dev->si_drv1;
86 sc->state &= ~IPS_DEV_OPEN;
91 ips_ioctl(struct dev_ioctl_args *ap)
95 sc = ap->a_head.a_dev->si_drv1;
96 return ips_ioctl_request(sc, ap->a_cmd, ap->a_data, ap->a_fflag);
100 ips_cmd_dmaload(void *cmdptr, bus_dma_segment_t *segments, int segnum,
103 ips_command_t *command = cmdptr;
105 PRINTF(10, "ips: in ips_cmd_dmaload\n");
107 command->command_phys_addr = segments[0].ds_addr;
111 /* is locking needed? what locking guarentees are there on removal? */
113 ips_cmdqueue_free(ips_softc_t *sc)
116 ips_command_t *command;
119 if (sc->used_commands == 0) {
120 for (i = 0; i < sc->max_cmds; i++) {
121 command = &sc->commandarray[i];
122 if (command->command_phys_addr == 0)
124 bus_dmamap_unload(sc->command_dmatag,
125 command->command_dmamap);
126 bus_dmamem_free(sc->command_dmatag,
127 command->command_buffer,
128 command->command_dmamap);
129 if (command->data_dmamap != NULL)
130 bus_dmamap_destroy(command->data_dmatag,
131 command->data_dmamap);
134 sc->state |= IPS_OFFLINE;
136 sc->staticcmd = NULL;
137 kfree(sc->commandarray, M_IPSBUF);
143 * Places all ips command structs on the free command queue.
144 * The first slot is used exclusively for static commands
145 * No locking as if someone else tries to access this during init,
146 * we have bigger problems
149 ips_cmdqueue_init(ips_softc_t *sc)
152 ips_command_t *command;
154 sc->commandarray = kmalloc(sizeof(sc->commandarray[0]) * sc->max_cmds,
155 M_IPSBUF, M_INTWAIT | M_ZERO);
156 SLIST_INIT(&sc->free_cmd_list);
157 for (i = 0; i < sc->max_cmds; i++) {
158 command = &sc->commandarray[i];
161 if (bus_dmamem_alloc(sc->command_dmatag,
162 &command->command_buffer, BUS_DMA_NOWAIT,
163 &command->command_dmamap))
165 bus_dmamap_load(sc->command_dmatag, command->command_dmamap,
166 command->command_buffer, IPS_COMMAND_LEN, ips_cmd_dmaload,
167 command, BUS_DMA_NOWAIT);
168 if (command->command_phys_addr == 0) {
169 bus_dmamem_free(sc->command_dmatag,
170 command->command_buffer, command->command_dmamap);
175 sc->staticcmd = command;
177 command->data_dmatag = sc->sg_dmatag;
178 if (bus_dmamap_create(command->data_dmatag, 0,
179 &command->data_dmamap))
181 SLIST_INSERT_HEAD(&sc->free_cmd_list, command, next);
184 sc->state &= ~IPS_OFFLINE;
187 ips_cmdqueue_free(sc);
192 * returns a free command struct if one is available.
193 * It also blanks out anything that may be a wild pointer/value.
194 * Also, command buffers are not freed. They are
195 * small so they are saved and kept dmamapped and loaded.
198 ips_get_free_cmd(ips_softc_t *sc, ips_command_t **cmd, unsigned long flags)
200 ips_command_t *command = NULL;
204 if (sc->state & IPS_OFFLINE) {
208 if ((flags & IPS_STATIC_FLAG) != 0) {
209 if (sc->state & IPS_STATIC_BUSY) {
213 command = sc->staticcmd;
214 sc->state |= IPS_STATIC_BUSY;
216 command = SLIST_FIRST(&sc->free_cmd_list);
217 if (!command || (sc->state & IPS_TIMEOUT)) {
221 SLIST_REMOVE_HEAD(&sc->free_cmd_list, next);
229 bzero(&command->status, (char *)(command + 1) - (char *)(&command->status));
230 bzero(command->command_buffer, IPS_COMMAND_LEN);
235 /* adds a command back to the free command queue */
237 ips_insert_free_cmd(ips_softc_t *sc, ips_command_t *command)
240 if (command == sc->staticcmd)
241 sc->state &= ~IPS_STATIC_BUSY;
243 SLIST_INSERT_HEAD(&sc->free_cmd_list, command, next);
250 ips_diskdev_statename(u_int8_t state)
252 static char statebuf[20];
261 case IPS_LD_DEGRADED:
274 ksprintf(statebuf, "UNKNOWN(0x%02x)", state);
279 ips_diskdev_init(ips_softc_t *sc)
283 for (i = 0; i < IPS_MAX_NUM_DRIVES; i++) {
284 if (sc->drives[i].state == IPS_LD_FREE)
286 device_printf(sc->dev,
287 "Logical Drive %d: RAID%d sectors: %u, state %s\n", i,
288 sc->drives[i].raid_lvl, sc->drives[i].sector_count,
289 ips_diskdev_statename(sc->drives[i].state));
290 if (sc->drives[i].state == IPS_LD_OKAY ||
291 sc->drives[i].state == IPS_LD_DEGRADED) {
292 sc->diskdev[i] = device_add_child(sc->dev, NULL, -1);
293 device_set_ivars(sc->diskdev[i], (void *)(uintptr_t)i);
296 if (bus_generic_attach(sc->dev))
297 device_printf(sc->dev, "Attaching bus failed\n");
302 ips_diskdev_free(ips_softc_t *sc)
307 for (i = 0; i < IPS_MAX_NUM_DRIVES; i++) {
308 if (sc->diskdev[i] != NULL) {
309 error = device_delete_child(sc->dev, sc->diskdev[i]);
314 bus_generic_detach(sc->dev);
319 * ips_timeout is periodically called to make sure no commands sent
320 * to the card have become stuck. If it finds a stuck command, it
321 * sets a flag so the driver won't start any more commands and then
322 * is periodically called to see if all outstanding commands have
323 * either finished or timed out. Once timed out, an attempt to
324 * reinitialize the card is made. If that fails, the driver gives
325 * up and declares the card dead.
328 ips_timeout(void *arg)
330 ips_command_t *command;
331 ips_softc_t *sc = arg;
334 lockmgr(&sc->queue_lock, LK_EXCLUSIVE|LK_RETRY);
335 command = &sc->commandarray[0];
336 for (i = 0; i < sc->max_cmds; i++) {
337 if (!command[i].timeout)
339 command[i].timeout--;
340 if (command[i].timeout == 0) {
341 if (!(sc->state & IPS_TIMEOUT)) {
342 sc->state |= IPS_TIMEOUT;
343 device_printf(sc->dev, "WARNING: command timeout. Adapter is in toaster mode, resetting to known state\n");
345 command[i].status.value = IPS_ERROR_STATUS;
346 command[i].callback(&command[i]);
347 /* hmm, this should be enough cleanup */
351 if (!state && (sc->state & IPS_TIMEOUT)) {
352 if (sc->ips_adapter_reinit(sc, 1)) {
353 device_printf(sc->dev, "AIEE! adapter reset failed, "
354 "giving up and going home! Have a nice day.\n");
355 sc->state |= IPS_OFFLINE;
356 sc->state &= ~IPS_TIMEOUT;
358 * Grr, I hate this solution. I run waiting commands
359 * one at a time and error them out just before they
360 * would go to the card. This sucks.
363 sc->state &= ~IPS_TIMEOUT;
365 if (sc->state != IPS_OFFLINE)
366 callout_reset(&sc->timer, 10 * hz, ips_timeout, sc);
367 lockmgr(&sc->queue_lock, LK_RELEASE);
370 /* check card and initialize it */
372 ips_adapter_init(ips_softc_t *sc)
377 DEVICE_PRINTF(1, sc->dev, "initializing\n");
378 if (bus_dma_tag_create( /* parent */ sc->adapter_dmatag,
381 /* lowaddr */ BUS_SPACE_MAXADDR_32BIT,
382 /* highaddr */ BUS_SPACE_MAXADDR,
384 /* filterarg */ NULL,
385 /* maxsize */ IPS_COMMAND_LEN +
388 /* maxsegsize*/ IPS_COMMAND_LEN +
391 &sc->command_dmatag) != 0) {
392 device_printf(sc->dev, "can't alloc command dma tag\n");
395 if (bus_dma_tag_create( /* parent */ sc->adapter_dmatag,
398 /* lowaddr */ BUS_SPACE_MAXADDR_32BIT,
399 /* highaddr */ BUS_SPACE_MAXADDR,
401 /* filterarg */ NULL,
402 /* maxsize */ IPS_MAX_IOBUF_SIZE,
403 /* numsegs */ IPS_MAX_SG_ELEMENTS,
404 /* maxsegsize*/ IPS_MAX_IOBUF_SIZE,
406 &sc->sg_dmatag) != 0) {
407 device_printf(sc->dev, "can't alloc SG dma tag\n");
411 * create one command buffer until we know how many commands this card
415 ips_cmdqueue_init(sc);
416 callout_init(&sc->timer);
417 if (sc->ips_adapter_reinit(sc, 0))
419 /* initialize ffdc values */
420 microtime(&sc->ffdc_resettime);
421 sc->ffdc_resetcount = 1;
422 if ((i = ips_ffdc_reset(sc)) != 0) {
423 device_printf(sc->dev,
424 "failed to send ffdc reset to device (%d)\n", i);
427 if ((i = ips_get_adapter_info(sc)) != 0) {
428 device_printf(sc->dev, "failed to get adapter configuration "
429 "data from device (%d)\n", i);
432 /* no error check as failure doesn't matter */
433 ips_update_nvram(sc);
434 if (sc->adapter_type > 0 && sc->adapter_type <= IPS_ADAPTER_MAX_T) {
435 device_printf(sc->dev, "adapter type: %s\n",
436 ips_adapter_name[sc->adapter_type]);
438 if ((i = ips_get_drive_info(sc)) != 0) {
439 device_printf(sc->dev, "failed to get drive "
440 "configuration data from device (%d)\n", i);
443 ips_cmdqueue_free(sc);
444 if (sc->adapter_info.max_concurrent_cmds)
445 sc->max_cmds = min(128, sc->adapter_info.max_concurrent_cmds);
448 if (ips_cmdqueue_init(sc)) {
449 device_printf(sc->dev,
450 "failed to initialize command buffers\n");
453 dev = make_dev(&ips_ops, device_get_unit(sc->dev),
454 UID_ROOT, GID_OPERATOR, S_IRUSR | S_IWUSR,
455 "ips%d", device_get_unit(sc->dev));
457 ips_diskdev_init(sc);
458 callout_reset(&sc->timer, 10 * hz, ips_timeout, sc);
461 ips_adapter_free(sc);
466 * see if we should reinitialize the card and wait for it to timeout
467 * or complete initialization
470 ips_morpheus_reinit(ips_softc_t *sc, int force)
475 tmp = ips_read_4(sc, MORPHEUS_REG_OISR);
476 if (!force && (ips_read_4(sc, MORPHEUS_REG_OMR0) >= IPS_POST1_OK) &&
477 (ips_read_4(sc, MORPHEUS_REG_OMR1) != 0xdeadbeef) && !tmp) {
478 ips_write_4(sc, MORPHEUS_REG_OIMR, 0);
481 ips_write_4(sc, MORPHEUS_REG_OIMR, 0xff);
482 ips_read_4(sc, MORPHEUS_REG_OIMR);
483 device_printf(sc->dev,
484 "resetting adapter, this may take up to 5 minutes\n");
485 ips_write_4(sc, MORPHEUS_REG_IDR, 0x80000000);
487 pci_read_config(sc->dev, 0, 4);
488 tmp = ips_read_4(sc, MORPHEUS_REG_OISR);
489 for (i = 0; i < 45 && !(tmp & MORPHEUS_BIT_POST1); i++) {
491 DEVICE_PRINTF(2, sc->dev, "post1: %d\n", i);
492 tmp = ips_read_4(sc, MORPHEUS_REG_OISR);
494 if (tmp & MORPHEUS_BIT_POST1)
495 ips_write_4(sc, MORPHEUS_REG_OISR, MORPHEUS_BIT_POST1);
497 if (i == 45 || ips_read_4(sc, MORPHEUS_REG_OMR0) < IPS_POST1_OK) {
498 device_printf(sc->dev,
499 "Adapter error during initialization.\n");
502 for (i = 0; i < 240 && !(tmp & MORPHEUS_BIT_POST2); i++) {
504 DEVICE_PRINTF(2, sc->dev, "post2: %d\n", i);
505 tmp = ips_read_4(sc, MORPHEUS_REG_OISR);
507 if (tmp & MORPHEUS_BIT_POST2)
508 ips_write_4(sc, MORPHEUS_REG_OISR, MORPHEUS_BIT_POST2);
510 if (i == 240 || !ips_read_4(sc, MORPHEUS_REG_OMR1)) {
511 device_printf(sc->dev, "adapter failed config check\n");
514 ips_write_4(sc, MORPHEUS_REG_OIMR, 0);
515 if (force && ips_clear_adapter(sc)) {
516 device_printf(sc->dev, "adapter clear failed\n");
522 /* clean up so we can unload the driver. */
524 ips_adapter_free(ips_softc_t *sc)
528 if (sc->state & IPS_DEV_OPEN)
530 if ((error = ips_diskdev_free(sc)))
532 if (ips_cmdqueue_free(sc)) {
533 device_printf(sc->dev,
534 "trying to exit when command queue is not empty!\n");
537 DEVICE_PRINTF(1, sc->dev, "free\n");
539 callout_stop(&sc->timer);
542 bus_dma_tag_destroy(sc->sg_dmatag);
543 if (sc->command_dmatag)
544 bus_dma_tag_destroy(sc->command_dmatag);
545 dev_ops_remove_minor(&ips_ops, device_get_unit(sc->dev));
550 ips_morpheus_check_intr(void *void_sc)
552 ips_softc_t *sc = (ips_softc_t *)void_sc;
553 u_int32_t oisr, iisr;
554 ips_cmd_status_t status;
555 ips_command_t *command;
559 iisr =ips_read_4(sc, MORPHEUS_REG_IISR);
560 oisr =ips_read_4(sc, MORPHEUS_REG_OISR);
561 PRINTF(9, "interrupt registers in:%x out:%x\n", iisr, oisr);
562 if (!(oisr & MORPHEUS_BIT_CMD_IRQ)) {
563 DEVICE_PRINTF(2, sc->dev, "got a non-command irq\n");
566 while ((status.value = ips_read_4(sc, MORPHEUS_REG_OQPR))
568 cmdnumber = status.fields.command_id;
569 command = &sc->commandarray[cmdnumber];
570 command->status.value = status.value;
571 command->timeout = 0;
572 command->callback(command);
573 DEVICE_PRINTF(9, sc->dev, "got command %d\n", cmdnumber);
580 ips_morpheus_intr(void *void_sc)
582 ips_softc_t *sc = void_sc;
584 lockmgr(&sc->queue_lock, LK_EXCLUSIVE|LK_RETRY);
585 ips_morpheus_check_intr(sc);
586 lockmgr(&sc->queue_lock, LK_RELEASE);
590 ips_issue_morpheus_cmd(ips_command_t *command)
593 /* hmmm, is there a cleaner way to do this? */
594 if (command->sc->state & IPS_OFFLINE) {
596 command->status.value = IPS_ERROR_STATUS;
597 command->callback(command);
600 command->timeout = 10;
601 ips_write_4(command->sc, MORPHEUS_REG_IQPR, command->command_phys_addr);
606 ips_morpheus_poll(ips_command_t *command)
610 ts = time_second + command->timeout;
611 while (command->timeout != 0 &&
612 ips_morpheus_check_intr(command->sc) == 0 &&
618 ips_copperhead_queue_callback(void *queueptr, bus_dma_segment_t *segments,
619 int segnum, int error)
621 ips_copper_queue_t *queue = queueptr;
625 queue->base_phys_addr = segments[0].ds_addr;
629 ips_copperhead_queue_init(ips_softc_t *sc)
631 bus_dma_tag_t dmatag;
635 if (bus_dma_tag_create( /* parent */ sc->adapter_dmatag,
638 /* lowaddr */ BUS_SPACE_MAXADDR_32BIT,
639 /* highaddr */ BUS_SPACE_MAXADDR,
641 /* filterarg */ NULL,
642 /* maxsize */ sizeof(ips_copper_queue_t),
644 /* maxsegsize*/ sizeof(ips_copper_queue_t),
647 device_printf(sc->dev, "can't alloc dma tag for statue queue\n");
651 if (bus_dmamem_alloc(dmatag, (void *)&(sc->copper_queue),
652 BUS_DMA_NOWAIT, &dmamap)) {
656 bzero(sc->copper_queue, sizeof(ips_copper_queue_t));
657 sc->copper_queue->dmatag = dmatag;
658 sc->copper_queue->dmamap = dmamap;
659 sc->copper_queue->nextstatus = 1;
660 bus_dmamap_load(dmatag, dmamap, &(sc->copper_queue->status[0]),
661 IPS_MAX_CMD_NUM * 4, ips_copperhead_queue_callback,
662 sc->copper_queue, BUS_DMA_NOWAIT);
663 if (sc->copper_queue->base_phys_addr == 0) {
667 ips_write_4(sc, COPPER_REG_SQSR, sc->copper_queue->base_phys_addr);
668 ips_write_4(sc, COPPER_REG_SQER, sc->copper_queue->base_phys_addr +
669 IPS_MAX_CMD_NUM * 4);
670 ips_write_4(sc, COPPER_REG_SQHR, sc->copper_queue->base_phys_addr + 4);
671 ips_write_4(sc, COPPER_REG_SQTR, sc->copper_queue->base_phys_addr);
674 bus_dmamem_free(dmatag, sc->copper_queue, dmamap);
675 bus_dma_tag_destroy(dmatag);
680 * see if we should reinitialize the card and wait for it to timeout or
681 * complete initialization FIXME
684 ips_copperhead_reinit(ips_softc_t *sc, int force)
686 u_int32_t postcode = 0, configstatus = 0;
689 ips_write_1(sc, COPPER_REG_SCPR, 0x80);
690 ips_write_1(sc, COPPER_REG_SCPR, 0);
691 device_printf(sc->dev,
692 "reinitializing adapter, this could take several minutes.\n");
693 for (j = 0; j < 2; j++) {
695 for (i = 0; i < 45; i++) {
696 if (ips_read_1(sc, COPPER_REG_HISR) & COPPER_GHI_BIT) {
697 postcode |= ips_read_1(sc, COPPER_REG_ISPR);
698 ips_write_1(sc, COPPER_REG_HISR,
707 for (j = 0; j < 2; j++) {
709 for (i = 0; i < 240; i++) {
710 if (ips_read_1(sc, COPPER_REG_HISR) & COPPER_GHI_BIT) {
711 configstatus |= ips_read_1(sc, COPPER_REG_ISPR);
712 ips_write_1(sc, COPPER_REG_HISR,
721 for (i = 0; i < 240; i++) {
722 if (!(ips_read_1(sc, COPPER_REG_CBSP) & COPPER_OP_BIT))
729 ips_write_2(sc, COPPER_REG_CCCR, 0x1000 | COPPER_ILE_BIT);
730 ips_write_1(sc, COPPER_REG_SCPR, COPPER_EBM_BIT);
731 ips_copperhead_queue_init(sc);
732 ips_write_1(sc, COPPER_REG_HISR, COPPER_GHI_BIT);
733 i = ips_read_1(sc, COPPER_REG_SCPR);
734 ips_write_1(sc, COPPER_REG_HISR, COPPER_EI_BIT);
735 if (configstatus == 0) {
736 device_printf(sc->dev, "adapter initialization failed\n");
739 if (force && ips_clear_adapter(sc)) {
740 device_printf(sc->dev, "adapter clear failed\n");
747 ips_copperhead_cmd_status(ips_softc_t *sc)
752 statnum = sc->copper_queue->nextstatus++;
753 if (sc->copper_queue->nextstatus == IPS_MAX_CMD_NUM)
754 sc->copper_queue->nextstatus = 0;
756 value = sc->copper_queue->status[statnum];
757 ips_write_4(sc, COPPER_REG_SQTR, sc->copper_queue->base_phys_addr +
764 ips_copperhead_intr(void *void_sc)
766 ips_softc_t *sc = (ips_softc_t *)void_sc;
767 ips_cmd_status_t status;
770 lockmgr(&sc->queue_lock, LK_EXCLUSIVE|LK_RETRY);
771 while (ips_read_1(sc, COPPER_REG_HISR) & COPPER_SCE_BIT) {
772 status.value = ips_copperhead_cmd_status(sc);
773 cmdnumber = status.fields.command_id;
774 sc->commandarray[cmdnumber].status.value = status.value;
775 sc->commandarray[cmdnumber].timeout = 0;
776 sc->commandarray[cmdnumber].callback(&(sc->commandarray[cmdnumber]));
777 PRINTF(9, "ips: got command %d\n", cmdnumber);
779 lockmgr(&sc->queue_lock, LK_RELEASE);
784 ips_issue_copperhead_cmd(ips_command_t *command)
789 /* hmmm, is there a cleaner way to do this? */
790 if (command->sc->state & IPS_OFFLINE) {
792 command->status.value = IPS_ERROR_STATUS;
793 command->callback(command);
796 command->timeout = 10;
797 for (i = 0; ips_read_4(command->sc, COPPER_REG_CCCR) & COPPER_SEM_BIT;
800 kprintf("sem bit still set, can't send a command\n");
804 DELAY(500); /* need to do a delay here */
806 ips_write_4(command->sc, COPPER_REG_CCSAR, command->command_phys_addr);
807 ips_write_2(command->sc, COPPER_REG_CCCR, COPPER_CMD_START);
812 ips_copperhead_poll(ips_command_t *command)
814 kprintf("ips: cmd polling not implemented for copperhead devices\n");