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.6 2003/11/27 08:37:36 mbr
28 * $DragonFly: src/sys/dev/raid/ips/ips.c,v 1.2 2004/01/18 18:47:31 dillon Exp $
31 #include <sys/cdefs.h>
33 #include <dev/raid/ips/ips.h>
36 #include <machine/clock.h>
38 static d_open_t ips_open;
39 static d_close_t ips_close;
40 static d_ioctl_t ips_ioctl;
42 static struct cdevsw ips_cdevsw = {
44 .d_maj = IPS_CDEV_MAJOR,
49 .old_close = ips_close,
50 .old_ioctl = ips_ioctl,
53 static const char *ips_adapter_name[] = {
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)"
74 ips_open(dev_t dev, int flags, int fmt, d_thread_t *td)
76 ips_softc_t *sc = dev->si_drv1;
78 sc->state |= IPS_DEV_OPEN;
83 ips_close(dev_t dev, int flags, int fmt, d_thread_t *td)
85 ips_softc_t *sc = dev->si_drv1;
87 sc->state &= ~IPS_DEV_OPEN;
92 ips_ioctl(dev_t dev, u_long command, caddr_t addr, int32_t flags,
98 return ips_ioctl_request(sc, command, addr, flags);
102 ips_cmd_dmaload(void *cmdptr, bus_dma_segment_t *segments, int segnum,
105 ips_command_t *command = cmdptr;
107 PRINTF(10, "ips: in ips_cmd_dmaload\n");
109 command->command_phys_addr = segments[0].ds_addr;
113 /* is locking needed? what locking guarentees are there on removal? */
114 static __inline__ int
115 ips_cmdqueue_free(ips_softc_t *sc)
121 if (sc->used_commands == 0) {
122 for (i = 0; i < sc->max_cmds; i++) {
123 if (sc->commandarray[i].command_phys_addr == 0)
125 bus_dmamap_unload(sc->command_dmatag,
126 sc->commandarray[i].command_dmamap);
127 bus_dmamem_free(sc->command_dmatag,
128 sc->commandarray[i].command_buffer,
129 sc->commandarray[i].command_dmamap);
132 sc->state |= IPS_OFFLINE;
138 /* places all ips command structs on the free command queue. No locking as if someone else tries
139 * to access this during init, we have bigger problems */
140 static __inline__ int
141 ips_cmdqueue_init(ips_softc_t *sc)
144 ips_command_t *command;
146 SLIST_INIT(&sc->free_cmd_list);
147 STAILQ_INIT(&sc->cmd_wait_list);
148 for (i = 0; i < sc->max_cmds; i++) {
149 sc->commandarray[i].id = i;
150 sc->commandarray[i].sc = sc;
151 SLIST_INSERT_HEAD(&sc->free_cmd_list, &sc->commandarray[i],
154 for (i = 0; i < sc->max_cmds; i++) {
155 command = &sc->commandarray[i];
156 if (bus_dmamem_alloc(sc->command_dmatag,
157 &command->command_buffer, BUS_DMA_NOWAIT,
158 &command->command_dmamap))
160 bus_dmamap_load(sc->command_dmatag, command->command_dmamap,
161 command->command_buffer, IPS_COMMAND_LEN, ips_cmd_dmaload,
162 command, BUS_DMA_NOWAIT);
163 if (command->command_phys_addr == 0) {
164 bus_dmamem_free(sc->command_dmatag,
165 command->command_buffer, command->command_dmamap);
169 sc->state &= ~IPS_OFFLINE;
172 ips_cmdqueue_free(sc);
177 ips_add_waiting_command(ips_softc_t *sc, int (*callback)(ips_command_t *),
178 void *data, unsigned long flags)
181 ips_command_t *command;
182 ips_wait_list_t *waiter;
183 unsigned long memflags = 0;
185 if (IPS_NOWAIT_FLAG & flags)
187 waiter = malloc(sizeof(ips_wait_list_t), M_DEVBUF, memflags);
191 if (sc->state & IPS_OFFLINE) {
193 free(waiter, M_DEVBUF);
196 command = SLIST_FIRST(&sc->free_cmd_list);
197 if (command && !(sc->state & IPS_TIMEOUT)) {
198 SLIST_REMOVE_HEAD(&sc->free_cmd_list, next);
201 clear_ips_command(command);
202 bzero(command->command_buffer, IPS_COMMAND_LEN);
203 free(waiter, M_DEVBUF);
205 return callback(command);
207 DEVICE_PRINTF(1, sc->dev, "adding command to the wait queue\n");
208 waiter->callback = callback;
210 STAILQ_INSERT_TAIL(&sc->cmd_wait_list, waiter, next);
216 ips_run_waiting_command(ips_softc_t *sc)
218 ips_wait_list_t *waiter;
219 ips_command_t *command;
220 int (*callback)(ips_command_t*);
224 waiter = STAILQ_FIRST(&sc->cmd_wait_list);
225 command = SLIST_FIRST(&sc->free_cmd_list);
226 if (waiter == NULL || command == NULL) {
230 DEVICE_PRINTF(1, sc->dev, "removing command from wait queue\n");
231 SLIST_REMOVE_HEAD(&sc->free_cmd_list, next);
232 STAILQ_REMOVE_HEAD(&sc->cmd_wait_list, next);
235 clear_ips_command(command);
236 bzero(command->command_buffer, IPS_COMMAND_LEN);
237 command->arg = waiter->data;
238 callback = waiter->callback;
239 free(waiter, M_DEVBUF);
245 * returns a free command struct if one is available.
246 * It also blanks out anything that may be a wild pointer/value.
247 * Also, command buffers are not freed. They are
248 * small so they are saved and kept dmamapped and loaded.
251 ips_get_free_cmd(ips_softc_t *sc, int (*callback)(ips_command_t *), void *data,
254 ips_command_t *command;
258 if (sc->state & IPS_OFFLINE) {
262 command = SLIST_FIRST(&sc->free_cmd_list);
263 if (!command || (sc->state & IPS_TIMEOUT)) {
265 if (flags & IPS_NOWAIT_FLAG)
267 return ips_add_waiting_command(sc, callback, data, flags);
269 SLIST_REMOVE_HEAD(&sc->free_cmd_list, next);
272 clear_ips_command(command);
273 bzero(command->command_buffer, IPS_COMMAND_LEN);
275 return callback(command);
278 /* adds a command back to the free command queue */
280 ips_insert_free_cmd(ips_softc_t *sc, ips_command_t *command)
285 SLIST_INSERT_HEAD(&sc->free_cmd_list, command, next);
288 if (!(sc->state & IPS_TIMEOUT))
289 ips_run_waiting_command(sc);
292 ips_diskdev_statename(u_int8_t state)
294 static char statebuf[20];
303 case IPS_LD_DEGRADED:
316 sprintf(statebuf, "UNKNOWN(0x%02x)", state);
321 ips_diskdev_init(ips_softc_t *sc)
325 for (i = 0; i < IPS_MAX_NUM_DRIVES; i++) {
326 if (sc->drives[i].state == IPS_LD_FREE)
328 device_printf(sc->dev,
329 "Logical Drive %d: RAID%d sectors: %u, state %s\n", i,
330 sc->drives[i].raid_lvl, sc->drives[i].sector_count,
331 ips_diskdev_statename(sc->drives[i].state));
332 if (sc->drives[i].state == IPS_LD_OKAY ||
333 sc->drives[i].state == IPS_LD_DEGRADED) {
334 sc->diskdev[i] = device_add_child(sc->dev, NULL, -1);
335 device_set_ivars(sc->diskdev[i], (void *)(uintptr_t)i);
338 if (bus_generic_attach(sc->dev))
339 device_printf(sc->dev, "Attaching bus failed\n");
344 ips_diskdev_free(ips_softc_t *sc)
349 for (i = 0; i < IPS_MAX_NUM_DRIVES; i++) {
350 if (sc->diskdev[i] != NULL) {
351 error = device_delete_child(sc->dev, sc->diskdev[i]);
356 bus_generic_detach(sc->dev);
361 * ips_timeout is periodically called to make sure no commands sent
362 * to the card have become stuck. If it finds a stuck command, it
363 * sets a flag so the driver won't start any more commands and then
364 * is periodically called to see if all outstanding commands have
365 * either finished or timed out. Once timed out, an attempt to
366 * reinitialize the card is made. If that fails, the driver gives
367 * up and declares the card dead.
370 ips_timeout(void *arg)
372 ips_command_t *command;
373 ips_softc_t *sc = arg;
377 command = &sc->commandarray[0];
379 for (i = 0; i < sc->max_cmds; i++) {
380 if (!command[i].timeout)
382 command[i].timeout--;
383 if (command[i].timeout == 0) {
384 if (!(sc->state & IPS_TIMEOUT)) {
385 sc->state |= IPS_TIMEOUT;
386 device_printf(sc->dev, "WARNING: command timeout. Adapter is in toaster mode, resetting to known state\n");
388 command[i].status.value = IPS_ERROR_STATUS;
389 command[i].callback(&command[i]);
390 /* hmm, this should be enough cleanup */
394 if (!state && (sc->state & IPS_TIMEOUT)) {
395 if (sc->ips_adapter_reinit(sc, 1)) {
396 device_printf(sc->dev, "AIEE! adapter reset failed, "
397 "giving up and going home! Have a nice day.\n");
398 sc->state |= IPS_OFFLINE;
399 sc->state &= ~IPS_TIMEOUT;
401 * Grr, I hate this solution. I run waiting commands
402 * one at a time and error them out just before they
403 * would go to the card. This sucks.
406 sc->state &= ~IPS_TIMEOUT;
407 ips_run_waiting_command(sc);
409 if (sc->state != IPS_OFFLINE)
410 sc->timer = timeout(ips_timeout, sc, 10 * hz);
414 /* check card and initialize it */
416 ips_adapter_init(ips_softc_t *sc)
420 DEVICE_PRINTF(1, sc->dev, "initializing\n");
421 if (bus_dma_tag_create( /* parent */ sc->adapter_dmatag,
424 /* lowaddr */ BUS_SPACE_MAXADDR_32BIT,
425 /* highaddr */ BUS_SPACE_MAXADDR,
427 /* filterarg */ NULL,
428 /* maxsize */ IPS_COMMAND_LEN +
431 /* maxsegsize*/ IPS_COMMAND_LEN +
434 &sc->command_dmatag) != 0) {
435 device_printf(sc->dev, "can't alloc command dma tag\n");
438 if (bus_dma_tag_create( /* parent */ sc->adapter_dmatag,
441 /* lowaddr */ BUS_SPACE_MAXADDR_32BIT,
442 /* highaddr */ BUS_SPACE_MAXADDR,
444 /* filterarg */ NULL,
445 /* maxsize */ IPS_MAX_IOBUF_SIZE,
446 /* numsegs */ IPS_MAX_SG_ELEMENTS,
447 /* maxsegsize*/ IPS_MAX_IOBUF_SIZE,
449 &sc->sg_dmatag) != 0) {
450 device_printf(sc->dev, "can't alloc SG dma tag\n");
454 * create one command buffer until we know how many commands this card
458 ips_cmdqueue_init(sc);
459 callout_handle_init(&sc->timer);
460 if (sc->ips_adapter_reinit(sc, 0))
463 /* initialize ffdc values */
464 microtime(&sc->ffdc_resettime);
465 sc->ffdc_resetcount = 1;
466 if ((i = ips_ffdc_reset(sc)) != 0) {
467 device_printf(sc->dev,
468 "failed to send ffdc reset to device (%d)\n", i);
471 if ((i = ips_get_adapter_info(sc)) != 0) {
472 device_printf(sc->dev, "failed to get adapter configuration "
473 "data from device (%d)\n", i);
476 /* no error check as failure doesn't matter */
477 ips_update_nvram(sc);
478 if (sc->adapter_type > 0 && sc->adapter_type <= IPS_ADAPTER_MAX_T) {
479 device_printf(sc->dev, "adapter type: %s\n",
480 ips_adapter_name[sc->adapter_type]);
482 if ((i = ips_get_drive_info(sc)) != 0) {
483 device_printf(sc->dev, "failed to get drive "
484 "configuration data from device (%d)\n", i);
487 ips_cmdqueue_free(sc);
488 if (sc->adapter_info.max_concurrent_cmds)
489 sc->max_cmds = min(128, sc->adapter_info.max_concurrent_cmds);
492 if (ips_cmdqueue_init(sc)) {
493 device_printf(sc->dev,
494 "failed to initialize command buffers\n");
497 sc->device_file = make_dev(&ips_cdevsw, device_get_unit(sc->dev),
498 UID_ROOT, GID_OPERATOR, S_IRUSR | S_IWUSR,
499 "ips%d", device_get_unit(sc->dev));
500 sc->device_file->si_drv1 = sc;
501 ips_diskdev_init(sc);
502 sc->timer = timeout(ips_timeout, sc, 10*hz);
505 ips_adapter_free(sc);
510 * see if we should reinitialize the card and wait for it to timeout
511 * or complete initialization
514 ips_morpheus_reinit(ips_softc_t *sc, int force)
519 tmp = ips_read_4(sc, MORPHEUS_REG_OISR);
520 if (!force && (ips_read_4(sc, MORPHEUS_REG_OMR0) >= IPS_POST1_OK) &&
521 (ips_read_4(sc, MORPHEUS_REG_OMR1) != 0xdeadbeef) && !tmp) {
522 ips_write_4(sc, MORPHEUS_REG_OIMR, 0);
525 ips_write_4(sc, MORPHEUS_REG_OIMR, 0xff);
526 ips_read_4(sc, MORPHEUS_REG_OIMR);
527 device_printf(sc->dev,
528 "resetting adapter, this may take up to 5 minutes\n");
529 ips_write_4(sc, MORPHEUS_REG_IDR, 0x80000000);
531 pci_read_config(sc->dev, 0, 4);
532 tmp = ips_read_4(sc, MORPHEUS_REG_OISR);
533 for (i = 0; i < 45 && !(tmp & MORPHEUS_BIT_POST1); i++) {
535 DEVICE_PRINTF(2, sc->dev, "post1: %d\n", i);
536 tmp = ips_read_4(sc, MORPHEUS_REG_OISR);
538 if (tmp & MORPHEUS_BIT_POST1)
539 ips_write_4(sc, MORPHEUS_REG_OISR, MORPHEUS_BIT_POST1);
541 if (i == 45 || ips_read_4(sc, MORPHEUS_REG_OMR0) < IPS_POST1_OK) {
542 device_printf(sc->dev,
543 "Adapter error during initialization.\n");
546 for (i = 0; i < 240 && !(tmp & MORPHEUS_BIT_POST2); i++) {
548 DEVICE_PRINTF(2, sc->dev, "post2: %d\n", i);
549 tmp = ips_read_4(sc, MORPHEUS_REG_OISR);
551 if (tmp & MORPHEUS_BIT_POST2)
552 ips_write_4(sc, MORPHEUS_REG_OISR, MORPHEUS_BIT_POST2);
554 if (i == 240 || !ips_read_4(sc, MORPHEUS_REG_OMR1)) {
555 device_printf(sc->dev, "adapter failed config check\n");
558 ips_write_4(sc, MORPHEUS_REG_OIMR, 0);
559 if (force && ips_clear_adapter(sc)) {
560 device_printf(sc->dev, "adapter clear failed\n");
566 /* clean up so we can unload the driver. */
568 ips_adapter_free(ips_softc_t *sc)
572 if (sc->state & IPS_DEV_OPEN)
574 if ((error = ips_diskdev_free(sc)))
576 if (ips_cmdqueue_free(sc)) {
577 device_printf(sc->dev,
578 "trying to exit when command queue is not empty!\n");
581 DEVICE_PRINTF(1, sc->dev, "free\n");
583 untimeout(ips_timeout, sc, sc->timer);
587 bus_dma_tag_destroy(sc->sg_dmatag);
588 if (sc->command_dmatag)
589 bus_dma_tag_destroy(sc->command_dmatag);
591 destroy_dev(sc->device_file);
596 ips_morpheus_intr(void *void_sc)
598 ips_softc_t *sc = (ips_softc_t *)void_sc;
599 u_int32_t oisr, iisr;
600 ips_cmd_status_t status;
603 iisr =ips_read_4(sc, MORPHEUS_REG_IISR);
604 oisr =ips_read_4(sc, MORPHEUS_REG_OISR);
605 PRINTF(9, "interrupt registers in:%x out:%x\n", iisr, oisr);
606 if (!(oisr & MORPHEUS_BIT_CMD_IRQ)) {
607 DEVICE_PRINTF(2, sc->dev, "got a non-command irq\n");
610 while ((status.value = ips_read_4(sc, MORPHEUS_REG_OQPR))
612 cmdnumber = status.fields.command_id;
613 sc->commandarray[cmdnumber].status.value = status.value;
614 sc->commandarray[cmdnumber].timeout = 0;
615 sc->commandarray[cmdnumber].callback(&(sc->commandarray[cmdnumber]));
616 DEVICE_PRINTF(9, sc->dev, "got command %d\n", cmdnumber);
622 ips_issue_morpheus_cmd(ips_command_t *command)
627 /* hmmm, is there a cleaner way to do this? */
628 if (command->sc->state & IPS_OFFLINE) {
630 command->status.value = IPS_ERROR_STATUS;
631 command->callback(command);
634 command->timeout = 10;
635 ips_write_4(command->sc, MORPHEUS_REG_IQPR, command->command_phys_addr);
640 ips_copperhead_queue_callback(void *queueptr, bus_dma_segment_t *segments,
641 int segnum, int error)
643 ips_copper_queue_t *queue = queueptr;
647 queue->base_phys_addr = segments[0].ds_addr;
651 ips_copperhead_queue_init(ips_softc_t *sc)
653 bus_dma_tag_t dmatag;
657 if (bus_dma_tag_create( /* parent */ sc->adapter_dmatag,
660 /* lowaddr */ BUS_SPACE_MAXADDR_32BIT,
661 /* highaddr */ BUS_SPACE_MAXADDR,
663 /* filterarg */ NULL,
664 /* maxsize */ sizeof(ips_copper_queue_t),
666 /* maxsegsize*/ sizeof(ips_copper_queue_t),
669 device_printf(sc->dev, "can't alloc dma tag for statue queue\n");
673 if (bus_dmamem_alloc(dmatag, (void *)&(sc->copper_queue),
674 BUS_DMA_NOWAIT, &dmamap)) {
678 bzero(sc->copper_queue, sizeof(ips_copper_queue_t));
679 sc->copper_queue->dmatag = dmatag;
680 sc->copper_queue->dmamap = dmamap;
681 sc->copper_queue->nextstatus = 1;
682 bus_dmamap_load(dmatag, dmamap, &(sc->copper_queue->status[0]),
683 IPS_MAX_CMD_NUM * 4, ips_copperhead_queue_callback,
684 sc->copper_queue, BUS_DMA_NOWAIT);
685 if (sc->copper_queue->base_phys_addr == 0) {
689 ips_write_4(sc, COPPER_REG_SQSR, sc->copper_queue->base_phys_addr);
690 ips_write_4(sc, COPPER_REG_SQER, sc->copper_queue->base_phys_addr +
691 IPS_MAX_CMD_NUM * 4);
692 ips_write_4(sc, COPPER_REG_SQHR, sc->copper_queue->base_phys_addr + 4);
693 ips_write_4(sc, COPPER_REG_SQTR, sc->copper_queue->base_phys_addr);
696 bus_dmamem_free(dmatag, sc->copper_queue, dmamap);
697 bus_dma_tag_destroy(dmatag);
702 * see if we should reinitialize the card and wait for it to timeout or
703 * complete initialization FIXME
706 ips_copperhead_reinit(ips_softc_t *sc, int force)
708 u_int32_t postcode = 0, configstatus = 0;
711 ips_write_1(sc, COPPER_REG_SCPR, 0x80);
712 ips_write_1(sc, COPPER_REG_SCPR, 0);
713 device_printf(sc->dev,
714 "reinitializing adapter, this could take several minutes.\n");
715 for (j = 0; j < 2; j++) {
717 for (i = 0; i < 45; i++) {
718 if (ips_read_1(sc, COPPER_REG_HISR) & COPPER_GHI_BIT) {
719 postcode |= ips_read_1(sc, COPPER_REG_ISPR);
720 ips_write_1(sc, COPPER_REG_HISR,
729 for (j = 0; j < 2; j++) {
731 for (i = 0; i < 240; i++) {
732 if (ips_read_1(sc, COPPER_REG_HISR) & COPPER_GHI_BIT) {
733 configstatus |= ips_read_1(sc, COPPER_REG_ISPR);
734 ips_write_1(sc, COPPER_REG_HISR,
743 for (i = 0; i < 240; i++) {
744 if (!(ips_read_1(sc, COPPER_REG_CBSP) & COPPER_OP_BIT))
751 ips_write_2(sc, COPPER_REG_CCCR, 0x1000 | COPPER_ILE_BIT);
752 ips_write_1(sc, COPPER_REG_SCPR, COPPER_EBM_BIT);
753 ips_copperhead_queue_init(sc);
754 ips_write_1(sc, COPPER_REG_HISR, COPPER_GHI_BIT);
755 i = ips_read_1(sc, COPPER_REG_SCPR);
756 ips_write_1(sc, COPPER_REG_HISR, COPPER_EI_BIT);
757 if (configstatus == 0) {
758 device_printf(sc->dev, "adapter initialization failed\n");
761 if (force && ips_clear_adapter(sc)) {
762 device_printf(sc->dev, "adapter clear failed\n");
769 ips_copperhead_cmd_status(ips_softc_t *sc)
775 statnum = sc->copper_queue->nextstatus++;
776 if (sc->copper_queue->nextstatus == IPS_MAX_CMD_NUM)
777 sc->copper_queue->nextstatus = 0;
779 value = sc->copper_queue->status[statnum];
780 ips_write_4(sc, COPPER_REG_SQTR, sc->copper_queue->base_phys_addr +
787 ips_copperhead_intr(void *void_sc)
789 ips_softc_t *sc = (ips_softc_t *)void_sc;
790 ips_cmd_status_t status;
793 while (ips_read_1(sc, COPPER_REG_HISR) & COPPER_SCE_BIT) {
794 status.value = ips_copperhead_cmd_status(sc);
795 cmdnumber = status.fields.command_id;
796 sc->commandarray[cmdnumber].status.value = status.value;
797 sc->commandarray[cmdnumber].timeout = 0;
798 sc->commandarray[cmdnumber].callback(&(sc->commandarray[cmdnumber]));
799 PRINTF(9, "ips: got command %d\n", cmdnumber);
805 ips_issue_copperhead_cmd(ips_command_t *command)
811 /* hmmm, is there a cleaner way to do this? */
812 if (command->sc->state & IPS_OFFLINE) {
814 command->status.value = IPS_ERROR_STATUS;
815 command->callback(command);
818 command->timeout = 10;
819 for (i = 0; ips_read_4(command->sc, COPPER_REG_CCCR) & COPPER_SEM_BIT;
822 printf("sem bit still set, can't send a command\n");
826 DELAY(500); /* need to do a delay here */
828 ips_write_4(command->sc, COPPER_REG_CCSAR, command->command_phys_addr);
829 ips_write_2(command->sc, COPPER_REG_CCCR, COPPER_CMD_START);