Пример #1
0
int ioctl_ata(int min, int cmd, long arg)
{
	struct ata_device *device = get_ata_device(min);
	struct ata_controller *cont = device->controller;
	if(!(device->flags & F_EXIST))
		return -ENOENT;
	if(cmd == -1)
	{
		ata_disk_sync(primary);
		ata_disk_sync(secondary);
		return 0;
	}
	if(cmd == 0)
	{
		if(arg)
			*(unsigned *)arg = device->length;
		return 512;
	}
	if(cmd == 1)
	{
		kprintf("[ata]: reload partition tables - not implemented\n");
		return 0;
	}
	if(cmd == -7)
	{
		if(arg)
			*(unsigned int *)arg = 512;
		return device->length;
	}
	return -EINVAL;
}
Пример #2
0
smart_device * smart_interface::get_smart_device(const char * name, const char * type)
{
  clear_err();

  // Call platform specific autodetection if no device type specified
  smart_device * dev;
  if (!type || !*type) {
    dev = autodetect_smart_device(name);
    if (!dev && !get_errno())
      set_err(EINVAL, "Unable to detect device type");
    return dev;
  }

  // First check for platform specific device types
  dev = get_custom_smart_device(name, type);
  if (dev || get_errno())
    return dev;

  if (!strcmp(type, "ata"))
    dev = get_ata_device(name, type);
  else if (!strcmp(type, "scsi"))
    dev = get_scsi_device(name, type);

  else if (  ((!strncmp(type, "sat", 3) && (!type[3] || strchr(",+", type[3])))
           || (!strncmp(type, "usb", 3)))) {
    // Split "sat...+base..." -> ("sat...", "base...")
    unsigned satlen = strcspn(type, "+");
    std::string sattype(type, satlen);
    const char * basetype = (type[satlen] ? type+satlen+1 : "");
    // Recurse to allocate base device, default is standard SCSI
    if (!*basetype)
      basetype = "scsi";
    smart_device_auto_ptr basedev( get_smart_device(name, basetype) );
    if (!basedev) {
      set_err(EINVAL, "Type '%s+...': %s", sattype.c_str(), get_errmsg());
      return 0;
    }
    // Result must be SCSI
    if (!basedev->is_scsi()) {
      set_err(EINVAL, "Type '%s+...': Device type '%s' is not SCSI", sattype.c_str(), basetype);
      return 0;
    }
    // Attach SAT tunnel
    ata_device * satdev = get_sat_device(sattype.c_str(), basedev->to_scsi());
    if (!satdev)
      return 0;
    basedev.release();
    return satdev;
  }

  else {
    set_err(EINVAL, "Unknown device type '%s'", type);
    return 0;
  }
  if (!dev && !get_errno())
    set_err(EINVAL, "Not a device of type '%s'", type);
  return dev;
}
Пример #3
0
bool legacy_smart_interface::scan_smart_devices(smart_device_list & devlist,
  const char * type, const char * pattern /*= 0*/)
{
  if (pattern) {
    set_err(EINVAL, "DEVICESCAN with pattern not implemented yet");
    return false;
  }

  // Make namelists
  char * * atanames = 0; int numata = 0;
  if (!type || !strcmp(type, "ata")) {
    numata = ::make_device_names(&atanames, "ATA");
    if (numata < 0) {
      set_err(ENOMEM);
      return false;
    }
  }

  char * * scsinames = 0; int numscsi = 0;
  if (!type || !strcmp(type, "scsi")) {
    numscsi = ::make_device_names(&scsinames, "SCSI");
    if (numscsi < 0) {
      free_devnames(atanames, numata);
      set_err(ENOMEM);
      return false;
    }
  }

  // Add to devlist
  int i;
  if (!type)
    type="";
  for (i = 0; i < numata; i++) {
    ata_device * atadev = get_ata_device(atanames[i], type);
    if (atadev)
      devlist.push_back(atadev);
  }
  free_devnames(atanames, numata);

  for (i = 0; i < numscsi; i++) {
    scsi_device * scsidev = get_scsi_device(scsinames[i], type);
    if (scsidev)
      devlist.push_back(scsidev);
  }
  free_devnames(scsinames, numscsi);
  return true;
}
Пример #4
0
int ata_rw_multiple(int rw, int dev, uint64_t blk, char *buf, int count)
{
	if(!count) return 0;
	struct ata_device *device = get_ata_device(dev);
	struct ata_controller *cont = device->controller;
	if(!cont->enabled || !(device->flags & F_ENABLED)) 
		return 0;
	if(!(device->flags & F_EXIST))
		return 0;
	if(blk+count > device->length)
		return 0;
	int ret;
	if(device->flags & F_DMA && cont->dma_use && ATA_DMA_ENABLE)
		ret = ata_dma_rw(cont, device, rw, blk, (unsigned char *)buf, count);
	else
		ret = ata_pio_rw(cont, device, rw, blk, (unsigned char *)buf, count);
	return ret;
}