static int PixI2c_Ioctl(struct inode *inode, struct file *fp, unsigned int cmd, unsigned long arg)
{
    PPIX_IIC_DATA ptr_user_data;
    unsigned int ui_data_length;
    unsigned char uc_device_addr;
    unsigned char uc_sub_addr;
    void *ptr_data=NULL;
    int i_return=0;

    switch(cmd)
    {
    case IOCTL_PIX_I2C_INIT:
        InitGPIO();
        break;
    case IOCTL_PIX_I2C_TERMINATE:
        ReleaseGPIO();
        break;
    case IOCTL_PIX_I2C_READ:
        ptr_user_data = (PPIX_IIC_DATA)arg;
        if((i_return=get_user(uc_device_addr, &ptr_user_data->device_addr))<0)
        {
            goto ERROR_IOCTL;
        }
        if((i_return=get_user(uc_sub_addr, &ptr_user_data->sub_addr))<0)
        {
            goto ERROR_IOCTL;
        }
        if((i_return=get_user(ui_data_length, &ptr_user_data->ui_data_length))<0)
        {
            goto ERROR_IOCTL;
        }
        ptr_data = kmalloc(ui_data_length,GFP_KERNEL);
        if((i_return=PixI2cRead(uc_device_addr, uc_sub_addr, ptr_data, ui_data_length))<0)
            goto ERROR_IOCTL;
        if((i_return=copy_to_user((void*)ptr_user_data->ptr_data, ptr_data, ui_data_length))<0)
            goto ERROR_IOCTL;
        break;
    case IOCTL_PIX_I2C_WRITE:
        ptr_user_data = (PPIX_IIC_DATA)arg;
        if((i_return=get_user(uc_device_addr, &ptr_user_data->device_addr))<0)
            goto ERROR_IOCTL;
        if((i_return=get_user(uc_sub_addr, &ptr_user_data->sub_addr))<0)
            goto ERROR_IOCTL;
        if((i_return=get_user(ui_data_length, &ptr_user_data->ui_data_length))<0)
            goto ERROR_IOCTL;
        ptr_data = kmalloc(ui_data_length,GFP_KERNEL);
        if((i_return=copy_from_user(ptr_data, (const void*)ptr_user_data->ptr_data, ui_data_length))<0)
            goto ERROR_IOCTL;
        if((i_return=PixI2cWrite(uc_device_addr, uc_sub_addr, ptr_data, ui_data_length))<0)
            goto ERROR_IOCTL;
        break;
    default:
        i_return=-EINVAL;
        break;
    }
ERROR_IOCTL:
    KERNEL_FREE(ptr_data);
    return i_return;
}
 /*ARGSUSED*/ static void
ymhusb_close_output (int dev, int mode)
{
  oss_native_word flags;
  ymhusb_midic *midic;

  midic = midi_devs[dev]->devc;

  ymhusb_flush_output (dev);

  MUTEX_ENTER_IRQDISABLE (midic->mutex, flags);
  midic->open_mode = 0;
  midic->midi_input_intr = NULL;
  udi_usb_free_request (midic->datapipe);
  udi_close_endpoint (midic->endpoint_handle);
  if (midic->outbuf != NULL)
    CONTIG_FREE (midic->osdev, midic->outbuf, OUTBUF_SIZE, midic->outbuf_dma_handle);
  if (midic->tmpbuf != NULL)
    KERNEL_FREE (midic->tmpbuf);
  midiparser_unalloc (midic->parser);
  midic->parser = NULL;
  MUTEX_EXIT_IRQRESTORE (midic->mutex, flags);
}