int ips_clear_adapter(ips_softc_t *sc) { ips_command_t *command; device_printf(sc->dev, "syncing config\n"); if (ips_get_free_cmd(sc, &command, IPS_STATIC_FLAG)){ device_printf(sc->dev, "ERROR: unable to get a command! can't sync cache!\n"); return 1; } ips_send_config_sync_cmd(command); if(COMMAND_ERROR(command)){ device_printf(sc->dev, "ERROR: cache sync command failed!\n"); return 1; } device_printf(sc->dev, "clearing error table\n"); if(ips_get_free_cmd(sc, &command, IPS_STATIC_FLAG)){ device_printf(sc->dev, "ERROR: unable to get a command! can't sync cache!\n"); return 1; } ips_send_error_table_cmd(command); if(COMMAND_ERROR(command)){ device_printf(sc->dev, "ERROR: etable command failed!\n"); return 1; } return 0; }
int ips_clear_adapter(ips_softc_t *sc) { ips_cmd_status_t *status; status = malloc(sizeof(ips_cmd_status_t), M_IPSBUF, M_NOWAIT|M_ZERO); if(!status) return ENOMEM; device_printf(sc->dev, "syncing config\n"); if(ips_get_free_cmd(sc, ips_send_config_sync_cmd, status, IPS_NOWAIT_FLAG)){ free(status, M_IPSBUF); device_printf(sc->dev, "ERROR: unable to get a command! can't sync cache!\n"); return 1; } if(COMMAND_ERROR(status)){ free(status, M_IPSBUF); device_printf(sc->dev, "ERROR: cache sync command failed!\n"); return 1; } device_printf(sc->dev, "clearing error table\n"); if(ips_get_free_cmd(sc, ips_send_error_table_cmd, status, IPS_NOWAIT_FLAG)){ free(status, M_IPSBUF); device_printf(sc->dev, "ERROR: unable to get a command! can't sync cache!\n"); return 1; } if(COMMAND_ERROR(status)){ device_printf(sc->dev, "ERROR: etable command failed!\n"); free(status, M_IPSBUF); return 1; } free(status, M_IPSBUF); return 0; }
static int ips_ioctl_cmd(ips_softc_t *sc, ips_ioctl_t *ioctl_cmd, ips_user_request *user_request) { ips_command_t *command; int error = EINVAL; if (bus_dma_tag_create( /* parent */ sc->adapter_dmatag, /* alignment */ 1, /* boundary */ 0, /* lowaddr */ BUS_SPACE_MAXADDR_32BIT, /* highaddr */ BUS_SPACE_MAXADDR, /* filter */ NULL, /* filterarg */ NULL, /* maxsize */ ioctl_cmd->datasize, /* numsegs */ 1, /* maxsegsize*/ ioctl_cmd->datasize, /* flags */ 0, /* lockfunc */ NULL, /* lockarg */ NULL, &ioctl_cmd->dmatag) != 0) { return ENOMEM; } if(bus_dmamem_alloc(ioctl_cmd->dmatag, &ioctl_cmd->data_buffer, 0, &ioctl_cmd->dmamap)){ error = ENOMEM; goto exit; } if(copyin(user_request->data_buffer,ioctl_cmd->data_buffer, ioctl_cmd->datasize)) goto exit; ioctl_cmd->status.value = 0xffffffff; mtx_lock(&sc->queue_mtx); if((error = ips_get_free_cmd(sc, &command, 0)) > 0){ error = ENOMEM; mtx_unlock(&sc->queue_mtx); goto exit; } command->arg = ioctl_cmd; ips_ioctl_start(command); while( ioctl_cmd->status.value == 0xffffffff) msleep(ioctl_cmd, &sc->queue_mtx, 0, "ips", hz/10); if(COMMAND_ERROR(ioctl_cmd)) error = EIO; else error = 0; mtx_unlock(&sc->queue_mtx); if(copyout(ioctl_cmd->data_buffer, user_request->data_buffer, ioctl_cmd->datasize)) error = EINVAL; mtx_lock(&sc->queue_mtx); ips_insert_free_cmd(sc, command); mtx_unlock(&sc->queue_mtx); exit: bus_dmamem_free(ioctl_cmd->dmatag, ioctl_cmd->data_buffer, ioctl_cmd->dmamap); bus_dma_tag_destroy(ioctl_cmd->dmatag); return error; }
static int ipsd_dump(struct dev_dump_args *ap) { cdev_t dev = ap->a_head.a_dev; ips_softc_t *sc; ips_command_t *command; ips_io_cmd *command_struct; ipsdisk_softc_t *dsc; off_t off; uint8_t *va; size_t len; int error = 0; dsc = dev->si_drv1; if (dsc == NULL) return (EINVAL); sc = dsc->sc; if (ips_get_free_cmd(sc, &command, 0) != 0) { kprintf("ipsd: failed to get cmd for dump\n"); return (ENOMEM); } command->data_dmatag = sc->sg_dmatag; command->callback = ipsd_dump_block_complete; command_struct = (ips_io_cmd *)command->command_buffer; command_struct->id = command->id; command_struct->drivenum = sc->drives[dsc->disk_number].drivenum; off = ap->a_offset; va = ap->a_virtual; size_t length = ap->a_length; while (length > 0) { len = length > IPS_MAX_IO_SIZE ? IPS_MAX_IO_SIZE : length; command_struct->lba = off / IPS_BLKSIZE; if (bus_dmamap_load(command->data_dmatag, command->data_dmamap, va, len, ipsd_dump_map_sg, command, 0) != 0) { error = EIO; break; } if (COMMAND_ERROR(&command->status)) { error = EIO; break; } length -= len; off += len; va += len; } ips_insert_free_cmd(command->sc, command); return(error); }
int ips_ffdc_reset(ips_softc_t *sc) { ips_command_t *command; if (ips_get_free_cmd(sc, &command, IPS_STATIC_FLAG)){ device_printf(sc->dev, "ERROR: unable to get a command! can't send ffdc reset!\n"); } ips_send_ffdc_reset_cmd(command); if(COMMAND_ERROR(command)){ device_printf(sc->dev, "ERROR: ffdc reset command failed!\n"); } return 0; }
int ips_flush_cache(ips_softc_t *sc) { ips_command_t *command; device_printf(sc->dev, "flushing cache\n"); if (ips_get_free_cmd(sc, &command, IPS_STATIC_FLAG)){ device_printf(sc->dev, "ERROR: unable to get a command! can't flush cache!\n"); } ips_send_flush_cache_cmd(command); if(COMMAND_ERROR(command)){ device_printf(sc->dev, "ERROR: cache flush command failed!\n"); } return 0; }
int ips_get_drive_info(ips_softc_t *sc) { int error = 0; ips_command_t *command; if (ips_get_free_cmd(sc, &command, IPS_STATIC_FLAG) > 0){ device_printf(sc->dev, "unable to get drive configuration\n"); return ENXIO; } ips_send_drive_info_cmd(command); if(COMMAND_ERROR(command)){ error = ENXIO; } return error; }
void ips_start_io_request(ips_softc_t *sc) { struct buf *iobuf; iobuf = bufq_first(&sc->queue); if(!iobuf) { return; } if(ips_get_free_cmd(sc, ips_send_io_request, iobuf, IPS_NOWAIT_FLAG)){ return; } bufq_remove(&sc->queue, iobuf); return; }
int ips_update_nvram(ips_softc_t *sc) { ips_command_t *command; if (ips_get_free_cmd(sc, &command, IPS_STATIC_FLAG)){ device_printf(sc->dev, "ERROR: unable to get a command! can't update nvram\n"); return 1; } ips_read_nvram(command); if(COMMAND_ERROR(command)){ device_printf(sc->dev, "ERROR: nvram update command failed!\n"); } return 0; }
void ips_start_io_request(ips_softc_t *sc) { struct bio *iobuf; ips_command_t *command; iobuf = bioq_first(&sc->queue); if(!iobuf) return; if (ips_get_free_cmd(sc, &command, 0)) return; bioq_remove(&sc->queue, iobuf); ips_send_io_request(command, iobuf); return; }
int ips_ffdc_reset(ips_softc_t *sc) { ips_cmd_status_t *status; status = malloc(sizeof(ips_cmd_status_t), M_IPSBUF, M_NOWAIT|M_ZERO); if(!status) return ENOMEM; if(ips_get_free_cmd(sc, ips_send_ffdc_reset_cmd, status, IPS_NOWAIT_FLAG)){ free(status, M_IPSBUF); device_printf(sc->dev, "ERROR: unable to get a command! can't send ffdc reset!\n"); } if(COMMAND_ERROR(status)){ device_printf(sc->dev, "ERROR: ffdc reset command failed!\n"); } free(status, M_IPSBUF); return 0; }
int ips_update_nvram(ips_softc_t *sc) { ips_cmd_status_t *status; status = malloc(sizeof(ips_cmd_status_t), M_IPSBUF, M_NOWAIT|M_ZERO); if(!status) return ENOMEM; if(ips_get_free_cmd(sc, ips_read_nvram, status, IPS_NOWAIT_FLAG)){ free(status, M_IPSBUF); device_printf(sc->dev, "ERROR: unable to get a command! can't update nvram\n"); return 1; } if(COMMAND_ERROR(status)){ device_printf(sc->dev, "ERROR: nvram update command failed!\n"); } free(status, M_IPSBUF); return 0; }
int ips_get_drive_info(ips_softc_t *sc) { int error = 0; ips_cmd_status_t *status; status = malloc(sizeof(ips_cmd_status_t), M_IPSBUF, M_NOWAIT|M_ZERO); if(!status) return ENOMEM; if(ips_get_free_cmd(sc, ips_send_drive_info_cmd, status, IPS_NOWAIT_FLAG) > 0){ free(status, M_IPSBUF); device_printf(sc->dev, "unable to get drive configuration\n"); return ENXIO; } if(COMMAND_ERROR(status)){ error = ENXIO; } free(status, M_IPSBUF); return error; }