ips_commands.c (124040) | ips_commands.c (126364) |
---|---|
1/*- 2 * Written by: David Jeffery 3 * Copyright (c) 2002 Adaptec Inc. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 12 unchanged lines hidden (view full) --- 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 25 * SUCH DAMAGE. 26 */ 27 28#include <sys/cdefs.h> | 1/*- 2 * Written by: David Jeffery 3 * Copyright (c) 2002 Adaptec Inc. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 12 unchanged lines hidden (view full) --- 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 25 * SUCH DAMAGE. 26 */ 27 28#include <sys/cdefs.h> |
29__FBSDID("$FreeBSD: head/sys/dev/ips/ips_commands.c 124040 2004-01-01 10:22:10Z mbr $"); | 29__FBSDID("$FreeBSD: head/sys/dev/ips/ips_commands.c 126364 2004-02-28 19:14:41Z scottl $"); |
30 31#include <dev/ips/ips.h> 32 33/* 34 * This is an interrupt callback. It is called from 35 * interrupt context when the adapter has completed the 36 * command. This very generic callback simply stores 37 * the command's return value in command->arg and wake's 38 * up anyone waiting on the command. 39 */ 40static void ips_wakeup_callback(ips_command_t *command) 41{ 42 ips_cmd_status_t *status; 43 status = command->arg; 44 status->value = command->status.value; 45 bus_dmamap_sync(command->sc->command_dmatag, command->command_dmamap, 46 BUS_DMASYNC_POSTWRITE); | 30 31#include <dev/ips/ips.h> 32 33/* 34 * This is an interrupt callback. It is called from 35 * interrupt context when the adapter has completed the 36 * command. This very generic callback simply stores 37 * the command's return value in command->arg and wake's 38 * up anyone waiting on the command. 39 */ 40static void ips_wakeup_callback(ips_command_t *command) 41{ 42 ips_cmd_status_t *status; 43 status = command->arg; 44 status->value = command->status.value; 45 bus_dmamap_sync(command->sc->command_dmatag, command->command_dmamap, 46 BUS_DMASYNC_POSTWRITE); |
47 mtx_lock(&command->sc->cmd_mtx); 48 wakeup(status); 49 mtx_unlock(&command->sc->cmd_mtx); | 47 sema_post(&command->cmd_sema); |
50} 51/* Below are a series of functions for sending an IO request 52 * to the adapter. The flow order is: start, send, callback, finish. 53 * The caller must have already assembled an iorequest struct to hold 54 * the details of the IO request. */ 55static void ips_io_request_finish(ips_command_t *command) 56{ 57 --- 100 unchanged lines hidden (view full) --- 158 command->callback = ips_io_request_finish; 159 PRINTF(10, "ips test: : bcount %ld\n", iobuf->bio_bcount); 160 bus_dmamap_load(command->data_dmatag, command->data_dmamap, 161 iobuf->bio_data, iobuf->bio_bcount, 162 ips_io_request_callback, command, 0); 163 return 0; 164} 165 | 48} 49/* Below are a series of functions for sending an IO request 50 * to the adapter. The flow order is: start, send, callback, finish. 51 * The caller must have already assembled an iorequest struct to hold 52 * the details of the IO request. */ 53static void ips_io_request_finish(ips_command_t *command) 54{ 55 --- 100 unchanged lines hidden (view full) --- 156 command->callback = ips_io_request_finish; 157 PRINTF(10, "ips test: : bcount %ld\n", iobuf->bio_bcount); 158 bus_dmamap_load(command->data_dmatag, command->data_dmamap, 159 iobuf->bio_data, iobuf->bio_bcount, 160 ips_io_request_callback, command, 0); 161 return 0; 162} 163 |
166void ips_start_io_request(ips_softc_t *sc, struct bio *iobuf) | 164void ips_start_io_request(ips_softc_t *sc) |
167{ | 165{ |
168 if(ips_get_free_cmd(sc, ips_send_io_request, iobuf, 0)){ 169 device_printf(sc->dev, "no mem for command slots!\n"); 170 iobuf->bio_flags |= BIO_ERROR; 171 iobuf->bio_error = ENOMEM; 172 ipsd_finish(iobuf); | 166 struct bio *iobuf; 167 168 mtx_lock(&sc->queue_mtx); 169 iobuf = bioq_first(&sc->queue); 170 if(!iobuf) { 171 mtx_unlock(&sc->queue_mtx); |
173 return; 174 } | 172 return; 173 } |
174 175 if(ips_get_free_cmd(sc, ips_send_io_request, iobuf, IPS_NOWAIT_FLAG)){ 176 mtx_unlock(&sc->queue_mtx); 177 return; 178 } 179 180 bioq_remove(&sc->queue, iobuf); 181 mtx_unlock(&sc->queue_mtx); |
|
175 return; 176} 177 178/* Below are a series of functions for sending an adapter info request 179 * to the adapter. The flow order is: get, send, callback. It uses 180 * the generic finish callback at the top of this file. 181 * This can be used to get configuration/status info from the card */ 182static void ips_adapter_info_callback(void *cmdptr, bus_dma_segment_t *segments,int segnum, int error) --- 48 unchanged lines hidden (view full) --- 231 goto exit; 232 } 233 if(bus_dmamem_alloc(command->data_dmatag, &command->data_buffer, 234 BUS_DMA_NOWAIT, &command->data_dmamap)){ 235 error = ENOMEM; 236 goto exit; 237 } 238 command->callback = ips_wakeup_callback; | 182 return; 183} 184 185/* Below are a series of functions for sending an adapter info request 186 * to the adapter. The flow order is: get, send, callback. It uses 187 * the generic finish callback at the top of this file. 188 * This can be used to get configuration/status info from the card */ 189static void ips_adapter_info_callback(void *cmdptr, bus_dma_segment_t *segments,int segnum, int error) --- 48 unchanged lines hidden (view full) --- 238 goto exit; 239 } 240 if(bus_dmamem_alloc(command->data_dmatag, &command->data_buffer, 241 BUS_DMA_NOWAIT, &command->data_dmamap)){ 242 error = ENOMEM; 243 goto exit; 244 } 245 command->callback = ips_wakeup_callback; |
239 mtx_lock(&sc->cmd_mtx); | |
240 bus_dmamap_load(command->data_dmatag, command->data_dmamap, 241 command->data_buffer,IPS_ADAPTER_INFO_LEN, 242 ips_adapter_info_callback, command, BUS_DMA_NOWAIT); 243 244 if ((status->value == IPS_ERROR_STATUS) || | 246 bus_dmamap_load(command->data_dmatag, command->data_dmamap, 247 command->data_buffer,IPS_ADAPTER_INFO_LEN, 248 ips_adapter_info_callback, command, BUS_DMA_NOWAIT); 249 250 if ((status->value == IPS_ERROR_STATUS) || |
245 (msleep(status, &sc->cmd_mtx, 0, "ips", 30*hz) == EWOULDBLOCK)) | 251 (sema_timedwait(&command->cmd_sema, 30*hz) == 0)) |
246 error = ETIMEDOUT; | 252 error = ETIMEDOUT; |
247 mtx_unlock(&sc->cmd_mtx); | |
248 249 if (error == 0) { 250 bus_dmamap_sync(command->data_dmatag, command->data_dmamap, 251 BUS_DMASYNC_POSTREAD); 252 memcpy(&(sc->adapter_info), command->data_buffer, 253 IPS_ADAPTER_INFO_LEN); 254 } 255 bus_dmamap_unload(command->data_dmatag, command->data_dmamap); --- 82 unchanged lines hidden (view full) --- 338 goto exit; 339 } 340 if(bus_dmamem_alloc(command->data_dmatag, &command->data_buffer, 341 BUS_DMA_NOWAIT, &command->data_dmamap)){ 342 error = ENOMEM; 343 goto exit; 344 } 345 command->callback = ips_wakeup_callback; | 253 254 if (error == 0) { 255 bus_dmamap_sync(command->data_dmatag, command->data_dmamap, 256 BUS_DMASYNC_POSTREAD); 257 memcpy(&(sc->adapter_info), command->data_buffer, 258 IPS_ADAPTER_INFO_LEN); 259 } 260 bus_dmamap_unload(command->data_dmatag, command->data_dmamap); --- 82 unchanged lines hidden (view full) --- 343 goto exit; 344 } 345 if(bus_dmamem_alloc(command->data_dmatag, &command->data_buffer, 346 BUS_DMA_NOWAIT, &command->data_dmamap)){ 347 error = ENOMEM; 348 goto exit; 349 } 350 command->callback = ips_wakeup_callback; |
346 mtx_lock(&sc->cmd_mtx); | |
347 bus_dmamap_load(command->data_dmatag, command->data_dmamap, 348 command->data_buffer,IPS_DRIVE_INFO_LEN, 349 ips_drive_info_callback, command, BUS_DMA_NOWAIT); 350 if ((status->value == IPS_ERROR_STATUS) || | 351 bus_dmamap_load(command->data_dmatag, command->data_dmamap, 352 command->data_buffer,IPS_DRIVE_INFO_LEN, 353 ips_drive_info_callback, command, BUS_DMA_NOWAIT); 354 if ((status->value == IPS_ERROR_STATUS) || |
351 (msleep(status, &sc->cmd_mtx, 0, "ips", 10*hz) == EWOULDBLOCK)) | 355 (sema_timedwait(&command->cmd_sema, 10*hz) == 0)) |
352 error = ETIMEDOUT; | 356 error = ETIMEDOUT; |
353 mtx_unlock(&sc->cmd_mtx); | |
354 355 if (error == 0) { 356 bus_dmamap_sync(command->data_dmatag, command->data_dmamap, 357 BUS_DMASYNC_POSTREAD); 358 driveinfo = command->data_buffer; 359 memcpy(sc->drives, driveinfo->drives, sizeof(ips_drive_t) * 8); 360 sc->drivecount = driveinfo->drivecount; 361 device_printf(sc->dev, "logical drives: %d\n",sc->drivecount); --- 39 unchanged lines hidden (view full) --- 401 402 PRINTF(10,"ips test: got a command, building flush command\n"); 403 command->callback = ips_wakeup_callback; 404 command_struct = (ips_generic_cmd *)command->command_buffer; 405 command_struct->command = IPS_CACHE_FLUSH_CMD; 406 command_struct->id = command->id; 407 bus_dmamap_sync(sc->command_dmatag, command->command_dmamap, 408 BUS_DMASYNC_PREWRITE); | 357 358 if (error == 0) { 359 bus_dmamap_sync(command->data_dmatag, command->data_dmamap, 360 BUS_DMASYNC_POSTREAD); 361 driveinfo = command->data_buffer; 362 memcpy(sc->drives, driveinfo->drives, sizeof(ips_drive_t) * 8); 363 sc->drivecount = driveinfo->drivecount; 364 device_printf(sc->dev, "logical drives: %d\n",sc->drivecount); --- 39 unchanged lines hidden (view full) --- 404 405 PRINTF(10,"ips test: got a command, building flush command\n"); 406 command->callback = ips_wakeup_callback; 407 command_struct = (ips_generic_cmd *)command->command_buffer; 408 command_struct->command = IPS_CACHE_FLUSH_CMD; 409 command_struct->id = command->id; 410 bus_dmamap_sync(sc->command_dmatag, command->command_dmamap, 411 BUS_DMASYNC_PREWRITE); |
409 mtx_lock(&sc->cmd_mtx); | |
410 sc->ips_issue_cmd(command); 411 if (status->value != IPS_ERROR_STATUS) | 412 sc->ips_issue_cmd(command); 413 if (status->value != IPS_ERROR_STATUS) |
412 msleep(status, &sc->cmd_mtx, 0, "flush2", 0); 413 mtx_unlock(&sc->cmd_mtx); | 414 sema_wait(&command->cmd_sema); |
414 ips_insert_free_cmd(sc, command); 415 return 0; 416} 417 418int ips_flush_cache(ips_softc_t *sc) 419{ 420 ips_cmd_status_t *status; 421 status = malloc(sizeof(ips_cmd_status_t), M_DEVBUF, M_NOWAIT|M_ZERO); --- 67 unchanged lines hidden (view full) --- 489 command_struct->command = IPS_FFDC_CMD; 490 command_struct->id = command->id; 491 command_struct->reset_count = sc->ffdc_resetcount; 492 command_struct->reset_type = 0x0; 493 ips_ffdc_settime(command_struct, sc->ffdc_resettime.tv_sec); 494 495 bus_dmamap_sync(sc->command_dmatag, command->command_dmamap, 496 BUS_DMASYNC_PREWRITE); | 415 ips_insert_free_cmd(sc, command); 416 return 0; 417} 418 419int ips_flush_cache(ips_softc_t *sc) 420{ 421 ips_cmd_status_t *status; 422 status = malloc(sizeof(ips_cmd_status_t), M_DEVBUF, M_NOWAIT|M_ZERO); --- 67 unchanged lines hidden (view full) --- 490 command_struct->command = IPS_FFDC_CMD; 491 command_struct->id = command->id; 492 command_struct->reset_count = sc->ffdc_resetcount; 493 command_struct->reset_type = 0x0; 494 ips_ffdc_settime(command_struct, sc->ffdc_resettime.tv_sec); 495 496 bus_dmamap_sync(sc->command_dmatag, command->command_dmamap, 497 BUS_DMASYNC_PREWRITE); |
497 mtx_lock(&sc->cmd_mtx); | |
498 sc->ips_issue_cmd(command); 499 if (status->value != IPS_ERROR_STATUS) | 498 sc->ips_issue_cmd(command); 499 if (status->value != IPS_ERROR_STATUS) |
500 msleep(status, &sc->cmd_mtx, 0, "ffdc", 0); 501 mtx_unlock(&sc->cmd_mtx); | 500 sema_wait(&command->cmd_sema); |
502 ips_insert_free_cmd(sc, command); 503 return 0; 504} 505 506int ips_ffdc_reset(ips_softc_t *sc) 507{ 508 ips_cmd_status_t *status; 509 status = malloc(sizeof(ips_cmd_status_t), M_DEVBUF, M_NOWAIT|M_ZERO); --- 88 unchanged lines hidden (view full) --- 598 goto exit; 599 } 600 if(bus_dmamem_alloc(command->data_dmatag, &command->data_buffer, 601 BUS_DMA_NOWAIT, &command->data_dmamap)){ 602 error = ENOMEM; 603 goto exit; 604 } 605 command->callback = ips_write_nvram; | 501 ips_insert_free_cmd(sc, command); 502 return 0; 503} 504 505int ips_ffdc_reset(ips_softc_t *sc) 506{ 507 ips_cmd_status_t *status; 508 status = malloc(sizeof(ips_cmd_status_t), M_DEVBUF, M_NOWAIT|M_ZERO); --- 88 unchanged lines hidden (view full) --- 597 goto exit; 598 } 599 if(bus_dmamem_alloc(command->data_dmatag, &command->data_buffer, 600 BUS_DMA_NOWAIT, &command->data_dmamap)){ 601 error = ENOMEM; 602 goto exit; 603 } 604 command->callback = ips_write_nvram; |
606 mtx_lock(&sc->cmd_mtx); | |
607 bus_dmamap_load(command->data_dmatag, command->data_dmamap, 608 command->data_buffer,IPS_NVRAM_PAGE_SIZE, 609 ips_read_nvram_callback, command, BUS_DMA_NOWAIT); 610 if ((status->value == IPS_ERROR_STATUS) || | 605 bus_dmamap_load(command->data_dmatag, command->data_dmamap, 606 command->data_buffer,IPS_NVRAM_PAGE_SIZE, 607 ips_read_nvram_callback, command, BUS_DMA_NOWAIT); 608 if ((status->value == IPS_ERROR_STATUS) || |
611 (msleep(status, &sc->cmd_mtx, 0, "ips", 0) == EWOULDBLOCK)) | 609 (sema_timedwait(&command->cmd_sema, 30*hz) == 0)) |
612 error = ETIMEDOUT; | 610 error = ETIMEDOUT; |
613 mtx_unlock(&sc->cmd_mtx); | |
614 615 if (error == 0) { 616 bus_dmamap_sync(command->data_dmatag, command->data_dmamap, 617 BUS_DMASYNC_POSTWRITE); 618 } 619 bus_dmamap_unload(command->data_dmatag, command->data_dmamap); 620 621exit: --- 34 unchanged lines hidden (view full) --- 656 PRINTF(10,"ips test: got a command, building flush command\n"); 657 command->callback = ips_wakeup_callback; 658 command_struct = (ips_generic_cmd *)command->command_buffer; 659 command_struct->command = IPS_CONFIG_SYNC_CMD; 660 command_struct->id = command->id; 661 command_struct->reserve2 = IPS_POCL; 662 bus_dmamap_sync(sc->command_dmatag, command->command_dmamap, 663 BUS_DMASYNC_PREWRITE); | 611 612 if (error == 0) { 613 bus_dmamap_sync(command->data_dmatag, command->data_dmamap, 614 BUS_DMASYNC_POSTWRITE); 615 } 616 bus_dmamap_unload(command->data_dmatag, command->data_dmamap); 617 618exit: --- 34 unchanged lines hidden (view full) --- 653 PRINTF(10,"ips test: got a command, building flush command\n"); 654 command->callback = ips_wakeup_callback; 655 command_struct = (ips_generic_cmd *)command->command_buffer; 656 command_struct->command = IPS_CONFIG_SYNC_CMD; 657 command_struct->id = command->id; 658 command_struct->reserve2 = IPS_POCL; 659 bus_dmamap_sync(sc->command_dmatag, command->command_dmamap, 660 BUS_DMASYNC_PREWRITE); |
664 mtx_lock(&sc->cmd_mtx); | |
665 sc->ips_issue_cmd(command); 666 if (status->value != IPS_ERROR_STATUS) | 661 sc->ips_issue_cmd(command); 662 if (status->value != IPS_ERROR_STATUS) |
667 msleep(status, &sc->cmd_mtx, 0, "ipssyn", 0); 668 mtx_unlock(&sc->cmd_mtx); | 663 sema_wait(&command->cmd_sema); |
669 ips_insert_free_cmd(sc, command); 670 return 0; 671} 672 673static int ips_send_error_table_cmd(ips_command_t *command) 674{ 675 ips_softc_t *sc = command->sc; 676 ips_cmd_status_t *status = command->arg; 677 ips_generic_cmd *command_struct; 678 679 PRINTF(10,"ips test: got a command, building errortable command\n"); 680 command->callback = ips_wakeup_callback; 681 command_struct = (ips_generic_cmd *)command->command_buffer; 682 command_struct->command = IPS_ERROR_TABLE_CMD; 683 command_struct->id = command->id; 684 command_struct->reserve2 = IPS_CSL; 685 bus_dmamap_sync(sc->command_dmatag, command->command_dmamap, 686 BUS_DMASYNC_PREWRITE); | 664 ips_insert_free_cmd(sc, command); 665 return 0; 666} 667 668static int ips_send_error_table_cmd(ips_command_t *command) 669{ 670 ips_softc_t *sc = command->sc; 671 ips_cmd_status_t *status = command->arg; 672 ips_generic_cmd *command_struct; 673 674 PRINTF(10,"ips test: got a command, building errortable command\n"); 675 command->callback = ips_wakeup_callback; 676 command_struct = (ips_generic_cmd *)command->command_buffer; 677 command_struct->command = IPS_ERROR_TABLE_CMD; 678 command_struct->id = command->id; 679 command_struct->reserve2 = IPS_CSL; 680 bus_dmamap_sync(sc->command_dmatag, command->command_dmamap, 681 BUS_DMASYNC_PREWRITE); |
687 mtx_lock(&sc->cmd_mtx); | |
688 sc->ips_issue_cmd(command); 689 if (status->value != IPS_ERROR_STATUS) | 682 sc->ips_issue_cmd(command); 683 if (status->value != IPS_ERROR_STATUS) |
690 msleep(status, &sc->cmd_mtx, 0, "ipsetc", 0); 691 mtx_unlock(&sc->cmd_mtx); | 684 sema_wait(&command->cmd_sema); |
692 ips_insert_free_cmd(sc, command); 693 return 0; 694} 695 696 697int ips_clear_adapter(ips_softc_t *sc) 698{ 699 ips_cmd_status_t *status; --- 32 unchanged lines hidden --- | 685 ips_insert_free_cmd(sc, command); 686 return 0; 687} 688 689 690int ips_clear_adapter(ips_softc_t *sc) 691{ 692 ips_cmd_status_t *status; --- 32 unchanged lines hidden --- |