Exemple #1
0
/* Flush the write buffer */
static int flush_write_buffer(int dev)
{
  int offset, transfer, blks;
  int result;
  unsigned char cmd[10];
  Scsi_Cmnd *SCpnt;

#if ST_WRITE_THRESHOLD_BLOCKS < ST_BUFFER_BLOCKS
  if (scsi_tapes[dev].buffer->writing) {
    write_behind_check(dev);
    if (scsi_tapes[dev].buffer->last_result) {
#ifdef DEBUG
      printk("st%d: Async write error %x.\n", dev,
	     scsi_tapes[dev].buffer->last_result);
#endif
      return (-EIO);
    }
  }
#endif

  result = 0;
  if (scsi_tapes[dev].dirty==1) {
    SCpnt = allocate_device(NULL, scsi_tapes[dev].device->index, 1);

    offset = scsi_tapes[dev].buffer->buffer_bytes;
    transfer = ((offset + scsi_tapes[dev].block_size - 1) /
		scsi_tapes[dev].block_size) * scsi_tapes[dev].block_size;
#ifdef DEBUG
    printk("st%d: Flushing %d bytes.\n", dev, transfer);
#endif
    memset(scsi_tapes[dev].buffer->b_data + offset, 0, transfer - offset);

    SCpnt->sense_buffer[0] = 0;
    memset(cmd, 0, 10);
    cmd[0] = WRITE_6;
    cmd[1] = 1;
    blks = transfer / scsi_tapes[dev].block_size;
    cmd[2] = blks >> 16;
    cmd[3] = blks >> 8;
    cmd[4] = blks;
    SCpnt->request.dev = dev;
    scsi_do_cmd (SCpnt,
		 (void *) cmd, scsi_tapes[dev].buffer->b_data, transfer,
		 st_sleep_done, ST_TIMEOUT, MAX_RETRIES);

    if (SCpnt->request.dev == dev) sleep_on( &scsi_tapes[dev].waiting );

    if (SCpnt->result != 0) {
      printk("st%d: Error on flush:\n", dev);
#ifdef DEBUG
      st_chk_result(dev, SCpnt->result, SCpnt->sense_buffer);
#endif
      result = (-EIO);
    }
    else {
      scsi_tapes[dev].dirty = 0;
      scsi_tapes[dev].buffer->buffer_bytes = 0;
    }
    SCpnt->request.dev = -1;  /* Mark as not busy */
  }
Exemple #2
0
static int ioctl_internal_command(Scsi_Device *dev, char * cmd,
				  int timeout, int retries)
{
    int result;
    Scsi_Cmnd * SCpnt;
    
    SCpnt = allocate_device(NULL, dev, 1);
    {
	struct semaphore sem = MUTEX_LOCKED;
	SCpnt->request.sem = &sem;
	scsi_do_cmd(SCpnt,  cmd, NULL,  0, scsi_ioctl_done,  timeout, retries);
	down(&sem);
    }
    
    if(driver_byte(SCpnt->result) != 0)
	switch(SCpnt->sense_buffer[2] & 0xf) {
	case ILLEGAL_REQUEST:
	    if(cmd[0] == ALLOW_MEDIUM_REMOVAL) dev->lockable = 0;
	    else printk("SCSI device (ioctl) reports ILLEGAL REQUEST.\n");
	    break;
	case NOT_READY: /* This happens if there is no disc in drive */
	    if(dev->removable){
		printk(KERN_INFO "Device not ready.  Make sure there is a disc in the drive.\n");
		break;
	    };
	case UNIT_ATTENTION:
	    if (dev->removable){
		dev->changed = 1;
		SCpnt->result = 0; /* This is no longer considered an error */
		printk(KERN_INFO "Disc change detected.\n");
		break;
	    };
	default: /* Fall through for non-removable media */
	    printk("SCSI error: host %d id %d lun %d return code = %x\n",
		   dev->host->host_no,
		   dev->id,
		   dev->lun,
		   SCpnt->result);
	    printk("\tSense class %x, sense error %x, extended sense %x\n",
		   sense_class(SCpnt->sense_buffer[0]),
		   sense_error(SCpnt->sense_buffer[0]),
		   SCpnt->sense_buffer[2] & 0xf);
	    
	};
    
    result = SCpnt->result;
    SCpnt->request.rq_status = RQ_INACTIVE;

    if (!SCpnt->device->was_reset && SCpnt->device->scsi_request_fn)
	(*SCpnt->device->scsi_request_fn)();

    wake_up(&SCpnt->device->device_wait);
    return result;
}
static int ioctl_internal_command(Scsi_Device *dev, char * cmd)
{
	int host, result;
	Scsi_Cmnd * SCpnt;

	host = dev->host_no;

	SCpnt = allocate_device(NULL, dev->index, 1);
	scsi_do_cmd(SCpnt,  cmd, NULL,  0,
			scsi_ioctl_done,  MAX_TIMEOUT,
			MAX_RETRIES);

	if (SCpnt->request.dev != 0xfffe){
	  SCpnt->request.waiting = current;
	  current->state = TASK_UNINTERRUPTIBLE;
	  while (SCpnt->request.dev != 0xfffe) schedule();
	};

	if(driver_byte(SCpnt->result) != 0)
	  switch(SCpnt->sense_buffer[2] & 0xf) {
	  case ILLEGAL_REQUEST:
	    if(cmd[0] == ALLOW_MEDIUM_REMOVAL) dev->lockable = 0;
	    else printk("SCSI device (ioctl) reports ILLEGAL REQUEST.\n");
	    break;
	  case NOT_READY: /* This happens if there is no disc in drive */
	    if(dev->removable){
	      printk("Device not ready.  Make sure there is a disc in the drive.\n");
	      break;
	    };
	  case UNIT_ATTENTION:
	    if (dev->removable){
	      dev->changed = 1;
	      SCpnt->result = 0; /* This is no longer considered an error */
	      printk("Disc change detected.\n");
	      break;
	    };
	  default: /* Fall through for non-removable media */
	    printk("SCSI CD error: host %d id %d lun %d return code = %x\n",
		   dev->host_no,
		   dev->id,
		   dev->lun,
		   SCpnt->result);
	    printk("\tSense class %x, sense error %x, extended sense %x\n",
		   sense_class(SCpnt->sense_buffer[0]),
		   sense_error(SCpnt->sense_buffer[0]),
		   SCpnt->sense_buffer[2] & 0xf);

	  };

	result = SCpnt->result;
	SCpnt->request.dev = -1;  /* Mark as not busy */
	wake_up(&scsi_devices[SCpnt->index].device_wait);
	return result;
}
Exemple #4
0
static int do_ioctl(int target, unsigned char * sr_cmd, void * buffer, unsigned buflength)
{
    Scsi_Cmnd * SCpnt;
    int result;

    SCpnt = allocate_device(NULL, scsi_CDs[target].device->index, 1);
    scsi_do_cmd(SCpnt,
                (void *) sr_cmd, buffer, buflength, sr_ioctl_done,
                IOCTL_TIMEOUT, IOCTL_RETRIES);


    if (SCpnt->request.dev != 0xfffe) {
        SCpnt->request.waiting = current;
        current->state = TASK_UNINTERRUPTIBLE;
        while (SCpnt->request.dev != 0xfffe) schedule();
    };

    result = SCpnt->result;

    /* Minimal error checking.  Ignore cases we know about, and report the rest. */
    if(driver_byte(result) != 0)
        switch(SCpnt->sense_buffer[2] & 0xf) {
        case UNIT_ATTENTION:
            scsi_CDs[target].device->changed = 1;
            printk("Disc change detected.\n");
            break;
        case NOT_READY: /* This happens if there is no disc in drive */
            printk("CDROM not ready.  Make sure there is a disc in the drive.\n");
            break;
        case ILLEGAL_REQUEST:
            printk("CDROM (ioctl) reports ILLEGAL REQUEST.\n");
            break;
        default:
            printk("SCSI CD error: host %d id %d lun %d return code = %03x\n",
                   scsi_CDs[target].device->host_no,
                   scsi_CDs[target].device->id,
                   scsi_CDs[target].device->lun,
                   result);
            printk("\tSense class %x, sense error %x, extended sense %x\n",
                   sense_class(SCpnt->sense_buffer[0]),
                   sense_error(SCpnt->sense_buffer[0]),
                   SCpnt->sense_buffer[2] & 0xf);

        };

    result = SCpnt->result;
    SCpnt->request.dev = -1; /* Deallocate */
    wake_up(&scsi_devices[SCpnt->index].device_wait);
    /* Wake up a process waiting for device*/
    return result;
}
Exemple #5
0
static int ntrig_usbhid_probe(struct hid_device *hdev, const struct hid_device_id *id)
{
	char				phys_path[256];
	int 				ret;
	struct ntrig_usbhid_data*	nd;
	struct usb_interface*		intf;
	struct usb_device* 		dev;
	struct usb_host_interface*	interface;
	struct usb_endpoint_descriptor*	endpoint;
	struct _ntrig_dev_ncp_func	ncp_func;
	struct _ntrig_dev_hid_func	hid_func;


	intf 	 = to_usb_interface(hdev->dev.parent);
	dev	 = interface_to_usbdev(intf);
	interface= intf->cur_altsetting;
	endpoint = &interface->endpoint[0].desc;
	nd = kmalloc(sizeof(struct ntrig_usbhid_data), GFP_KERNEL);
	if (!nd) {
		dev_err(&hdev->dev, "cannot allocate N-Trig data\n");
		return -ENOMEM;
	} 
	if(DTRG_NO_ERROR != allocate_device(&nd->ntrig_dispatcher)){
		dev_err(&hdev->dev, "cannot allocate N-Trig dispatcher\n");
		return DTRG_FAILED;
	}

	hid_set_drvdata(hdev, nd);
	ret = hid_parse(hdev);
	if (ret) {
		dev_err(&hdev->dev, "parse failed, error code=%d\n", ret);
		goto err_free;
	}

	if (NCP_EP_ADDRESS == endpoint->bEndpointAddress) {
		ret = hid_hw_start(hdev, ~HID_QUIRK_MULTI_INPUT);
		if (ret) {
			dev_err(&hdev->dev, "hw start failed NCP, error code=%d\n", ret);
			goto err_free;
		}

		/* register device in the dispatcher - set device and function pointers for ncp
		set sensor id in the device data structure */	  
	// NOTE: registration of ncp_read, ncp_write & dev is linked. 
	//  It's the resposibility of this function to set these parameters together
		ncp_func.dev = (void *) hdev;
		ncp_func.read = NTRIGReadNCP;
		ncp_func.write = NTRIGWriteNCP;
		nd->sensor_id = RegNtrigDispatcher(TYPE_BUS_USB_HID, hdev->uniq, &ncp_func, NULL);
		// TODO: define behavior in case of fail
		if (nd->sensor_id == DTRG_FAILED) {
			ntrig_dbg("%s: Cannot register device to dispatcher\n", __FUNCTION__);
			goto err_free;
		}
		ntrig_dbg("%s NCP dev registered with dispatcher, bus_id = %s, sensor_id = %d\n", __FUNCTION__, hdev->uniq, nd->sensor_id);
		return 0;
	}

	else {
		ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF);
		if (ret) {
			dev_err(&hdev->dev, "hw start failed TOUCH, error code=%d\n", ret);
			goto err_free;
		}
		ret = ntrig_usbhid_send_report(hdev, REPORTID_DRIVER_ALIVE, NULL, 0);
		if (ret < 0) {
			dev_err(&hdev->dev, "send set feature failed, error code=%d\n", ret);
			goto err_free;
		}

		/* register device in the dispatcher - no need to set device and function pointers for touch events
		   set sensor id in the device data structure */	  
	// NOTE: registration of ncp_read, ncp_write & dev is linked. 
	//  It's the resposibility of this function to set these parameters together
		hid_func.dev = (void *)hdev;
		hid_func.read = NTRIGReadSensor;
		hid_func.write = NTRIGWriteSensor;
		nd->sensor_id = RegNtrigDispatcher(TYPE_BUS_USB_HID, hdev->uniq, NULL, &hid_func); 
		// TODO: define behavior in case of fail
		if (nd->sensor_id == DTRG_FAILED) {
			ntrig_dbg("%s: Cannot register device to dispatcher\n", __FUNCTION__);
			goto err_free;
		}
		ntrig_dbg("%s HID dev registered with dispatcher, bus_id = %s, sensor_id = %d\n", __FUNCTION__, hdev->uniq, nd->sensor_id);
	}
	/**
	 * Create additional single touch queue
         */

	usb_make_path(dev, phys_path, sizeof(phys_path));
	strlcat(phys_path, "/input0", sizeof(phys_path));
	
	nd->ntrig_dispatcher->phys = phys_path;
	nd->ntrig_dispatcher->name = "USBHID";
	nd->ntrig_dispatcher->pressure_min= 0;
	nd->ntrig_dispatcher->pressure_max= 0xFF;
	create_single_touch(nd->ntrig_dispatcher, nd->sensor_id);
	create_multi_touch (nd->ntrig_dispatcher, nd->sensor_id);

	nd->battery_status = PEN_BUTTON_BATTERY_NOT_AVAILABLE;

	ntrig_dbg("Iside %s, bus_id = %d, name = %s, phys = %s, uniq = %s\n", __FUNCTION__, hdev->bus, hdev->name, hdev->phys, hdev->uniq );

	ntrig_dbg("End of %s\n", __FUNCTION__);
	return DTRG_NO_ERROR;
err_free:
	ntrig_dbg("Error End of %s\n", __FUNCTION__);
	remove_device(&nd->ntrig_dispatcher);	
	kfree(nd);
	return DTRG_FAILED;
}
static int ioctl_command(Scsi_Device *dev, void *buffer)
{
	char * buf;
	char cmd[12];
	char * cmd_in;
	Scsi_Cmnd * SCpnt;
	unsigned char opcode;
	int inlen, outlen, cmdlen;
	int needed;
	int result;

	if (!buffer)
		return -EINVAL;
	
	inlen = get_fs_long((unsigned long *) buffer);
	outlen = get_fs_long( ((unsigned long *) buffer) + 1);

	cmd_in = (char *) ( ((int *)buffer) + 2);
	opcode = get_fs_byte(cmd_in); 

	needed = (inlen > outlen ? inlen : outlen);
	if(needed){
	  needed = (needed + 511) & ~511;
	  if (needed > MAX_BUF) needed = MAX_BUF;
	  buf = (char *) scsi_malloc(needed);
	  if (!buf) return -ENOMEM;
	} else
	  buf = NULL;

	memcpy_fromfs ((void *) cmd,  cmd_in,  cmdlen = COMMAND_SIZE (opcode));
	memcpy_fromfs ((void *) buf,  (void *) (cmd_in + cmdlen), inlen > MAX_BUF ? MAX_BUF : inlen);

	cmd[1] = ( cmd[1] & 0x1f ) | (dev->lun << 5);

#ifndef DEBUG_NO_CMD
	
	SCpnt = allocate_device(NULL, dev->index, 1);

	scsi_do_cmd(SCpnt,  cmd,  buf, needed,  scsi_ioctl_done,  MAX_TIMEOUT, 
			MAX_RETRIES);

	if (SCpnt->request.dev != 0xfffe){
	  SCpnt->request.waiting = current;
	  current->state = TASK_UNINTERRUPTIBLE;
	  while (SCpnt->request.dev != 0xfffe) schedule();
	};


	/* If there was an error condition, pass the info back to the user. */
	if(SCpnt->result) {
	  result = verify_area(VERIFY_WRITE, cmd_in, sizeof(SCpnt->sense_buffer));
	  if (result)
	    return result;
	  memcpy_tofs((void *) cmd_in,  SCpnt->sense_buffer, sizeof(SCpnt->sense_buffer));
	} else {

	  result = verify_area(VERIFY_WRITE, cmd_in, (outlen > MAX_BUF) ? MAX_BUF  : outlen);
	  if (result)
	    return result;
	  memcpy_tofs ((void *) cmd_in,  buf,  (outlen > MAX_BUF) ? MAX_BUF  : outlen);
	};
	result = SCpnt->result;
	SCpnt->request.dev = -1;  /* Mark as not busy */
	if (buf) scsi_free(buf, needed);
	wake_up(&scsi_devices[SCpnt->index].device_wait);
	return result;
#else
	{
	int i;
	printk("scsi_ioctl : device %d.  command = ", dev->id);
	for (i = 0; i < 12; ++i)
		printk("%02x ", cmd[i]);
	printk("\nbuffer =");
	for (i = 0; i < 20; ++i)
		printk("%02x ", buf[i]);
	printk("\n");
	printk("inlen = %d, outlen = %d, cmdlen = %d\n",
		inlen, outlen, cmdlen);
	printk("buffer = %d, cmd_in = %d\n", buffer, cmd_in);
	}
	return 0;
#endif
}
Exemple #7
0
/*
 * This interface is depreciated - users should use the scsi generics
 * interface instead, as this is a more flexible approach to performing
 * generic SCSI commands on a device.
 */
static int ioctl_command(Scsi_Device *dev, void *buffer)
{
    char * buf;
    unsigned char cmd[12]; 
    char * cmd_in;
    Scsi_Cmnd * SCpnt;
    unsigned char opcode;
    int inlen, outlen, cmdlen;
    int needed, buf_needed;
    int timeout, retries, result;
    
    if (!buffer)
	return -EINVAL;
    

    /*
     * Verify that we can read at least this much.
     */
    result = verify_area(VERIFY_READ, buffer, 2*sizeof(long) + 1);
    if (result) return result;

    /*
     * The structure that we are passed should look like:
     *
     * struct sdata {
     *	unsigned int inlen;
     *	unsigned int outlen;
     *	unsigned char  cmd[];  # However many bytes are used for cmd.
     *	unsigned char  data[];
     * };
     */
    inlen = get_user((unsigned int *) buffer);
    outlen = get_user( ((unsigned int *) buffer) + 1);
    
    /*
     * We do not transfer more than MAX_BUF with this interface.
     * If the user needs to transfer more data than this, they
     * should use scsi_generics instead.
     */
    if( inlen > MAX_BUF )  return -EINVAL;
    if( outlen > MAX_BUF )  return -EINVAL;

    cmd_in = (char *) ( ((int *)buffer) + 2);
    opcode = get_user(cmd_in); 
    
    needed = buf_needed = (inlen > outlen ? inlen : outlen);
    if(buf_needed){
	buf_needed = (buf_needed + 511) & ~511;
	if (buf_needed > MAX_BUF) buf_needed = MAX_BUF;
	buf = (char *) scsi_malloc(buf_needed);
	if (!buf) return -ENOMEM;
	memset(buf, 0, buf_needed);
    } else
	buf = NULL;
    
    /*
     * Obtain the command from the user's address space.
     */
    cmdlen = COMMAND_SIZE(opcode);

    result = verify_area(VERIFY_READ, cmd_in, 
                         cmdlen + inlen > MAX_BUF ? MAX_BUF : inlen);
    if (result) return result;

    memcpy_fromfs ((void *) cmd,  cmd_in,  cmdlen);
    
    /*
     * Obtain the data to be sent to the device (if any).
     */
    memcpy_fromfs ((void *) buf,  
                   (void *) (cmd_in + cmdlen), 
                   inlen);
    
    /*
     * Set the lun field to the correct value.
     */
    cmd[1] = ( cmd[1] & 0x1f ) | (dev->lun << 5);
    
    switch (opcode)
      {
      case FORMAT_UNIT:
	timeout = FORMAT_UNIT_TIMEOUT;
	retries = 1;
	break;
      case START_STOP:
	timeout = START_STOP_TIMEOUT;
	retries = NORMAL_RETRIES;
	break;
      case MOVE_MEDIUM:
	timeout = MOVE_MEDIUM_TIMEOUT;
	retries = NORMAL_RETRIES;
	break;
      case READ_ELEMENT_STATUS:
	timeout = READ_ELEMENT_STATUS_TIMEOUT;
	retries = NORMAL_RETRIES;
	break;
      default:
	timeout = NORMAL_TIMEOUT;
	retries = NORMAL_RETRIES;
	break;
      }

#ifndef DEBUG_NO_CMD
    
    SCpnt = allocate_device(NULL, dev, 1);

    {
	struct semaphore sem = MUTEX_LOCKED;
	SCpnt->request.sem = &sem;
	scsi_do_cmd(SCpnt,  cmd,  buf, needed,  scsi_ioctl_done,
		    timeout, retries);
	down(&sem);
    }
    
    /* 
     * If there was an error condition, pass the info back to the user. 
     */
    if(SCpnt->result) {
        result = verify_area(VERIFY_WRITE, 
                             cmd_in, 
                             sizeof(SCpnt->sense_buffer));
        if (result) return result;
        memcpy_tofs((void *) cmd_in,  
                    SCpnt->sense_buffer, 
                    sizeof(SCpnt->sense_buffer));
    } else {
        result = verify_area(VERIFY_WRITE, cmd_in, outlen);
        if (result) return result;
        memcpy_tofs ((void *) cmd_in,  buf,  outlen);
    }
    result = SCpnt->result;

    SCpnt->request.rq_status = RQ_INACTIVE;

    if (buf) scsi_free(buf, buf_needed);
    
    if(SCpnt->device->scsi_request_fn)
	(*SCpnt->device->scsi_request_fn)();
    
    wake_up(&SCpnt->device->device_wait);
    return result;
#else
    {
	int i;
	printk("scsi_ioctl : device %d.  command = ", dev->id);
	for (i = 0; i < 12; ++i)
	    printk("%02x ", cmd[i]);
	printk("\nbuffer =");
	for (i = 0; i < 20; ++i)
	    printk("%02x ", buf[i]);
	printk("\n");
	printk("inlen = %d, outlen = %d, cmdlen = %d\n",
	       inlen, outlen, cmdlen);
	printk("buffer = %d, cmd_in = %d\n", buffer, cmd_in);
    }
    return 0;
#endif
}