aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/sr_ioctl.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2005-09-07 20:31:27 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-09-07 20:31:27 -0400
commit0481990b758628e12f4b0a9e15094e70cefc7cd1 (patch)
tree67a4b4b7acc6a688b87ef2a2d3ec0e296e6e480c /drivers/scsi/sr_ioctl.c
parentdb400b3c4ee89d384d9163836a55577abdae772d (diff)
parent17fa53da1239b8712c5cebbd72a74c713b6c2db9 (diff)
Merge master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-for-linus-2.6
Diffstat (limited to 'drivers/scsi/sr_ioctl.c')
-rw-r--r--drivers/scsi/sr_ioctl.c62
1 files changed, 27 insertions, 35 deletions
diff --git a/drivers/scsi/sr_ioctl.c b/drivers/scsi/sr_ioctl.c
index 82d68fdb1548..6e45ac3c43c5 100644
--- a/drivers/scsi/sr_ioctl.c
+++ b/drivers/scsi/sr_ioctl.c
@@ -17,7 +17,7 @@
17#include <scsi/scsi_eh.h> 17#include <scsi/scsi_eh.h>
18#include <scsi/scsi_host.h> 18#include <scsi/scsi_host.h>
19#include <scsi/scsi_ioctl.h> 19#include <scsi/scsi_ioctl.h>
20#include <scsi/scsi_request.h> 20#include <scsi/scsi_cmnd.h>
21 21
22#include "sr.h" 22#include "sr.h"
23 23
@@ -84,41 +84,37 @@ static int sr_fake_playtrkind(struct cdrom_device_info *cdi, struct cdrom_ti *ti
84 84
85int sr_do_ioctl(Scsi_CD *cd, struct packet_command *cgc) 85int sr_do_ioctl(Scsi_CD *cd, struct packet_command *cgc)
86{ 86{
87 struct scsi_request *SRpnt;
88 struct scsi_device *SDev; 87 struct scsi_device *SDev;
89 struct request *req; 88 struct scsi_sense_hdr sshdr;
90 int result, err = 0, retries = 0; 89 int result, err = 0, retries = 0;
90 struct request_sense *sense = cgc->sense;
91 91
92 SDev = cd->device; 92 SDev = cd->device;
93 SRpnt = scsi_allocate_request(SDev, GFP_KERNEL); 93
94 if (!SRpnt) { 94 if (!sense) {
95 printk(KERN_ERR "Unable to allocate SCSI request in sr_do_ioctl"); 95 sense = kmalloc(sizeof(*sense), GFP_KERNEL);
96 err = -ENOMEM; 96 if (!sense) {
97 goto out; 97 err = -ENOMEM;
98 } 98 goto out;
99 SRpnt->sr_data_direction = cgc->data_direction; 99 }
100 }
100 101
101 retry: 102 retry:
102 if (!scsi_block_when_processing_errors(SDev)) { 103 if (!scsi_block_when_processing_errors(SDev)) {
103 err = -ENODEV; 104 err = -ENODEV;
104 goto out_free; 105 goto out;
105 } 106 }
106 107
107 scsi_wait_req(SRpnt, cgc->cmd, cgc->buffer, cgc->buflen, 108 memset(sense, 0, sizeof(*sense));
108 cgc->timeout, IOCTL_RETRIES); 109 result = scsi_execute(SDev, cgc->cmd, cgc->data_direction,
109 110 cgc->buffer, cgc->buflen, (char *)sense,
110 req = SRpnt->sr_request; 111 cgc->timeout, IOCTL_RETRIES, 0);
111 if (SRpnt->sr_buffer && req->buffer && SRpnt->sr_buffer != req->buffer) {
112 memcpy(req->buffer, SRpnt->sr_buffer, SRpnt->sr_bufflen);
113 kfree(SRpnt->sr_buffer);
114 SRpnt->sr_buffer = req->buffer;
115 }
116 112
117 result = SRpnt->sr_result; 113 scsi_normalize_sense((char *)sense, sizeof(*sense), &sshdr);
118 114
119 /* Minimal error checking. Ignore cases we know about, and report the rest. */ 115 /* Minimal error checking. Ignore cases we know about, and report the rest. */
120 if (driver_byte(result) != 0) { 116 if (driver_byte(result) != 0) {
121 switch (SRpnt->sr_sense_buffer[2] & 0xf) { 117 switch (sshdr.sense_key) {
122 case UNIT_ATTENTION: 118 case UNIT_ATTENTION:
123 SDev->changed = 1; 119 SDev->changed = 1;
124 if (!cgc->quiet) 120 if (!cgc->quiet)
@@ -128,8 +124,8 @@ int sr_do_ioctl(Scsi_CD *cd, struct packet_command *cgc)
128 err = -ENOMEDIUM; 124 err = -ENOMEDIUM;
129 break; 125 break;
130 case NOT_READY: /* This happens if there is no disc in drive */ 126 case NOT_READY: /* This happens if there is no disc in drive */
131 if (SRpnt->sr_sense_buffer[12] == 0x04 && 127 if (sshdr.asc == 0x04 &&
132 SRpnt->sr_sense_buffer[13] == 0x01) { 128 sshdr.ascq == 0x01) {
133 /* sense: Logical unit is in process of becoming ready */ 129 /* sense: Logical unit is in process of becoming ready */
134 if (!cgc->quiet) 130 if (!cgc->quiet)
135 printk(KERN_INFO "%s: CDROM not ready yet.\n", cd->cdi.name); 131 printk(KERN_INFO "%s: CDROM not ready yet.\n", cd->cdi.name);
@@ -146,37 +142,33 @@ int sr_do_ioctl(Scsi_CD *cd, struct packet_command *cgc)
146 if (!cgc->quiet) 142 if (!cgc->quiet)
147 printk(KERN_INFO "%s: CDROM not ready. Make sure there is a disc in the drive.\n", cd->cdi.name); 143 printk(KERN_INFO "%s: CDROM not ready. Make sure there is a disc in the drive.\n", cd->cdi.name);
148#ifdef DEBUG 144#ifdef DEBUG
149 scsi_print_req_sense("sr", SRpnt); 145 scsi_print_sense_hdr("sr", &sshdr);
150#endif 146#endif
151 err = -ENOMEDIUM; 147 err = -ENOMEDIUM;
152 break; 148 break;
153 case ILLEGAL_REQUEST: 149 case ILLEGAL_REQUEST:
154 err = -EIO; 150 err = -EIO;
155 if (SRpnt->sr_sense_buffer[12] == 0x20 && 151 if (sshdr.asc == 0x20 &&
156 SRpnt->sr_sense_buffer[13] == 0x00) 152 sshdr.ascq == 0x00)
157 /* sense: Invalid command operation code */ 153 /* sense: Invalid command operation code */
158 err = -EDRIVE_CANT_DO_THIS; 154 err = -EDRIVE_CANT_DO_THIS;
159#ifdef DEBUG 155#ifdef DEBUG
160 __scsi_print_command(cgc->cmd); 156 __scsi_print_command(cgc->cmd);
161 scsi_print_req_sense("sr", SRpnt); 157 scsi_print_sense_hdr("sr", &sshdr);
162#endif 158#endif
163 break; 159 break;
164 default: 160 default:
165 printk(KERN_ERR "%s: CDROM (ioctl) error, command: ", cd->cdi.name); 161 printk(KERN_ERR "%s: CDROM (ioctl) error, command: ", cd->cdi.name);
166 __scsi_print_command(cgc->cmd); 162 __scsi_print_command(cgc->cmd);
167 scsi_print_req_sense("sr", SRpnt); 163 scsi_print_sense_hdr("sr", &sshdr);
168 err = -EIO; 164 err = -EIO;
169 } 165 }
170 } 166 }
171 167
172 if (cgc->sense)
173 memcpy(cgc->sense, SRpnt->sr_sense_buffer, sizeof(*cgc->sense));
174
175 /* Wake up a process waiting for device */ 168 /* Wake up a process waiting for device */
176 out_free:
177 scsi_release_request(SRpnt);
178 SRpnt = NULL;
179 out: 169 out:
170 if (!cgc->sense)
171 kfree(sense);
180 cgc->stat = err; 172 cgc->stat = err;
181 return err; 173 return err;
182} 174}