static int ata_getparam(struct ata_device *atadev, u_int8_t command) { struct ata_params *ata_parm; int retry = 0; if (!(ata_parm = malloc(sizeof(struct ata_params), M_ATA, M_NOWAIT))) { ata_prtdev(atadev, "malloc for identify data failed\n"); return -1; } /* apparently some devices needs this repeated */ do { if (ata_command(atadev, command, 0, 0, 0, ATA_IMMEDIATE)) { ata_prtdev(atadev, "%s identify failed\n", command == ATA_C_ATAPI_IDENTIFY ? "ATAPI" : "ATA"); free(ata_parm, M_ATA); return -1; } if (retry++ > 4) { ata_prtdev(atadev, "%s identify retries exceeded\n", command == ATA_C_ATAPI_IDENTIFY ? "ATAPI" : "ATA"); free(ata_parm, M_ATA); return -1; } } while (ata_wait(atadev, ((command == ATA_C_ATAPI_IDENTIFY) ? ATA_S_DRQ : (ATA_S_READY|ATA_S_DSC|ATA_S_DRQ)))); ATA_INSW(atadev->channel->r_io, ATA_DATA, (int16_t *)ata_parm, sizeof(struct ata_params)/sizeof(int16_t)); if (command == ATA_C_ATA_IDENTIFY || !((ata_parm->model[0] == 'N' && ata_parm->model[1] == 'E') || (ata_parm->model[0] == 'F' && ata_parm->model[1] == 'X') || (ata_parm->model[0] == 'P' && ata_parm->model[1] == 'i'))) bswap(ata_parm->model, sizeof(ata_parm->model)); btrim(ata_parm->model, sizeof(ata_parm->model)); bpack(ata_parm->model, ata_parm->model, sizeof(ata_parm->model)); bswap(ata_parm->revision, sizeof(ata_parm->revision)); btrim(ata_parm->revision, sizeof(ata_parm->revision)); bpack(ata_parm->revision, ata_parm->revision, sizeof(ata_parm->revision)); bswap(ata_parm->serial, sizeof(ata_parm->serial)); btrim(ata_parm->serial, sizeof(ata_parm->serial)); bpack(ata_parm->serial, ata_parm->serial, sizeof(ata_parm->serial)); atadev->param = ata_parm; return 0; }
static int ata_getparam(struct ata_device *atadev, int init) { struct ata_channel *ch = device_get_softc(device_get_parent(atadev->dev)); struct ata_request *request; u_int8_t command = 0; int error = ENOMEM, retries = 2; if (ch->devices & (atadev->unit == ATA_MASTER ? ATA_ATA_MASTER : ATA_ATA_SLAVE)) command = ATA_ATA_IDENTIFY; if (ch->devices & (atadev->unit == ATA_MASTER ? ATA_ATAPI_MASTER : ATA_ATAPI_SLAVE)) command = ATA_ATAPI_IDENTIFY; if (!command) return ENXIO; while (retries-- > 0 && error) { if (!(request = ata_alloc_request())) break; request->dev = atadev->dev; request->timeout = 1; request->retries = 0; request->u.ata.command = command; request->flags = (ATA_R_READ|ATA_R_AT_HEAD|ATA_R_DIRECT|ATA_R_QUIET); request->data = (void *)&atadev->param; request->bytecount = sizeof(struct ata_params); request->donecount = 0; request->transfersize = DEV_BSIZE; ata_queue_request(request); error = request->result; ata_free_request(request); } if (!error && (isprint(atadev->param.model[0]) || isprint(atadev->param.model[1]))) { struct ata_params *atacap = &atadev->param; char buffer[64]; int16_t *ptr; for (ptr = (int16_t *)atacap; ptr < (int16_t *)atacap + sizeof(struct ata_params)/2; ptr++) { *ptr = le16toh(*ptr); } if (!(!strncmp(atacap->model, "FX", 2) || !strncmp(atacap->model, "NEC", 3) || !strncmp(atacap->model, "Pioneer", 7) || !strncmp(atacap->model, "SHARP", 5))) { bswap(atacap->model, sizeof(atacap->model)); bswap(atacap->revision, sizeof(atacap->revision)); bswap(atacap->serial, sizeof(atacap->serial)); } btrim(atacap->model, sizeof(atacap->model)); bpack(atacap->model, atacap->model, sizeof(atacap->model)); btrim(atacap->revision, sizeof(atacap->revision)); bpack(atacap->revision, atacap->revision, sizeof(atacap->revision)); btrim(atacap->serial, sizeof(atacap->serial)); bpack(atacap->serial, atacap->serial, sizeof(atacap->serial)); if (bootverbose) printf("ata%d-%s: pio=%s wdma=%s udma=%s cable=%s wire\n", device_get_unit(ch->dev), atadev->unit == ATA_MASTER ? "master" : "slave", ata_mode2str(ata_pmode(atacap)), ata_mode2str(ata_wmode(atacap)), ata_mode2str(ata_umode(atacap)), (atacap->hwres & ATA_CABLE_ID) ? "80":"40"); if (init) { sprintf(buffer, "%.40s/%.8s", atacap->model, atacap->revision); device_set_desc_copy(atadev->dev, buffer); if ((atadev->param.config & ATA_PROTO_ATAPI) && (atadev->param.config != ATA_CFA_MAGIC1) && (atadev->param.config != ATA_CFA_MAGIC2)) { if (atapi_dma && ch->dma && (atadev->param.config & ATA_DRQ_MASK) != ATA_DRQ_INTR && ata_umode(&atadev->param) >= ATA_UDMA2) atadev->mode = ATA_DMA_MAX; } else { if (ata_dma && ch->dma && (ata_umode(&atadev->param) > 0 || ata_wmode(&atadev->param) > 0)) atadev->mode = ATA_DMA_MAX; } } } else { if (!error) error = ENXIO; } return error; }
static int pst_attach(device_t dev) { struct pst_softc *psc = device_get_softc(dev); struct i2o_get_param_reply *reply; struct i2o_device_identity *ident; int lun = device_get_unit(dev); int8_t name [32]; if (!(reply = iop_get_util_params(psc->iop, psc->lct->local_tid, I2O_PARAMS_OPERATION_FIELD_GET, I2O_BSA_DEVICE_INFO_GROUP_NO))) return ENODEV; if (!(psc->info = (struct i2o_bsa_device *) malloc(sizeof(struct i2o_bsa_device), M_PSTRAID, M_NOWAIT))) { contigfree(reply, PAGE_SIZE, M_PSTIOP); return ENOMEM; } bcopy(reply->result, psc->info, sizeof(struct i2o_bsa_device)); contigfree(reply, PAGE_SIZE, M_PSTIOP); if (!(reply = iop_get_util_params(psc->iop, psc->lct->local_tid, I2O_PARAMS_OPERATION_FIELD_GET, I2O_UTIL_DEVICE_IDENTITY_GROUP_NO))) return ENODEV; ident = (struct i2o_device_identity *)reply->result; #ifdef PSTDEBUG printf("pst: vendor=<%.16s> product=<%.16s>\n", ident->vendor, ident->product); printf("pst: description=<%.16s> revision=<%.8s>\n", ident->description, ident->revision); printf("pst: capacity=%lld blocksize=%d\n", psc->info->capacity, psc->info->block_size); #endif bpack(ident->vendor, ident->vendor, 16); bpack(ident->product, ident->product, 16); sprintf(name, "%s %s", ident->vendor, ident->product); contigfree(reply, PAGE_SIZE, M_PSTIOP); bioq_init(&psc->queue); psc->disk = disk_alloc(); psc->disk->d_name = "pst"; psc->disk->d_strategy = pststrategy; psc->disk->d_maxsize = 64 * 1024; /*I2O_SGL_MAX_SEGS * PAGE_SIZE;*/ psc->disk->d_drv1 = psc; psc->disk->d_unit = lun; psc->disk->d_sectorsize = psc->info->block_size; psc->disk->d_mediasize = psc->info->capacity; psc->disk->d_fwsectors = 63; psc->disk->d_fwheads = 255; disk_create(psc->disk, DISK_VERSION); printf("pst%d: %lluMB <%.40s> [%lld/%d/%d] on %.16s\n", lun, (unsigned long long)psc->info->capacity / (1024 * 1024), name, psc->info->capacity/(512*255*63), 255, 63, device_get_nameunit(psc->iop->dev)); EVENTHANDLER_REGISTER(shutdown_post_sync, pst_shutdown, dev, SHUTDOWN_PRI_FIRST); return 0; }
/* -------------------------------------------------------------------------- */ int server_process(server_t* server, const unsigned char* data, size_t size, unsigned char** response, size_t* response_size) { if(server == NULL || server->db == NULL || data == NULL || strlen((char*)data) == 0 || size == 0 || response == NULL || response_size == NULL) return ERROR_INVALID_ARGUMENTS; /* unpack package */ unsigned char packettype = '\0'; unsigned char *domain = NULL; unsigned char* key = NULL; data_store_t ds; if(simple_memory_buffer_new(&ds, data, size) != ERROR_OK ) return ERROR_UNKNOWN; int64_t ret = ERROR_OK; if((ret = data_store_read_byte(&ds, &packettype)) != ERROR_OK || (ret = bunpack(&ds, "ss", &domain, &key)) != ERROR_OK){ if(domain != NULL) freeMemory(domain); if(key != NULL) freeMemory(key); } /* handle incomming data */ int64_t integer = 0; double dob = 0.0; char* string = NULL; unsigned char* blob = NULL; size_t bsize = 0; database_value_type_t type; size_t count = 0; int64_t count_enum = 0; size_t esize = 0; char* keys = NULL; data_store_t response_ds; if(simple_memory_buffer_new(&response_ds, NULL, 0) != ERROR_OK){ if(domain != NULL) freeMemory(domain); if(key != NULL) freeMemory(key); simple_memory_buffer_free(&ds); return ERROR_UNKNOWN; } if(ret == ERROR_OK){ switch(packettype){ /* Int handling */ case PACKET_GET_INT: ret = database_get_int64(server->db, (char*)domain, (char*)key, &integer); if(ret != ERROR_OK) break; if(data_store_write_byte(&response_ds, PACKET_INT) != ERROR_OK || bpack(&response_ds, "l", integer) != ERROR_OK) ret = ERROR_UNKNOWN; break; case PACKET_SET_INT: if(bunpack(&ds, "l", &integer) != ERROR_OK){ ret = ERROR_UNKNOWN; break; } ret = database_set_int64(server->db, (char*)domain, (char*)key, integer); if(ret != ERROR_OK) break; if(data_store_write_byte(&response_ds, PACKET_OK) != ERROR_OK) ret = ERROR_UNKNOWN; break; /* Double handling */ case PACKET_GET_DOUBLE: ret = database_get_double(server->db, (char*)domain, (char*)key, &dob); if(ret != ERROR_OK) break; if(data_store_write_byte(&response_ds, PACKET_DOUBLE) != ERROR_OK || bpack(&response_ds, "d", dob) != ERROR_OK) ret = ERROR_UNKNOWN; break; case PACKET_SET_DOUBLE: if(bunpack(&ds, "d", &dob) != ERROR_OK){ ret = ERROR_UNKNOWN; break; } ret = database_set_double(server->db, (char*)domain, (char*)key, dob); if(ret != ERROR_OK) break; if(data_store_write_byte(&response_ds, PACKET_OK) != ERROR_OK) ret = ERROR_UNKNOWN; break; /* String handling */ case PACKET_GET_STRING: ret = database_get_string(server->db, (char*)domain, (char*)key, &string); if(ret != ERROR_OK){ if(string) freeMemory(string); break; } if(data_store_write_byte(&response_ds, PACKET_STRING) != ERROR_OK || bpack(&response_ds, "s", string) != ERROR_OK) ret = ERROR_UNKNOWN; freeMemory(string); break; case PACKET_SET_STRING: if(bunpack(&ds, "s", &string) != ERROR_OK){ ret = ERROR_UNKNOWN; break; } ret = database_set_string(server->db, (char*)domain, (char*)key, string); if(ret != ERROR_OK) break; freeMemory(string); if(data_store_write_byte(&response_ds, PACKET_OK) != ERROR_OK) ret = ERROR_UNKNOWN; break; /* Blob handling */ case PACKET_GET_BLOB: ret = database_get_blob(server->db, (char*)domain, (char*)key, &blob, &bsize); if(ret != ERROR_OK){ if(blob != NULL) freeMemory(blob); break; } if(data_store_write_byte(&response_ds, PACKET_BLOB) != ERROR_OK || bpack(&response_ds, "b", bsize, blob) != ERROR_OK) ret = ERROR_UNKNOWN; freeMemory(blob); break; case PACKET_SET_BLOB: if(bunpack(&ds, "b", &bsize, &blob) != ERROR_OK){ ret = ERROR_UNKNOWN; break; } ret = database_set_blob(server->db, (char*)domain, (char*)key, blob, bsize); if(ret != ERROR_OK) break; freeMemory(blob); if(data_store_write_byte(&response_ds, PACKET_OK) != ERROR_OK) ret = ERROR_UNKNOWN; break; /* Others handling */ case PACKET_GET_ENUM: ret = database_enum_keys(server->db, (char*)domain, (char*)key, &count, &esize, &keys); if(ret != ERROR_OK){ if(keys != NULL) freeMemory(keys); break; } count_enum = count; if(data_store_write_byte(&response_ds, PACKET_ENUM) != ERROR_OK) ret = ERROR_UNKNOWN; if(keys == NULL){ if(bpack(&response_ds, "l", count_enum) != ERROR_OK) ret = ERROR_UNKNOWN; }else{ if(bpack(&response_ds, "lb", count_enum, esize, keys) != ERROR_OK) ret = ERROR_UNKNOWN; freeMemory(keys); } break; case PACKET_GET_VALUE_TYPE: ret = database_get_type(server->db, (char*)domain, (char*)key, &type); if(ret != ERROR_OK) break; if(data_store_write_byte(&response_ds, PACKET_TYPE) != ERROR_OK || bpack(&response_ds, "l", (int64_t)type) != ERROR_OK) ret = ERROR_UNKNOWN; break; case PACKET_SHUTDOWN: if(server_shutdown(server) != ERROR_OK){ ret = ERROR_UNKNOWN; break; } ret = ERROR_SERVER_SHUTDOWN; break; default: ret = ERROR_UNKNOWN; break; } freeMemory(domain); freeMemory(key); } /* free input datastore */ if(simple_memory_buffer_free(&ds) != ERROR_OK) ret = ERROR_UNKNOWN; /* send packet */ if(ret == ERROR_OK){ if(sendPacket(&response_ds, response_size, response) != ERROR_OK) ret = ERROR_UNKNOWN; } if(simple_memory_buffer_free(&response_ds) != ERROR_OK) ret = ERROR_UNKNOWN; /* error packet */ if(ret != ERROR_OK && ret != ERROR_SERVER_SHUTDOWN){ data_store_t error_ds; if(simple_memory_buffer_new(&error_ds, NULL, 0) != ERROR_OK || data_store_write_byte(&error_ds, PACKET_ERROR) != ERROR_OK || bpack(&error_ds, "l", ret) != ERROR_OK){ simple_memory_buffer_free(&error_ds); ret = ERROR_UNKNOWN; }else{ if((ret = sendPacket(&error_ds, response_size, response)) != ERROR_OK) ret = ERROR_UNKNOWN; simple_memory_buffer_free(&error_ds); } } return ret; }
/* -------------------------------------------------------------------------- */ int registry_key_get_value_type(registry_t* handle, const char* key, int* type) { if(handle == NULL || handle->domain == NULL || strlen(handle->domain) == 0 || handle->channel == NULL || key == NULL || strlen(key) == 0 || type == NULL) return ERROR_INVALID_ARGUMENTS; /* pack package */ data_store_t ds; if(simple_memory_buffer_new(&ds, NULL, 0) != ERROR_OK || data_store_write_byte(&ds, PACKET_GET_VALUE_TYPE) != ERROR_OK || bpack(&ds, "ss", handle->domain, key) != ERROR_OK){ simple_memory_buffer_free(&ds); return ERROR_UNKNOWN; } /* send package */ unsigned char *data = NULL; size_t size = 0; if(simple_memory_buffer_get_data(&ds, &data) != ERROR_OK || simple_memory_buffer_get_size(&ds, &size) != ERROR_OK){ simple_memory_buffer_free(&ds); return ERROR_UNKNOWN; } int retval = ERROR_OK; while((retval = channel_client_write_bytes(handle->channel, data, size)) == ERROR_CHANNEL_BUSY); if(retval != ERROR_OK){ simple_memory_buffer_free(&ds); return ERROR_UNKNOWN; } if(simple_memory_buffer_free(&ds) != ERROR_OK) return ERROR_UNKNOWN; /* receive response */ unsigned char *res_data = NULL; size_t res_size = 0; while((retval = channel_client_read_bytes(handle->channel, &res_data, &res_size)) == ERROR_CHANNEL_BUSY); if(retval != ERROR_OK) return ERROR_UNKNOWN; /* unpack package */ unsigned char packettype = '\0'; data_store_t res_ds; if(simple_memory_buffer_new(&res_ds, res_data, res_size) != ERROR_OK || data_store_read_byte(&res_ds, &packettype) != ERROR_OK){ simple_memory_buffer_free(&res_ds); return ERROR_UNKNOWN; } freeMemory(res_data); /* handling data */ int ret = ERROR_OK; int64_t errorcode = ERROR_OK; int64_t valuetype = 0; switch(packettype){ case PACKET_ERROR: if(bunpack(&res_ds, "l", &errorcode) != ERROR_OK) ret = ERROR_UNKNOWN; if(errorcode == ERROR_DATABASE_INVALID) ret = ERROR_REGISTRY_INVALID_STATE; if(errorcode == ERROR_DATABASE_NO_SUCH_KEY) ret = ERROR_REGISTRY_NO_SUCH_KEY; else ret = ERROR_UNKNOWN; break; case PACKET_TYPE: if(bunpack(&res_ds, "l", &valuetype) != ERROR_OK) ret = ERROR_UNKNOWN; *type = valuetype; break; default: ret = ERROR_UNKNOWN; } if(simple_memory_buffer_free(&res_ds) != ERROR_OK) ret = ERROR_UNKNOWN; return ret; }
/* -------------------------------------------------------------------------- */ int registry_enum_keys(registry_t* handle, const char* pattern, size_t* count, size_t* size, char** keys) { if(handle == NULL || handle->domain == NULL || strlen(handle->domain) == 0 || handle->channel == NULL || pattern == NULL || count == NULL || size == NULL || keys == NULL) return ERROR_INVALID_ARGUMENTS; /* pack package */ data_store_t ds; if(simple_memory_buffer_new(&ds, NULL, 0) != ERROR_OK || data_store_write_byte(&ds, PACKET_GET_ENUM) != ERROR_OK || bpack(&ds, "ss", handle->domain, pattern) != ERROR_OK){ simple_memory_buffer_free(&ds); return ERROR_UNKNOWN; } /* send package */ unsigned char *data = NULL; size_t enum_size = 0; if(simple_memory_buffer_get_data(&ds, &data) != ERROR_OK || simple_memory_buffer_get_size(&ds, &enum_size) != ERROR_OK){ simple_memory_buffer_free(&ds); return ERROR_UNKNOWN; } int retval = ERROR_OK; while((retval = channel_client_write_bytes(handle->channel, data, enum_size)) == ERROR_CHANNEL_BUSY); if(retval != ERROR_OK){ simple_memory_buffer_free(&ds); return ERROR_UNKNOWN; } if(simple_memory_buffer_free(&ds) != ERROR_OK) return ERROR_UNKNOWN; /* receive response */ unsigned char *res_data = NULL; size_t res_size = 0; while((retval = channel_client_read_bytes(handle->channel, &res_data, &res_size)) == ERROR_CHANNEL_BUSY); if(retval != ERROR_OK) return ERROR_UNKNOWN; /* unpack package */ unsigned char packettype = '\0'; data_store_t res_ds; if(simple_memory_buffer_new(&res_ds, res_data, res_size) != ERROR_OK || data_store_read_byte(&res_ds, &packettype) != ERROR_OK){ simple_memory_buffer_free(&res_ds); return ERROR_UNKNOWN; } freeMemory(res_data); /* handling data */ int ret = ERROR_OK; int64_t errorcode = ERROR_OK; int64_t count_enum = 0; switch(packettype){ case PACKET_ERROR: if(bunpack(&res_ds, "l", &errorcode) != ERROR_OK) ret = ERROR_UNKNOWN; if(errorcode == ERROR_DATABASE_INVALID) ret = ERROR_REGISTRY_INVALID_STATE; if(errorcode == ERROR_DATABASE_NO_SUCH_KEY) ret = ERROR_REGISTRY_NO_SUCH_KEY; else ret = ERROR_UNKNOWN; break; case PACKET_ENUM: if(bunpack(&res_ds, "l", &count_enum) != ERROR_OK) ret = ERROR_UNKNOWN; *count = count_enum; if(count_enum > 0){ if(bunpack(&res_ds, "b", size, keys) != ERROR_OK) ret = ERROR_UNKNOWN; }else{ *size = 0; *keys = NULL; } break; default: ret = ERROR_UNKNOWN; } if(simple_memory_buffer_free(&res_ds) != ERROR_OK) ret = ERROR_UNKNOWN; return ret; }