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_commands.c,v 1.8 2004/01/01 10:22:10 mbr $
28 * $DragonFly: src/sys/dev/raid/ips/ips_commands.c,v 1.5 2004/07/09 16:15:27 dillon Exp $
31 #include <sys/cdefs.h>
33 #include <dev/raid/ips/ips.h>
36 ips_msleep(void *ident, struct ips_softc *sc, int priority, const char *wmesg,
42 r = tsleep(ident, priority, wmesg, timo);
48 * This is an interrupt callback. It is called from
49 * interrupt context when the adapter has completed the
50 * command. This very generic callback simply stores
51 * the command's return value in command->arg and wake's
52 * up anyone waiting on the command.
55 ips_wakeup_callback(ips_command_t *command)
57 ips_cmd_status_t *status;
59 status = command->arg;
60 status->value = command->status.value;
61 bus_dmamap_sync(command->sc->command_dmatag, command->command_dmamap,
62 BUS_DMASYNC_POSTWRITE);
63 IPS_LOCK(command->sc);
65 IPS_UNLOCK(command->sc);
67 /* Below are a series of functions for sending an IO request
68 * to the adapter. The flow order is: start, send, callback, finish.
69 * The caller must have already assembled an iorequest struct to hold
70 * the details of the IO request. */
71 static void ips_io_request_finish(ips_command_t *command)
73 struct bio *iobuf = command->arg;
75 if (ips_read_request(iobuf)) {
76 bus_dmamap_sync(command->data_dmatag, command->data_dmamap,
77 BUS_DMASYNC_POSTREAD);
79 bus_dmamap_sync(command->data_dmatag, command->data_dmamap,
80 BUS_DMASYNC_POSTWRITE);
82 bus_dmamap_unload(command->data_dmatag, command->data_dmamap);
83 bus_dmamap_destroy(command->data_dmatag, command->data_dmamap);
84 if (COMMAND_ERROR(&command->status)) {
85 iobuf->bio_flags |=BIO_ERROR;
86 iobuf->bio_error = EIO;
88 ips_insert_free_cmd(command->sc, command);
93 ips_io_request_callback(void *cmdptr, bus_dma_segment_t *segments, int segnum,
97 ips_command_t *command = cmdptr;
98 ips_sg_element_t *sg_list;
99 ips_io_cmd *command_struct;
100 struct bio *iobuf = command->arg;
106 printf("ips: error = %d in ips_sg_request_callback\n", error);
107 bus_dmamap_unload(command->data_dmatag, command->data_dmamap);
108 bus_dmamap_destroy(command->data_dmatag, command->data_dmamap);
109 iobuf->bio_flags |= BIO_ERROR;
110 iobuf->bio_error = ENOMEM;
111 ips_insert_free_cmd(sc, command);
115 command_struct = (ips_io_cmd *)command->command_buffer;
116 command_struct->id = command->id;
117 command_struct->drivenum = (uintptr_t)iobuf->bio_driver1;
119 if (ips_read_request(iobuf))
120 cmdtype = IPS_SG_READ_CMD;
122 cmdtype = IPS_SG_WRITE_CMD;
123 command_struct->segnum = segnum;
124 sg_list = (ips_sg_element_t *)((u_int8_t *)
125 command->command_buffer + IPS_COMMAND_LEN);
126 for (i = 0; i < segnum; i++) {
127 sg_list[i].addr = segments[i].ds_addr;
128 sg_list[i].len = segments[i].ds_len;
129 length += segments[i].ds_len;
131 command_struct->buffaddr =
132 (u_int32_t)command->command_phys_addr + IPS_COMMAND_LEN;
134 if (ips_read_request(iobuf))
135 cmdtype = IPS_READ_CMD;
137 cmdtype = IPS_WRITE_CMD;
138 command_struct->buffaddr = segments[0].ds_addr;
139 length = segments[0].ds_len;
141 command_struct->command = cmdtype;
142 command_struct->lba = iobuf->bio_pblkno;
143 length = (length + IPS_BLKSIZE - 1)/IPS_BLKSIZE;
144 command_struct->length = length;
145 bus_dmamap_sync(sc->command_dmatag, command->command_dmamap,
146 BUS_DMASYNC_PREWRITE);
147 if (ips_read_request(iobuf)) {
148 bus_dmamap_sync(command->data_dmatag, command->data_dmamap,
149 BUS_DMASYNC_PREREAD);
151 bus_dmamap_sync(command->data_dmatag, command->data_dmamap,
152 BUS_DMASYNC_PREWRITE);
155 * the cast to long long below is necessary because our b_pblkno
156 * is 32bit wide whereas it's 64bit on FreeBSD-CURRENT.
158 PRINTF(10, "ips test: command id: %d segments: %d "
159 "pblkno: %lld length: %d, ds_len: %d\n", command->id, segnum,
160 (long long)iobuf->bio_pblkno,
161 length, segments[0].ds_len);
163 sc->ips_issue_cmd(command);
168 ips_send_io_request(ips_command_t *command)
170 ips_softc_t *sc = command->sc;
171 struct bio *iobuf = command->arg;
172 command->data_dmatag = sc->sg_dmatag;
174 if (bus_dmamap_create(command->data_dmatag, 0, &command->data_dmamap)) {
175 device_printf(sc->dev, "dmamap failed\n");
176 iobuf->bio_flags |= BIO_ERROR;
177 iobuf->bio_error = ENOMEM;
178 ips_insert_free_cmd(sc, command);
182 command->callback = ips_io_request_finish;
183 PRINTF(10, "ips test: : bcount %ld\n", iobuf->bio_bcount);
184 bus_dmamap_load(command->data_dmatag, command->data_dmamap,
185 iobuf->bio_data, iobuf->bio_bcount,
186 ips_io_request_callback, command, 0);
191 ips_start_io_request(ips_softc_t *sc, struct bio *iobuf)
193 if (ips_get_free_cmd(sc, ips_send_io_request, iobuf, 0)) {
194 device_printf(sc->dev, "no mem for command slots!\n");
195 iobuf->bio_flags |= BIO_ERROR;
196 iobuf->bio_error = ENOMEM;
204 * Below are a series of functions for sending an adapter info request
205 * to the adapter. The flow order is: get, send, callback. It uses
206 * the generic finish callback at the top of this file.
207 * This can be used to get configuration/status info from the card
210 ips_adapter_info_callback(void *cmdptr, bus_dma_segment_t *segments,int segnum,
214 ips_command_t *command = cmdptr;
215 ips_adapter_info_cmd *command_struct;
218 ips_cmd_status_t * status = command->arg;
219 status->value = IPS_ERROR_STATUS; /* a lovely error value */
220 ips_insert_free_cmd(sc, command);
221 printf("ips: error = %d in ips_get_adapter_info\n", error);
224 command_struct = (ips_adapter_info_cmd *)command->command_buffer;
225 command_struct->command = IPS_ADAPTER_INFO_CMD;
226 command_struct->id = command->id;
227 command_struct->buffaddr = segments[0].ds_addr;
229 bus_dmamap_sync(sc->command_dmatag, command->command_dmamap,
230 BUS_DMASYNC_PREWRITE);
231 bus_dmamap_sync(command->data_dmatag, command->data_dmamap,
232 BUS_DMASYNC_PREREAD);
233 sc->ips_issue_cmd(command);
237 ips_send_adapter_info_cmd(ips_command_t *command)
239 ips_softc_t *sc = command->sc;
240 ips_cmd_status_t *status = command->arg;
243 if (bus_dma_tag_create( /* parent */ sc->adapter_dmatag,
246 /* lowaddr */ BUS_SPACE_MAXADDR_32BIT,
247 /* highaddr */ BUS_SPACE_MAXADDR,
249 /* filterarg */ NULL,
250 /* maxsize */ IPS_ADAPTER_INFO_LEN,
252 /* maxsegsize*/ IPS_ADAPTER_INFO_LEN,
254 &command->data_dmatag) != 0) {
255 printf("ips: can't alloc dma tag for adapter status\n");
259 if (bus_dmamem_alloc(command->data_dmatag, &command->data_buffer,
260 BUS_DMA_NOWAIT, &command->data_dmamap)) {
264 command->callback = ips_wakeup_callback;
266 bus_dmamap_load(command->data_dmatag, command->data_dmamap,
267 command->data_buffer, IPS_ADAPTER_INFO_LEN,
268 ips_adapter_info_callback, command, BUS_DMA_NOWAIT);
269 if ((status->value == IPS_ERROR_STATUS) ||
270 ips_msleep(status, sc, 0, "ips", 30 * hz) == EWOULDBLOCK)
274 bus_dmamap_sync(command->data_dmatag, command->data_dmamap,
275 BUS_DMASYNC_POSTREAD);
276 memcpy(&(sc->adapter_info), command->data_buffer,
277 IPS_ADAPTER_INFO_LEN);
279 bus_dmamap_unload(command->data_dmatag, command->data_dmamap);
281 /* I suppose I should clean up my memory allocations */
282 bus_dmamem_free(command->data_dmatag, command->data_buffer,
283 command->data_dmamap);
284 bus_dma_tag_destroy(command->data_dmatag);
285 ips_insert_free_cmd(sc, command);
290 ips_get_adapter_info(ips_softc_t *sc)
293 ips_cmd_status_t *status;
295 status = malloc(sizeof(ips_cmd_status_t), M_DEVBUF, M_INTWAIT | M_ZERO);
296 if (ips_get_free_cmd(sc, ips_send_adapter_info_cmd, status,
297 IPS_NOWAIT_FLAG) > 0) {
298 device_printf(sc->dev, "unable to get adapter configuration\n");
299 free(status, M_DEVBUF);
302 if (COMMAND_ERROR(status))
304 free(status, M_DEVBUF);
309 * Below are a series of functions for sending a drive info request
310 * to the adapter. The flow order is: get, send, callback. It uses
311 * the generic finish callback at the top of this file.
312 * This can be used to get drive status info from the card
315 ips_drive_info_callback(void *cmdptr, bus_dma_segment_t *segments, int segnum,
319 ips_command_t *command = cmdptr;
320 ips_drive_cmd *command_struct;
324 ips_cmd_status_t *status = command->arg;
326 status->value = IPS_ERROR_STATUS;
327 ips_insert_free_cmd(sc, command);
328 printf("ips: error = %d in ips_get_drive_info\n", error);
331 command_struct = (ips_drive_cmd *)command->command_buffer;
332 command_struct->command = IPS_DRIVE_INFO_CMD;
333 command_struct->id = command->id;
334 command_struct->buffaddr = segments[0].ds_addr;
335 bus_dmamap_sync(sc->command_dmatag, command->command_dmamap,
336 BUS_DMASYNC_PREWRITE);
337 bus_dmamap_sync(command->data_dmatag, command->data_dmamap,
338 BUS_DMASYNC_PREREAD);
339 sc->ips_issue_cmd(command);
343 ips_send_drive_info_cmd(ips_command_t *command)
346 ips_softc_t *sc = command->sc;
347 ips_cmd_status_t *status = command->arg;
348 ips_drive_info_t *driveinfo;
350 if (bus_dma_tag_create( /* parent */ sc->adapter_dmatag,
353 /* lowaddr */ BUS_SPACE_MAXADDR_32BIT,
354 /* highaddr */ BUS_SPACE_MAXADDR,
356 /* filterarg */ NULL,
357 /* maxsize */ IPS_DRIVE_INFO_LEN,
359 /* maxsegsize*/ IPS_DRIVE_INFO_LEN,
361 &command->data_dmatag) != 0) {
362 printf("ips: can't alloc dma tag for drive status\n");
366 if (bus_dmamem_alloc(command->data_dmatag, &command->data_buffer,
367 BUS_DMA_NOWAIT, &command->data_dmamap)) {
371 command->callback = ips_wakeup_callback;
373 bus_dmamap_load(command->data_dmatag, command->data_dmamap,
374 command->data_buffer,IPS_DRIVE_INFO_LEN,
375 ips_drive_info_callback, command, BUS_DMA_NOWAIT);
376 if ((status->value == IPS_ERROR_STATUS) ||
377 ips_msleep(status, sc, 0, "ips", 10 * hz) == EWOULDBLOCK)
382 bus_dmamap_sync(command->data_dmatag, command->data_dmamap,
383 BUS_DMASYNC_POSTREAD);
384 driveinfo = command->data_buffer;
385 memcpy(sc->drives, driveinfo->drives, sizeof(ips_drive_t) * 8);
386 sc->drivecount = driveinfo->drivecount;
387 device_printf(sc->dev, "logical drives: %d\n", sc->drivecount);
389 bus_dmamap_unload(command->data_dmatag, command->data_dmamap);
391 /* I suppose I should clean up my memory allocations */
392 bus_dmamem_free(command->data_dmatag, command->data_buffer,
393 command->data_dmamap);
394 bus_dma_tag_destroy(command->data_dmatag);
395 ips_insert_free_cmd(sc, command);
400 ips_get_drive_info(ips_softc_t *sc)
403 ips_cmd_status_t *status;
405 status = malloc(sizeof(ips_cmd_status_t), M_DEVBUF, M_INTWAIT | M_ZERO);
406 if (ips_get_free_cmd(sc, ips_send_drive_info_cmd, status,
407 IPS_NOWAIT_FLAG) > 0) {
408 free(status, M_DEVBUF);
409 device_printf(sc->dev, "unable to get drive configuration\n");
412 if (COMMAND_ERROR(status))
414 free(status, M_DEVBUF);
419 * Below is a pair of functions for making sure data is safely
420 * on disk by flushing the adapter's cache.
423 ips_send_flush_cache_cmd(ips_command_t *command)
425 ips_softc_t *sc = command->sc;
426 ips_cmd_status_t *status = command->arg;
427 ips_generic_cmd *command_struct;
429 PRINTF(10,"ips test: got a command, building flush command\n");
430 command->callback = ips_wakeup_callback;
431 command_struct = (ips_generic_cmd *)command->command_buffer;
432 command_struct->command = IPS_CACHE_FLUSH_CMD;
433 command_struct->id = command->id;
434 bus_dmamap_sync(sc->command_dmatag, command->command_dmamap,
435 BUS_DMASYNC_PREWRITE);
437 sc->ips_issue_cmd(command);
438 if (status->value != IPS_ERROR_STATUS)
439 ips_msleep(status, sc, 0, "flush2", 0);
441 ips_insert_free_cmd(sc, command);
446 ips_flush_cache(ips_softc_t *sc)
448 ips_cmd_status_t *status;
450 status = malloc(sizeof(ips_cmd_status_t), M_DEVBUF, M_INTWAIT | M_ZERO);
451 device_printf(sc->dev, "flushing cache\n");
452 if (ips_get_free_cmd(sc, ips_send_flush_cache_cmd, status,
454 free(status, M_DEVBUF);
455 device_printf(sc->dev, "ERROR: unable to get a command! "
456 "can't flush cache!\n");
459 if (COMMAND_ERROR(status)) {
460 free(status, M_DEVBUF);
461 device_printf(sc->dev, "ERROR: cache flush command failed!\n");
464 free(status, M_DEVBUF);
469 * Simplified localtime to provide timevalues for ffdc.
470 * Taken from libc/stdtime/localtime.c
473 ips_ffdc_settime(ips_adapter_ffdc_cmd *command, time_t sctime)
476 int yleap, *ip, month;
477 int year_lengths[2] = { IPS_DAYSPERNYEAR, IPS_DAYSPERLYEAR };
478 int mon_lengths[2][IPS_MONSPERYEAR] = {
479 { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
480 { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
483 days = sctime / IPS_SECSPERDAY;
484 rem = sctime % IPS_SECSPERDAY;
486 command->hour = rem / IPS_SECSPERHOUR;
487 rem = rem % IPS_SECSPERHOUR;
489 command->minute = rem / IPS_SECSPERMIN;
490 command->second = rem % IPS_SECSPERMIN;
493 while (days < 0 || days >= (long)year_lengths[yleap = ips_isleap(y)]) {
496 newy = y + days / IPS_DAYSPERNYEAR;
499 days -= (newy - y) * IPS_DAYSPERNYEAR +
500 IPS_LEAPS_THRU_END_OF(newy - 1) -
501 IPS_LEAPS_THRU_END_OF(y - 1);
504 command->yearH = y / 100;
505 command->yearL = y % 100;
506 ip = mon_lengths[yleap];
507 for (month = 0; days >= (long)ip[month]; ++month)
508 days = days - (long)ip[month];
509 command->month = month + 1;
510 command->day = days + 1;
514 ips_send_ffdc_reset_cmd(ips_command_t *command)
516 ips_softc_t *sc = command->sc;
517 ips_cmd_status_t *status = command->arg;
518 ips_adapter_ffdc_cmd *command_struct;
520 PRINTF(10, "ips test: got a command, building ffdc reset command\n");
521 command->callback = ips_wakeup_callback;
522 command_struct = (ips_adapter_ffdc_cmd *)command->command_buffer;
523 command_struct->command = IPS_FFDC_CMD;
524 command_struct->id = command->id;
525 command_struct->reset_count = sc->ffdc_resetcount;
526 command_struct->reset_type = 0x0;
527 ips_ffdc_settime(command_struct, sc->ffdc_resettime.tv_sec);
528 bus_dmamap_sync(sc->command_dmatag, command->command_dmamap,
529 BUS_DMASYNC_PREWRITE);
531 sc->ips_issue_cmd(command);
532 if (status->value != IPS_ERROR_STATUS)
533 ips_msleep(status, sc, 0, "ffdc", 0);
535 ips_insert_free_cmd(sc, command);
540 ips_ffdc_reset(ips_softc_t *sc)
542 ips_cmd_status_t *status;
544 status = malloc(sizeof(ips_cmd_status_t), M_DEVBUF, M_INTWAIT | M_ZERO);
545 if (ips_get_free_cmd(sc, ips_send_ffdc_reset_cmd, status,
547 free(status, M_DEVBUF);
548 device_printf(sc->dev, "ERROR: unable to get a command! "
549 "can't send ffdc reset!\n");
552 if (COMMAND_ERROR(status)) {
553 free(status, M_DEVBUF);
554 device_printf(sc->dev, "ERROR: ffdc reset command failed!\n");
557 free(status, M_DEVBUF);
562 ips_write_nvram(ips_command_t *command)
564 ips_softc_t *sc = command->sc;
565 ips_rw_nvram_cmd *command_struct;
566 ips_nvram_page5 *nvram;
568 /*FIXME check for error */
569 command->callback = ips_wakeup_callback;
570 command_struct = (ips_rw_nvram_cmd *)command->command_buffer;
571 command_struct->command = IPS_RW_NVRAM_CMD;
572 command_struct->id = command->id;
573 command_struct->pagenum = 5;
574 command_struct->rw = 1; /* write */
575 bus_dmamap_sync(command->data_dmatag, command->data_dmamap,
576 BUS_DMASYNC_POSTREAD);
577 nvram = command->data_buffer;
578 /* retrieve adapter info and save in sc */
579 sc->adapter_type = nvram->adapter_type;
580 strncpy(nvram->driver_high, IPS_VERSION_MAJOR, 4);
581 strncpy(nvram->driver_low, IPS_VERSION_MINOR, 4);
582 nvram->operating_system = IPS_OS_FREEBSD;
583 bus_dmamap_sync(sc->command_dmatag, command->command_dmamap,
584 BUS_DMASYNC_PREWRITE);
585 sc->ips_issue_cmd(command);
589 ips_read_nvram_callback(void *cmdptr, bus_dma_segment_t *segments, int segnum,
593 ips_command_t *command = cmdptr;
594 ips_rw_nvram_cmd *command_struct;
598 ips_cmd_status_t *status = command->arg;
600 status->value = IPS_ERROR_STATUS;
601 ips_insert_free_cmd(sc, command);
602 printf("ips: error = %d in ips_read_nvram_callback\n", error);
605 command_struct = (ips_rw_nvram_cmd *)command->command_buffer;
606 command_struct->command = IPS_RW_NVRAM_CMD;
607 command_struct->id = command->id;
608 command_struct->pagenum = 5;
609 command_struct->rw = 0;
610 command_struct->buffaddr = segments[0].ds_addr;
612 bus_dmamap_sync(sc->command_dmatag, command->command_dmamap,
613 BUS_DMASYNC_PREWRITE);
614 bus_dmamap_sync(command->data_dmatag, command->data_dmamap,
615 BUS_DMASYNC_PREREAD);
616 sc->ips_issue_cmd(command);
620 ips_read_nvram(ips_command_t *command)
623 ips_softc_t *sc = command->sc;
624 ips_cmd_status_t *status = command->arg;
626 if (bus_dma_tag_create( /* parent */ sc->adapter_dmatag,
629 /* lowaddr */ BUS_SPACE_MAXADDR_32BIT,
630 /* highaddr */ BUS_SPACE_MAXADDR,
632 /* filterarg */ NULL,
633 /* maxsize */ IPS_NVRAM_PAGE_SIZE,
635 /* maxsegsize*/ IPS_NVRAM_PAGE_SIZE,
637 &command->data_dmatag) != 0) {
638 printf("ips: can't alloc dma tag for nvram\n");
642 if (bus_dmamem_alloc(command->data_dmatag, &command->data_buffer,
643 BUS_DMA_NOWAIT, &command->data_dmamap)) {
647 command->callback = ips_write_nvram;
649 bus_dmamap_load(command->data_dmatag, command->data_dmamap,
650 command->data_buffer, IPS_NVRAM_PAGE_SIZE, ips_read_nvram_callback,
651 command, BUS_DMA_NOWAIT);
652 if ((status->value == IPS_ERROR_STATUS) ||
653 ips_msleep(status, sc, 0, "ips", 0) == EWOULDBLOCK)
657 bus_dmamap_sync(command->data_dmatag, command->data_dmamap,
658 BUS_DMASYNC_POSTWRITE);
660 bus_dmamap_unload(command->data_dmatag, command->data_dmamap);
662 bus_dmamem_free(command->data_dmatag, command->data_buffer,
663 command->data_dmamap);
664 bus_dma_tag_destroy(command->data_dmatag);
665 ips_insert_free_cmd(sc, command);
670 ips_update_nvram(ips_softc_t *sc)
672 ips_cmd_status_t *status;
674 status = malloc(sizeof(ips_cmd_status_t), M_DEVBUF, M_INTWAIT | M_ZERO);
675 if (ips_get_free_cmd(sc, ips_read_nvram, status, IPS_NOWAIT_FLAG)) {
676 free(status, M_DEVBUF);
677 device_printf(sc->dev, "ERROR: unable to get a command! "
678 "can't update nvram\n");
681 if (COMMAND_ERROR(status)) {
682 free(status, M_DEVBUF);
683 device_printf(sc->dev, "ERROR: nvram update command failed!\n");
686 free(status, M_DEVBUF);
691 ips_send_config_sync_cmd(ips_command_t *command)
693 ips_softc_t *sc = command->sc;
694 ips_cmd_status_t *status = command->arg;
695 ips_generic_cmd *command_struct;
697 PRINTF(10, "ips test: got a command, building flush command\n");
698 command->callback = ips_wakeup_callback;
699 command_struct = (ips_generic_cmd *)command->command_buffer;
700 command_struct->command = IPS_CONFIG_SYNC_CMD;
701 command_struct->id = command->id;
702 command_struct->reserve2 = IPS_POCL;
703 bus_dmamap_sync(sc->command_dmatag, command->command_dmamap,
704 BUS_DMASYNC_PREWRITE);
706 sc->ips_issue_cmd(command);
707 if (status->value != IPS_ERROR_STATUS)
708 ips_msleep(status, sc, 0, "ipssyn", 0);
710 ips_insert_free_cmd(sc, command);
715 ips_send_error_table_cmd(ips_command_t *command)
717 ips_softc_t *sc = command->sc;
718 ips_cmd_status_t *status = command->arg;
719 ips_generic_cmd *command_struct;
721 PRINTF(10, "ips test: got a command, building errortable command\n");
722 command->callback = ips_wakeup_callback;
723 command_struct = (ips_generic_cmd *)command->command_buffer;
724 command_struct->command = IPS_ERROR_TABLE_CMD;
725 command_struct->id = command->id;
726 command_struct->reserve2 = IPS_CSL;
727 bus_dmamap_sync(sc->command_dmatag, command->command_dmamap,
728 BUS_DMASYNC_PREWRITE);
730 sc->ips_issue_cmd(command);
731 if (status->value != IPS_ERROR_STATUS)
732 ips_msleep(status, sc, 0, "ipsetc", 0);
734 ips_insert_free_cmd(sc, command);
739 ips_clear_adapter(ips_softc_t *sc)
741 ips_cmd_status_t *status;
743 status = malloc(sizeof(ips_cmd_status_t), M_DEVBUF, M_INTWAIT | M_ZERO);
744 device_printf(sc->dev, "syncing config\n");
745 if (ips_get_free_cmd(sc, ips_send_config_sync_cmd, status,
747 free(status, M_DEVBUF);
748 device_printf(sc->dev, "ERROR: unable to get a command! "
749 "can't sync cache!\n");
752 if (COMMAND_ERROR(status)) {
753 free(status, M_DEVBUF);
754 device_printf(sc->dev, "ERROR: cache sync command failed!\n");
757 device_printf(sc->dev, "clearing error table\n");
758 if (ips_get_free_cmd(sc, ips_send_error_table_cmd, status,
760 free(status, M_DEVBUF);
761 device_printf(sc->dev, "ERROR: unable to get a command! "
762 "can't sync cache!\n");
765 if (COMMAND_ERROR(status)) {
766 device_printf(sc->dev, "ERROR: etable command failed!\n");
767 free(status, M_DEVBUF);
770 free(status, M_DEVBUF);