vserver 1.9.5.x5
[linux-2.6.git] / drivers / block / scsi_ioctl.c
index f8fb532..689527a 100644 (file)
@@ -107,12 +107,13 @@ static int sg_emulated_host(request_queue_t *q, int __user *p)
 
 #define CMD_READ_SAFE  0x01
 #define CMD_WRITE_SAFE 0x02
+#define CMD_WARNED     0x04
 #define safe_for_read(cmd)     [cmd] = CMD_READ_SAFE
 #define safe_for_write(cmd)    [cmd] = CMD_WRITE_SAFE
 
 static int verify_command(struct file *file, unsigned char *cmd)
 {
-       static const unsigned char cmd_type[256] = {
+       static unsigned char cmd_type[256] = {
 
                /* Basic read-only commands */
                safe_for_read(TEST_UNIT_READY),
@@ -126,10 +127,10 @@ static int verify_command(struct file *file, unsigned char *cmd)
                safe_for_read(INQUIRY),
                safe_for_read(MODE_SENSE),
                safe_for_read(MODE_SENSE_10),
+               safe_for_read(LOG_SENSE),
                safe_for_read(START_STOP),
                safe_for_read(GPCMD_VERIFY_10),
                safe_for_read(VERIFY_16),
-               safe_for_read(READ_BUFFER),
 
                /* Audio CD commands */
                safe_for_read(GPCMD_PLAY_CD),
@@ -139,6 +140,7 @@ static int verify_command(struct file *file, unsigned char *cmd)
                safe_for_read(GPCMD_PAUSE_RESUME),
 
                /* CD/DVD data reading */
+               safe_for_read(GPCMD_READ_BUFFER_CAPACITY),
                safe_for_read(GPCMD_READ_CD),
                safe_for_read(GPCMD_READ_CD_MSF),
                safe_for_read(GPCMD_READ_DISC_INFO),
@@ -168,6 +170,7 @@ static int verify_command(struct file *file, unsigned char *cmd)
                safe_for_write(ERASE),
                safe_for_write(GPCMD_MODE_SELECT_10),
                safe_for_write(MODE_SELECT),
+               safe_for_write(LOG_SELECT),
                safe_for_write(GPCMD_BLANK),
                safe_for_write(GPCMD_CLOSE_TRACK),
                safe_for_write(GPCMD_FLUSH_CACHE),
@@ -196,6 +199,11 @@ static int verify_command(struct file *file, unsigned char *cmd)
                        return 0;
        }
 
+       if (!type) {
+               cmd_type[cmd[0]] = CMD_WARNED;
+               printk(KERN_WARNING "scsi: unknown opcode 0x%02x\n", cmd[0]);
+       }
+
        /* And root can do any command.. */
        if (capable(CAP_SYS_RAWIO))
                return 0;
@@ -293,11 +301,11 @@ static int sg_io(struct file *file, request_queue_t *q,
        blk_execute_rq(q, bd_disk, rq);
 
        /* write to all output members */
-       hdr->status = rq->errors;       
-       hdr->masked_status = (hdr->status >> 1) & 0x1f;
-       hdr->msg_status = 0;
-       hdr->host_status = 0;
-       hdr->driver_status = 0;
+       hdr->status = 0xff & rq->errors;
+       hdr->masked_status = status_byte(rq->errors);
+       hdr->msg_status = msg_byte(rq->errors);
+       hdr->host_status = host_byte(rq->errors);
+       hdr->driver_status = driver_byte(rq->errors);
        hdr->info = 0;
        if (hdr->masked_status || hdr->host_status || hdr->driver_status)
                hdr->info |= SG_INFO_CHECK;
@@ -331,7 +339,8 @@ static int sg_scsi_ioctl(struct file *file, request_queue_t *q,
                         struct gendisk *bd_disk, Scsi_Ioctl_Command __user *sic)
 {
        struct request *rq;
-       int err, in_len, out_len, bytes, opcode, cmdlen;
+       int err;
+       unsigned int in_len, out_len, bytes, opcode, cmdlen;
        char *buffer = NULL, sense[SCSI_SENSE_BUFFERSIZE];
 
        /*
@@ -348,7 +357,7 @@ static int sg_scsi_ioctl(struct file *file, request_queue_t *q,
 
        bytes = max(in_len, out_len);
        if (bytes) {
-               buffer = kmalloc(bytes, q->bounce_gfp | GFP_USER);
+               buffer = kmalloc(bytes, q->bounce_gfp | GFP_USER| __GFP_NOWARN);
                if (!buffer)
                        return -ENOMEM;