diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2005-09-07 20:31:27 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-09-07 20:31:27 -0400 |
commit | 0481990b758628e12f4b0a9e15094e70cefc7cd1 (patch) | |
tree | 67a4b4b7acc6a688b87ef2a2d3ec0e296e6e480c /drivers/scsi/sr_ioctl.c | |
parent | db400b3c4ee89d384d9163836a55577abdae772d (diff) | |
parent | 17fa53da1239b8712c5cebbd72a74c713b6c2db9 (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.c | 62 |
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 | ||
85 | int sr_do_ioctl(Scsi_CD *cd, struct packet_command *cgc) | 85 | int 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 | } |