USB: gadget rndis: stop windows self-immolation
[pandora-kernel.git] / block / scsi_ioctl.c
index c5b9bcf..ec4b7f2 100644 (file)
@@ -105,12 +105,96 @@ static int sg_emulated_host(struct request_queue *q, int __user *p)
        return put_user(1, p);
 }
 
+void blk_set_cmd_filter_defaults(struct blk_cmd_filter *filter)
+{
+       /* Basic read-only commands */
+       __set_bit(TEST_UNIT_READY, filter->read_ok);
+       __set_bit(REQUEST_SENSE, filter->read_ok);
+       __set_bit(READ_6, filter->read_ok);
+       __set_bit(READ_10, filter->read_ok);
+       __set_bit(READ_12, filter->read_ok);
+       __set_bit(READ_16, filter->read_ok);
+       __set_bit(READ_BUFFER, filter->read_ok);
+       __set_bit(READ_DEFECT_DATA, filter->read_ok);
+       __set_bit(READ_CAPACITY, filter->read_ok);
+       __set_bit(READ_LONG, filter->read_ok);
+       __set_bit(INQUIRY, filter->read_ok);
+       __set_bit(MODE_SENSE, filter->read_ok);
+       __set_bit(MODE_SENSE_10, filter->read_ok);
+       __set_bit(LOG_SENSE, filter->read_ok);
+       __set_bit(START_STOP, filter->read_ok);
+       __set_bit(GPCMD_VERIFY_10, filter->read_ok);
+       __set_bit(VERIFY_16, filter->read_ok);
+       __set_bit(REPORT_LUNS, filter->read_ok);
+       __set_bit(SERVICE_ACTION_IN, filter->read_ok);
+       __set_bit(RECEIVE_DIAGNOSTIC, filter->read_ok);
+       __set_bit(MAINTENANCE_IN, filter->read_ok);
+       __set_bit(GPCMD_READ_BUFFER_CAPACITY, filter->read_ok);
+
+       /* Audio CD commands */
+       __set_bit(GPCMD_PLAY_CD, filter->read_ok);
+       __set_bit(GPCMD_PLAY_AUDIO_10, filter->read_ok);
+       __set_bit(GPCMD_PLAY_AUDIO_MSF, filter->read_ok);
+       __set_bit(GPCMD_PLAY_AUDIO_TI, filter->read_ok);
+       __set_bit(GPCMD_PAUSE_RESUME, filter->read_ok);
+
+       /* CD/DVD data reading */
+       __set_bit(GPCMD_READ_CD, filter->read_ok);
+       __set_bit(GPCMD_READ_CD_MSF, filter->read_ok);
+       __set_bit(GPCMD_READ_DISC_INFO, filter->read_ok);
+       __set_bit(GPCMD_READ_CDVD_CAPACITY, filter->read_ok);
+       __set_bit(GPCMD_READ_DVD_STRUCTURE, filter->read_ok);
+       __set_bit(GPCMD_READ_HEADER, filter->read_ok);
+       __set_bit(GPCMD_READ_TRACK_RZONE_INFO, filter->read_ok);
+       __set_bit(GPCMD_READ_SUBCHANNEL, filter->read_ok);
+       __set_bit(GPCMD_READ_TOC_PMA_ATIP, filter->read_ok);
+       __set_bit(GPCMD_REPORT_KEY, filter->read_ok);
+       __set_bit(GPCMD_SCAN, filter->read_ok);
+       __set_bit(GPCMD_GET_CONFIGURATION, filter->read_ok);
+       __set_bit(GPCMD_READ_FORMAT_CAPACITIES, filter->read_ok);
+       __set_bit(GPCMD_GET_EVENT_STATUS_NOTIFICATION, filter->read_ok);
+       __set_bit(GPCMD_GET_PERFORMANCE, filter->read_ok);
+       __set_bit(GPCMD_SEEK, filter->read_ok);
+       __set_bit(GPCMD_STOP_PLAY_SCAN, filter->read_ok);
+
+       /* Basic writing commands */
+       __set_bit(WRITE_6, filter->write_ok);
+       __set_bit(WRITE_10, filter->write_ok);
+       __set_bit(WRITE_VERIFY, filter->write_ok);
+       __set_bit(WRITE_12, filter->write_ok);
+       __set_bit(WRITE_VERIFY_12, filter->write_ok);
+       __set_bit(WRITE_16, filter->write_ok);
+       __set_bit(WRITE_LONG, filter->write_ok);
+       __set_bit(WRITE_LONG_2, filter->write_ok);
+       __set_bit(ERASE, filter->write_ok);
+       __set_bit(GPCMD_MODE_SELECT_10, filter->write_ok);
+       __set_bit(MODE_SELECT, filter->write_ok);
+       __set_bit(LOG_SELECT, filter->write_ok);
+       __set_bit(GPCMD_BLANK, filter->write_ok);
+       __set_bit(GPCMD_CLOSE_TRACK, filter->write_ok);
+       __set_bit(GPCMD_FLUSH_CACHE, filter->write_ok);
+       __set_bit(GPCMD_FORMAT_UNIT, filter->write_ok);
+       __set_bit(GPCMD_REPAIR_RZONE_TRACK, filter->write_ok);
+       __set_bit(GPCMD_RESERVE_RZONE_TRACK, filter->write_ok);
+       __set_bit(GPCMD_SEND_DVD_STRUCTURE, filter->write_ok);
+       __set_bit(GPCMD_SEND_EVENT, filter->write_ok);
+       __set_bit(GPCMD_SEND_KEY, filter->write_ok);
+       __set_bit(GPCMD_SEND_OPC, filter->write_ok);
+       __set_bit(GPCMD_SEND_CUE_SHEET, filter->write_ok);
+       __set_bit(GPCMD_SET_SPEED, filter->write_ok);
+       __set_bit(GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL, filter->write_ok);
+       __set_bit(GPCMD_LOAD_UNLOAD, filter->write_ok);
+       __set_bit(GPCMD_SET_STREAMING, filter->write_ok);
+}
+EXPORT_SYMBOL_GPL(blk_set_cmd_filter_defaults);
+
 static int blk_fill_sghdr_rq(struct request_queue *q, struct request *rq,
                             struct sg_io_hdr *hdr, struct file *file)
 {
        if (copy_from_user(rq->cmd, hdr->cmdp, hdr->cmd_len))
                return -EFAULT;
-       if (blk_verify_command(file, rq->cmd))
+       if (blk_verify_command(&q->cmd_filter, rq->cmd,
+                              file->f_mode & FMODE_WRITE))
                return -EPERM;
 
        /*
@@ -298,7 +382,7 @@ int sg_scsi_ioctl(struct file *file, struct request_queue *q,
                  struct gendisk *disk, struct scsi_ioctl_command __user *sic)
 {
        struct request *rq;
-       int err;
+       int err, write_perm = 0;
        unsigned int in_len, out_len, bytes, opcode, cmdlen;
        char *buffer = NULL, sense[SCSI_SENSE_BUFFERSIZE];
 
@@ -340,7 +424,11 @@ int sg_scsi_ioctl(struct file *file, struct request_queue *q,
        if (in_len && copy_from_user(buffer, sic->data + cmdlen, in_len))
                goto error;
 
-       err = blk_verify_command(file, rq->cmd);
+       /* scsi_ioctl passes NULL */
+       if (file && (file->f_mode & FMODE_WRITE))
+               write_perm = 1;
+
+       err = blk_verify_command(&q->cmd_filter, rq->cmd, write_perm);
        if (err)
                goto error;
 
@@ -518,7 +606,7 @@ int scsi_cmd_ioctl(struct file *file, struct request_queue *q,
                        hdr.sbp = cgc.sense;
                        if (hdr.sbp)
                                hdr.mx_sb_len = sizeof(struct request_sense);
-                       hdr.timeout = cgc.timeout;
+                       hdr.timeout = jiffies_to_msecs(cgc.timeout);
                        hdr.cmdp = ((struct cdrom_generic_command __user*) arg)->cmd;
                        hdr.cmd_len = sizeof(cgc.cmd);