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.10 2004/05/30 04:01:29 scottl Exp $
28 * $DragonFly: src/sys/dev/raid/ips/ips_commands.c,v 1.13 2006/12/23 00:26:23 swildner Exp $
31 #include <sys/devicestat.h>
32 #include <dev/raid/ips/ips.h>
33 #include <dev/raid/ips/ips_disk.h>
36 ips_timed_wait(ips_command_t
*command
, const char *id
, int timo
)
40 while (command
->completed
== 0) {
42 if (command
->completed
== 0)
43 error
= tsleep(&command
->completed
, 0, id
, timo
);
45 if (error
== EWOULDBLOCK
) {
54 * This is an interrupt callback. It is called from
55 * interrupt context when the adapter has completed the
56 * command, and wakes up anyone waiting on the command.
59 ips_wakeup_callback(ips_command_t
*command
)
61 bus_dmamap_sync(command
->sc
->command_dmatag
, command
->command_dmamap
,
62 BUS_DMASYNC_POSTWRITE
);
63 command
->completed
= 1;
64 wakeup(&command
->completed
);
68 * Below are a series of functions for sending an IO request
69 * to the adapter. The flow order is: start, send, callback, finish.
70 * The caller must have already assembled an iorequest struct to hold
71 * the details of the IO request.
74 ips_io_request_finish(ips_command_t
*command
)
76 struct bio
*bio
= command
->arg
;
78 if (ips_read_request(bio
)) {
79 bus_dmamap_sync(command
->data_dmatag
, command
->data_dmamap
,
80 BUS_DMASYNC_POSTREAD
);
82 bus_dmamap_sync(command
->data_dmatag
, command
->data_dmamap
,
83 BUS_DMASYNC_POSTWRITE
);
85 bus_dmamap_unload(command
->data_dmatag
, command
->data_dmamap
);
86 if (COMMAND_ERROR(&command
->status
)) {
87 bio
->bio_buf
->b_flags
|=B_ERROR
;
88 bio
->bio_buf
->b_error
= EIO
;
90 ips_insert_free_cmd(command
->sc
, command
);
95 ips_io_request_callback(void *cmdptr
, bus_dma_segment_t
*segments
, int segnum
,
99 ips_command_t
*command
= cmdptr
;
100 ips_sg_element_t
*sg_list
;
101 ips_io_cmd
*command_struct
;
102 struct bio
*bio
= command
->arg
;
103 struct buf
*bp
= bio
->bio_buf
;
104 ipsdisk_softc_t
*dsc
;
110 kprintf("ips: error = %d in ips_sg_request_callback\n", error
);
111 bus_dmamap_unload(command
->data_dmatag
, command
->data_dmamap
);
112 bp
->b_flags
|= B_ERROR
;
113 bp
->b_error
= ENOMEM
;
114 ips_insert_free_cmd(sc
, command
);
118 dsc
= bio
->bio_driver_info
;
119 command_struct
= (ips_io_cmd
*)command
->command_buffer
;
120 command_struct
->id
= command
->id
;
121 command_struct
->drivenum
= dsc
->sc
->drives
[dsc
->disk_number
].drivenum
;
124 if (ips_read_request(bio
))
125 cmdtype
= IPS_SG_READ_CMD
;
127 cmdtype
= IPS_SG_WRITE_CMD
;
128 command_struct
->segnum
= segnum
;
129 sg_list
= (ips_sg_element_t
*)((u_int8_t
*)
130 command
->command_buffer
+ IPS_COMMAND_LEN
);
131 for (i
= 0; i
< segnum
; i
++) {
132 sg_list
[i
].addr
= segments
[i
].ds_addr
;
133 sg_list
[i
].len
= segments
[i
].ds_len
;
134 length
+= segments
[i
].ds_len
;
136 command_struct
->buffaddr
=
137 (u_int32_t
)command
->command_phys_addr
+ IPS_COMMAND_LEN
;
139 if (ips_read_request(bio
))
140 cmdtype
= IPS_READ_CMD
;
142 cmdtype
= IPS_WRITE_CMD
;
143 command_struct
->buffaddr
= segments
[0].ds_addr
;
144 length
= segments
[0].ds_len
;
146 command_struct
->command
= cmdtype
;
147 command_struct
->lba
= bio
->bio_offset
/ IPS_BLKSIZE
;
148 length
= (length
+ IPS_BLKSIZE
- 1)/IPS_BLKSIZE
;
149 command_struct
->length
= length
;
150 bus_dmamap_sync(sc
->command_dmatag
, command
->command_dmamap
,
151 BUS_DMASYNC_PREWRITE
);
152 if (ips_read_request(bio
)) {
153 bus_dmamap_sync(command
->data_dmatag
, command
->data_dmamap
,
154 BUS_DMASYNC_PREREAD
);
156 bus_dmamap_sync(command
->data_dmatag
, command
->data_dmamap
,
157 BUS_DMASYNC_PREWRITE
);
160 * the cast to long long below is necessary because our b_pblkno
161 * is 32bit wide whereas it's 64bit on FreeBSD-CURRENT.
163 PRINTF(10, "ips test: command id: %d segments: %d "
164 "pblkno: %lld length: %d, ds_len: %d\n", command
->id
, segnum
,
165 bio
->bio_offset
/ IPS_BLKSIZE
,
166 length
, segments
[0].ds_len
);
168 sc
->ips_issue_cmd(command
);
173 ips_send_io_request(ips_command_t
*command
, struct bio
*bio
)
175 struct buf
*bp
= bio
->bio_buf
;
177 command
->callback
= ips_io_request_finish
;
179 PRINTF(10, "ips test: : bcount %ld\n", bp
->b_bcount
);
180 bus_dmamap_load(command
->data_dmatag
, command
->data_dmamap
,
181 bp
->b_data
, bp
->b_bcount
,
182 ips_io_request_callback
, command
, 0);
187 ips_start_io_request(ips_softc_t
*sc
)
189 ips_command_t
*command
;
192 bio
= bioq_first(&sc
->bio_queue
);
195 if (ips_get_free_cmd(sc
, &command
, 0) != 0)
197 bioq_remove(&sc
->bio_queue
, bio
);
198 ips_send_io_request(command
, bio
);
202 * Below are a series of functions for sending an adapter info request
203 * to the adapter. The flow order is: get, send, callback. It uses
204 * the generic finish callback at the top of this file.
205 * This can be used to get configuration/status info from the card
208 ips_adapter_info_callback(void *cmdptr
, bus_dma_segment_t
*segments
,int segnum
,
212 ips_command_t
*command
= cmdptr
;
213 ips_adapter_info_cmd
*command_struct
;
216 command
->status
.value
= IPS_ERROR_STATUS
; /* a lovely error value */
217 ips_insert_free_cmd(sc
, command
);
218 kprintf("ips: error = %d in ips_get_adapter_info\n", error
);
221 command_struct
= (ips_adapter_info_cmd
*)command
->command_buffer
;
222 command_struct
->command
= IPS_ADAPTER_INFO_CMD
;
223 command_struct
->id
= command
->id
;
224 command_struct
->buffaddr
= segments
[0].ds_addr
;
226 bus_dmamap_sync(sc
->command_dmatag
, command
->command_dmamap
,
227 BUS_DMASYNC_PREWRITE
);
228 bus_dmamap_sync(command
->data_dmatag
, command
->data_dmamap
,
229 BUS_DMASYNC_PREREAD
);
230 sc
->ips_issue_cmd(command
);
234 ips_send_adapter_info_cmd(ips_command_t
*command
)
236 ips_softc_t
*sc
= command
->sc
;
239 if (bus_dma_tag_create( /* parent */ sc
->adapter_dmatag
,
242 /* lowaddr */ BUS_SPACE_MAXADDR_32BIT
,
243 /* highaddr */ BUS_SPACE_MAXADDR
,
245 /* filterarg */ NULL
,
246 /* maxsize */ IPS_ADAPTER_INFO_LEN
,
248 /* maxsegsize*/ IPS_ADAPTER_INFO_LEN
,
250 &command
->data_dmatag
) != 0) {
251 kprintf("ips: can't alloc dma tag for adapter status\n");
255 if (bus_dmamem_alloc(command
->data_dmatag
, &command
->data_buffer
,
256 BUS_DMA_NOWAIT
, &command
->data_dmamap
)) {
260 command
->callback
= ips_wakeup_callback
;
261 bus_dmamap_load(command
->data_dmatag
, command
->data_dmamap
,
262 command
->data_buffer
, IPS_ADAPTER_INFO_LEN
,
263 ips_adapter_info_callback
, command
, BUS_DMA_NOWAIT
);
264 if ((command
->status
.value
== IPS_ERROR_STATUS
) ||
265 ips_timed_wait(command
, "ips", 30 * hz
) != 0)
268 bus_dmamap_sync(command
->data_dmatag
, command
->data_dmamap
,
269 BUS_DMASYNC_POSTREAD
);
270 memcpy(&(sc
->adapter_info
), command
->data_buffer
,
271 IPS_ADAPTER_INFO_LEN
);
273 bus_dmamap_unload(command
->data_dmatag
, command
->data_dmamap
);
275 /* I suppose I should clean up my memory allocations */
276 bus_dmamem_free(command
->data_dmatag
, command
->data_buffer
,
277 command
->data_dmamap
);
278 bus_dma_tag_destroy(command
->data_dmatag
);
279 ips_insert_free_cmd(sc
, command
);
284 ips_get_adapter_info(ips_softc_t
*sc
)
286 ips_command_t
*command
;
289 if (ips_get_free_cmd(sc
, &command
, IPS_STATIC_FLAG
) != 0) {
290 device_printf(sc
->dev
, "unable to get adapter configuration\n");
293 ips_send_adapter_info_cmd(command
);
294 if (COMMAND_ERROR(&command
->status
))
300 * Below are a series of functions for sending a drive info request
301 * to the adapter. The flow order is: get, send, callback. It uses
302 * the generic finish callback at the top of this file.
303 * This can be used to get drive status info from the card
306 ips_drive_info_callback(void *cmdptr
, bus_dma_segment_t
*segments
, int segnum
,
310 ips_command_t
*command
= cmdptr
;
311 ips_drive_cmd
*command_struct
;
316 command
->status
.value
= IPS_ERROR_STATUS
;
317 ips_insert_free_cmd(sc
, command
);
318 kprintf("ips: error = %d in ips_get_drive_info\n", error
);
321 command_struct
= (ips_drive_cmd
*)command
->command_buffer
;
322 command_struct
->command
= IPS_DRIVE_INFO_CMD
;
323 command_struct
->id
= command
->id
;
324 command_struct
->buffaddr
= segments
[0].ds_addr
;
325 bus_dmamap_sync(sc
->command_dmatag
, command
->command_dmamap
,
326 BUS_DMASYNC_PREWRITE
);
327 bus_dmamap_sync(command
->data_dmatag
, command
->data_dmamap
,
328 BUS_DMASYNC_PREREAD
);
329 sc
->ips_issue_cmd(command
);
333 ips_send_drive_info_cmd(ips_command_t
*command
)
336 ips_softc_t
*sc
= command
->sc
;
337 ips_drive_info_t
*driveinfo
;
339 if (bus_dma_tag_create( /* parent */ sc
->adapter_dmatag
,
342 /* lowaddr */ BUS_SPACE_MAXADDR_32BIT
,
343 /* highaddr */ BUS_SPACE_MAXADDR
,
345 /* filterarg */ NULL
,
346 /* maxsize */ IPS_DRIVE_INFO_LEN
,
348 /* maxsegsize*/ IPS_DRIVE_INFO_LEN
,
350 &command
->data_dmatag
) != 0) {
351 kprintf("ips: can't alloc dma tag for drive status\n");
355 if (bus_dmamem_alloc(command
->data_dmatag
, &command
->data_buffer
,
356 BUS_DMA_NOWAIT
, &command
->data_dmamap
)) {
360 command
->callback
= ips_wakeup_callback
;
361 bus_dmamap_load(command
->data_dmatag
, command
->data_dmamap
,
362 command
->data_buffer
,IPS_DRIVE_INFO_LEN
,
363 ips_drive_info_callback
, command
, BUS_DMA_NOWAIT
);
364 if ((command
->status
.value
== IPS_ERROR_STATUS
) ||
365 ips_timed_wait(command
, "ips", 10 * hz
) != 0)
369 bus_dmamap_sync(command
->data_dmatag
, command
->data_dmamap
,
370 BUS_DMASYNC_POSTREAD
);
371 driveinfo
= command
->data_buffer
;
372 memcpy(sc
->drives
, driveinfo
->drives
, sizeof(ips_drive_t
) * 8);
373 sc
->drivecount
= driveinfo
->drivecount
;
374 device_printf(sc
->dev
, "logical drives: %d\n", sc
->drivecount
);
376 bus_dmamap_unload(command
->data_dmatag
, command
->data_dmamap
);
378 /* I suppose I should clean up my memory allocations */
379 bus_dmamem_free(command
->data_dmatag
, command
->data_buffer
,
380 command
->data_dmamap
);
381 bus_dma_tag_destroy(command
->data_dmatag
);
382 ips_insert_free_cmd(sc
, command
);
387 ips_get_drive_info(ips_softc_t
*sc
)
390 ips_command_t
*command
;
392 if (ips_get_free_cmd(sc
, &command
, IPS_STATIC_FLAG
) != 0) {
393 device_printf(sc
->dev
, "unable to get drive configuration\n");
396 ips_send_drive_info_cmd(command
);
397 if (COMMAND_ERROR(&command
->status
))
403 * Below is a pair of functions for making sure data is safely
404 * on disk by flushing the adapter's cache.
407 ips_send_flush_cache_cmd(ips_command_t
*command
)
409 ips_softc_t
*sc
= command
->sc
;
410 ips_generic_cmd
*command_struct
;
412 PRINTF(10,"ips test: got a command, building flush command\n");
413 command
->callback
= ips_wakeup_callback
;
414 command_struct
= (ips_generic_cmd
*)command
->command_buffer
;
415 command_struct
->command
= IPS_CACHE_FLUSH_CMD
;
416 command_struct
->id
= command
->id
;
417 bus_dmamap_sync(sc
->command_dmatag
, command
->command_dmamap
,
418 BUS_DMASYNC_PREWRITE
);
419 sc
->ips_issue_cmd(command
);
420 if (command
->status
.value
!= IPS_ERROR_STATUS
)
421 ips_timed_wait(command
, "flush2", 0);
422 ips_insert_free_cmd(sc
, command
);
427 ips_flush_cache(ips_softc_t
*sc
)
429 ips_command_t
*command
;
431 device_printf(sc
->dev
, "flushing cache\n");
432 if (ips_get_free_cmd(sc
, &command
, IPS_STATIC_FLAG
) != 0) {
433 device_printf(sc
->dev
, "ERROR: unable to get a command! "
434 "can't flush cache!\n");
437 ips_send_flush_cache_cmd(command
);
438 if (COMMAND_ERROR(&command
->status
)) {
439 device_printf(sc
->dev
, "ERROR: cache flush command failed!\n");
446 * Simplified localtime to provide timevalues for ffdc.
447 * Taken from libc/stdtime/localtime.c
450 ips_ffdc_settime(ips_adapter_ffdc_cmd
*command
, time_t sctime
)
453 int yleap
, *ip
, month
;
454 int year_lengths
[2] = { IPS_DAYSPERNYEAR
, IPS_DAYSPERLYEAR
};
455 int mon_lengths
[2][IPS_MONSPERYEAR
] = {
456 { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
457 { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
460 days
= sctime
/ IPS_SECSPERDAY
;
461 rem
= sctime
% IPS_SECSPERDAY
;
463 command
->hour
= rem
/ IPS_SECSPERHOUR
;
464 rem
= rem
% IPS_SECSPERHOUR
;
466 command
->minute
= rem
/ IPS_SECSPERMIN
;
467 command
->second
= rem
% IPS_SECSPERMIN
;
470 while (days
< 0 || days
>= (long)year_lengths
[yleap
= ips_isleap(y
)]) {
473 newy
= y
+ days
/ IPS_DAYSPERNYEAR
;
476 days
-= (newy
- y
) * IPS_DAYSPERNYEAR
+
477 IPS_LEAPS_THRU_END_OF(newy
- 1) -
478 IPS_LEAPS_THRU_END_OF(y
- 1);
481 command
->yearH
= y
/ 100;
482 command
->yearL
= y
% 100;
483 ip
= mon_lengths
[yleap
];
484 for (month
= 0; days
>= (long)ip
[month
]; ++month
)
485 days
= days
- (long)ip
[month
];
486 command
->month
= month
+ 1;
487 command
->day
= days
+ 1;
491 ips_send_ffdc_reset_cmd(ips_command_t
*command
)
493 ips_softc_t
*sc
= command
->sc
;
494 ips_adapter_ffdc_cmd
*command_struct
;
496 PRINTF(10, "ips test: got a command, building ffdc reset command\n");
497 command
->callback
= ips_wakeup_callback
;
498 command_struct
= (ips_adapter_ffdc_cmd
*)command
->command_buffer
;
499 command_struct
->command
= IPS_FFDC_CMD
;
500 command_struct
->id
= command
->id
;
501 command_struct
->reset_count
= sc
->ffdc_resetcount
;
502 command_struct
->reset_type
= 0x0;
503 ips_ffdc_settime(command_struct
, sc
->ffdc_resettime
.tv_sec
);
504 bus_dmamap_sync(sc
->command_dmatag
, command
->command_dmamap
,
505 BUS_DMASYNC_PREWRITE
);
506 sc
->ips_issue_cmd(command
);
507 if (command
->status
.value
!= IPS_ERROR_STATUS
)
508 ips_timed_wait(command
, "ffdc", 0);
509 ips_insert_free_cmd(sc
, command
);
514 ips_ffdc_reset(ips_softc_t
*sc
)
516 ips_command_t
*command
;
518 if (ips_get_free_cmd(sc
, &command
, IPS_STATIC_FLAG
) != 0) {
519 device_printf(sc
->dev
, "ERROR: unable to get a command! "
520 "can't send ffdc reset!\n");
523 ips_send_ffdc_reset_cmd(command
);
524 if (COMMAND_ERROR(&command
->status
)) {
526 * apparently some cards may report error status for
527 * an ffdc reset command, even though it works correctly
528 * afterwards. just complain about that and proceed here.
530 device_printf(sc
->dev
,
531 "ERROR: ffdc reset command failed(0x%04x)!\n",
532 command
->status
.value
);
538 ips_write_nvram(ips_command_t
*command
)
540 ips_softc_t
*sc
= command
->sc
;
541 ips_rw_nvram_cmd
*command_struct
;
542 ips_nvram_page5
*nvram
;
544 /*FIXME check for error */
545 command
->callback
= ips_wakeup_callback
;
546 command_struct
= (ips_rw_nvram_cmd
*)command
->command_buffer
;
547 command_struct
->command
= IPS_RW_NVRAM_CMD
;
548 command_struct
->id
= command
->id
;
549 command_struct
->pagenum
= 5;
550 command_struct
->rw
= 1; /* write */
551 bus_dmamap_sync(command
->data_dmatag
, command
->data_dmamap
,
552 BUS_DMASYNC_POSTREAD
);
553 nvram
= command
->data_buffer
;
554 /* retrieve adapter info and save in sc */
555 sc
->adapter_type
= nvram
->adapter_type
;
556 strncpy(nvram
->driver_high
, IPS_VERSION_MAJOR
, 4);
557 strncpy(nvram
->driver_low
, IPS_VERSION_MINOR
, 4);
558 nvram
->operating_system
= IPS_OS_FREEBSD
;
559 bus_dmamap_sync(sc
->command_dmatag
, command
->command_dmamap
,
560 BUS_DMASYNC_PREWRITE
);
561 sc
->ips_issue_cmd(command
);
565 ips_read_nvram_callback(void *cmdptr
, bus_dma_segment_t
*segments
, int segnum
,
569 ips_command_t
*command
= cmdptr
;
570 ips_rw_nvram_cmd
*command_struct
;
574 command
->status
.value
= IPS_ERROR_STATUS
;
575 ips_insert_free_cmd(sc
, command
);
576 kprintf("ips: error = %d in ips_read_nvram_callback\n", error
);
579 command_struct
= (ips_rw_nvram_cmd
*)command
->command_buffer
;
580 command_struct
->command
= IPS_RW_NVRAM_CMD
;
581 command_struct
->id
= command
->id
;
582 command_struct
->pagenum
= 5;
583 command_struct
->rw
= 0;
584 command_struct
->buffaddr
= segments
[0].ds_addr
;
586 bus_dmamap_sync(sc
->command_dmatag
, command
->command_dmamap
,
587 BUS_DMASYNC_PREWRITE
);
588 bus_dmamap_sync(command
->data_dmatag
, command
->data_dmamap
,
589 BUS_DMASYNC_PREREAD
);
590 sc
->ips_issue_cmd(command
);
594 ips_read_nvram(ips_command_t
*command
)
597 ips_softc_t
*sc
= command
->sc
;
599 if (bus_dma_tag_create( /* parent */ sc
->adapter_dmatag
,
602 /* lowaddr */ BUS_SPACE_MAXADDR_32BIT
,
603 /* highaddr */ BUS_SPACE_MAXADDR
,
605 /* filterarg */ NULL
,
606 /* maxsize */ IPS_NVRAM_PAGE_SIZE
,
608 /* maxsegsize*/ IPS_NVRAM_PAGE_SIZE
,
610 &command
->data_dmatag
) != 0) {
611 kprintf("ips: can't alloc dma tag for nvram\n");
615 if (bus_dmamem_alloc(command
->data_dmatag
, &command
->data_buffer
,
616 BUS_DMA_NOWAIT
, &command
->data_dmamap
)) {
620 command
->callback
= ips_write_nvram
;
621 bus_dmamap_load(command
->data_dmatag
, command
->data_dmamap
,
622 command
->data_buffer
, IPS_NVRAM_PAGE_SIZE
, ips_read_nvram_callback
,
623 command
, BUS_DMA_NOWAIT
);
624 if ((command
->status
.value
== IPS_ERROR_STATUS
) ||
625 ips_timed_wait(command
, "ips", 0) != 0)
628 bus_dmamap_sync(command
->data_dmatag
, command
->data_dmamap
,
629 BUS_DMASYNC_POSTWRITE
);
631 bus_dmamap_unload(command
->data_dmatag
, command
->data_dmamap
);
633 bus_dmamem_free(command
->data_dmatag
, command
->data_buffer
,
634 command
->data_dmamap
);
635 bus_dma_tag_destroy(command
->data_dmatag
);
636 ips_insert_free_cmd(sc
, command
);
641 ips_update_nvram(ips_softc_t
*sc
)
643 ips_command_t
*command
;
645 if (ips_get_free_cmd(sc
, &command
, IPS_STATIC_FLAG
) != 0) {
646 device_printf(sc
->dev
, "ERROR: unable to get a command! "
647 "can't update nvram\n");
650 ips_read_nvram(command
);
651 if (COMMAND_ERROR(&command
->status
)) {
652 device_printf(sc
->dev
, "ERROR: nvram update command failed!\n");
659 ips_send_config_sync_cmd(ips_command_t
*command
)
661 ips_softc_t
*sc
= command
->sc
;
662 ips_generic_cmd
*command_struct
;
664 PRINTF(10, "ips test: got a command, building flush command\n");
665 command
->callback
= ips_wakeup_callback
;
666 command_struct
= (ips_generic_cmd
*)command
->command_buffer
;
667 command_struct
->command
= IPS_CONFIG_SYNC_CMD
;
668 command_struct
->id
= command
->id
;
669 command_struct
->reserve2
= IPS_POCL
;
670 bus_dmamap_sync(sc
->command_dmatag
, command
->command_dmamap
,
671 BUS_DMASYNC_PREWRITE
);
672 sc
->ips_issue_cmd(command
);
673 if (command
->status
.value
!= IPS_ERROR_STATUS
)
674 ips_timed_wait(command
, "ipssyn", 0);
675 ips_insert_free_cmd(sc
, command
);
680 ips_send_error_table_cmd(ips_command_t
*command
)
682 ips_softc_t
*sc
= command
->sc
;
683 ips_generic_cmd
*command_struct
;
685 PRINTF(10, "ips test: got a command, building errortable command\n");
686 command
->callback
= ips_wakeup_callback
;
687 command_struct
= (ips_generic_cmd
*)command
->command_buffer
;
688 command_struct
->command
= IPS_ERROR_TABLE_CMD
;
689 command_struct
->id
= command
->id
;
690 command_struct
->reserve2
= IPS_CSL
;
691 bus_dmamap_sync(sc
->command_dmatag
, command
->command_dmamap
,
692 BUS_DMASYNC_PREWRITE
);
693 sc
->ips_issue_cmd(command
);
694 if (command
->status
.value
!= IPS_ERROR_STATUS
)
695 ips_timed_wait(command
, "ipsetc", 0);
696 ips_insert_free_cmd(sc
, command
);
701 ips_clear_adapter(ips_softc_t
*sc
)
703 ips_command_t
*command
;
705 device_printf(sc
->dev
, "syncing config\n");
706 if (ips_get_free_cmd(sc
, &command
, IPS_STATIC_FLAG
) != 0) {
707 device_printf(sc
->dev
, "ERROR: unable to get a command! "
708 "can't sync cache!\n");
711 ips_send_config_sync_cmd(command
);
712 if (COMMAND_ERROR(&command
->status
)) {
713 device_printf(sc
->dev
, "ERROR: cache sync command failed!\n");
716 device_printf(sc
->dev
, "clearing error table\n");
717 if (ips_get_free_cmd(sc
, &command
, IPS_STATIC_FLAG
) != 0) {
718 device_printf(sc
->dev
, "ERROR: unable to get a command! "
719 "can't sync cache!\n");
722 ips_send_error_table_cmd(command
);
723 if (COMMAND_ERROR(&command
->status
)) {
724 device_printf(sc
->dev
, "ERROR: etable command failed!\n");