Exemple #1
0
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;
}
Exemple #3
0
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;
}