Lines 2191-2196
Link Here
|
2191 |
device_for_each_child(dev, NULL, target_unblock); |
2191 |
device_for_each_child(dev, NULL, target_unblock); |
2192 |
} |
2192 |
} |
2193 |
EXPORT_SYMBOL_GPL(scsi_target_unblock); |
2193 |
EXPORT_SYMBOL_GPL(scsi_target_unblock); |
|
|
2194 |
|
2195 |
/* |
2196 |
* As per scsi_wait_req_end_io(), which was removed in 2.6.15 |
2197 |
*/ |
2198 |
static void scsi_protect_wait_req_end_io(struct request *req, int error) |
2199 |
{ |
2200 |
BUG_ON(!req->waiting); |
2201 |
|
2202 |
complete(req->waiting); |
2203 |
} |
2204 |
|
2205 |
/* |
2206 |
* As per scsi_wait_done(), except calls scsi_device_block |
2207 |
* to block the queue at command completion. Only called by |
2208 |
* scsi_protect_wait(). |
2209 |
* todo: |
2210 |
* - we block the queue regardless of success and rely on the |
2211 |
* scsi_protect_queue function to unblock if the command |
2212 |
* failed... should we also inspect here? |
2213 |
*/ |
2214 |
static void scsi_protect_wait_done(struct scsi_cmnd *cmd) |
2215 |
{ |
2216 |
struct request *req = cmd->request; |
2217 |
struct request_queue *q = cmd->device->request_queue; |
2218 |
struct scsi_device *sdev = cmd->device; |
2219 |
unsigned long flags; |
2220 |
|
2221 |
req->rq_status = RQ_SCSI_DONE; /* Busy, but indicate request done */ |
2222 |
|
2223 |
spin_lock_irqsave(q->queue_lock, flags); |
2224 |
if (blk_rq_tagged(req)) |
2225 |
blk_queue_end_tag(q, req); |
2226 |
spin_unlock_irqrestore(q->queue_lock, flags); |
2227 |
|
2228 |
scsi_internal_device_block(sdev); |
2229 |
|
2230 |
if (req->waiting) |
2231 |
complete(req->waiting); |
2232 |
} |
2233 |
|
2234 |
/* |
2235 |
* As per scsi_wait_req(), except sets the completion function |
2236 |
* as scsi_protect_wait_done(). |
2237 |
*/ |
2238 |
void scsi_protect_wait_req(struct scsi_request *sreq, const void *cmnd, void *buffer, |
2239 |
unsigned bufflen, int timeout, int retries) |
2240 |
{ |
2241 |
DECLARE_COMPLETION(wait); |
2242 |
|
2243 |
sreq->sr_request->waiting = &wait; |
2244 |
sreq->sr_request->rq_status = RQ_SCSI_BUSY; |
2245 |
sreq->sr_request->end_io = scsi_protect_wait_req_end_io; |
2246 |
scsi_do_req(sreq, cmnd, buffer, bufflen, scsi_protect_wait_done, |
2247 |
timeout, retries); |
2248 |
wait_for_completion(&wait); |
2249 |
sreq->sr_request->waiting = NULL; |
2250 |
if (sreq->sr_request->rq_status != RQ_SCSI_DONE) |
2251 |
sreq->sr_result |= (DRIVER_ERROR << 24); |
2252 |
|
2253 |
__scsi_release_request(sreq); |
2254 |
} |
2255 |
|
2256 |
/* |
2257 |
* scsi_unprotect_queue() |
2258 |
* - release the queue that was previously blocked |
2259 |
*/ |
2260 |
int scsi_unprotect_queue(request_queue_t *q){ |
2261 |
|
2262 |
struct scsi_device *sdev = q->queuedata; |
2263 |
int rc = 0, pending = 0; |
2264 |
u8 scsi_cmd[MAX_COMMAND_SIZE]; |
2265 |
struct scsi_sense_hdr sshdr; |
2266 |
|
2267 |
if (sdev->sdev_state != SDEV_BLOCK) |
2268 |
return -ENXIO; |
2269 |
|
2270 |
/* Are there any pending jobs on the queue? */ |
2271 |
pending = ((q->rq.count[READ] > 0) || (q->rq.count[WRITE] > 0)) ? 1 : 0; |
2272 |
|
2273 |
rc = scsi_internal_device_unblock(sdev); |
2274 |
if (rc) |
2275 |
return rc; |
2276 |
|
2277 |
if (!pending) { |
2278 |
printk(KERN_DEBUG "scsi_unprotect_queue(): No pending I/O, re-enabling power management..\n"); |
2279 |
|
2280 |
memset(scsi_cmd, 0, sizeof(scsi_cmd)); |
2281 |
scsi_cmd[0] = ATA_16; |
2282 |
scsi_cmd[1] = (3 << 1); /* Non-data */ |
2283 |
/* scsi_cmd[2] is already 0 -- no off.line, cc, or data xfer */ |
2284 |
scsi_cmd[14] = 0xe5; /* CHECK_POWER_MODE1 */ |
2285 |
|
2286 |
/* Good values for timeout and retries? Values below |
2287 |
from scsi_ioctl_send_command() for default case... */ |
2288 |
if (scsi_execute_req(sdev, scsi_cmd, DMA_NONE, NULL, 0, &sshdr, |
2289 |
(10*HZ), 5)) |
2290 |
rc = -EIO; |
2291 |
} |
2292 |
return rc; |
2293 |
} |
2294 |
EXPORT_SYMBOL_GPL(scsi_unprotect_queue); |
2295 |
|
2296 |
/* |
2297 |
* scsi_protect_queue() |
2298 |
* - build and issue the park/standby command.. |
2299 |
* - queue is blocked during command completion handler |
2300 |
*/ |
2301 |
int scsi_protect_queue(request_queue_t *q, int unload) |
2302 |
{ |
2303 |
struct scsi_device *sdev = q->queuedata; |
2304 |
int rc = 0; |
2305 |
u8 scsi_cmd[MAX_COMMAND_SIZE]; |
2306 |
u8 args[7]; |
2307 |
struct scsi_request *sreq; |
2308 |
unsigned char *sb, *desc; |
2309 |
|
2310 |
if (sdev->sdev_state != SDEV_RUNNING) |
2311 |
return -ENXIO; |
2312 |
|
2313 |
memset(args, 0, sizeof(args)); |
2314 |
|
2315 |
if (unload) { |
2316 |
args[0] = 0xe1; |
2317 |
args[1] = 0x44; |
2318 |
args[3] = 0x4c; |
2319 |
args[4] = 0x4e; |
2320 |
args[5] = 0x55; |
2321 |
} else |
2322 |
args[0] = 0xe0; |
2323 |
|
2324 |
memset(scsi_cmd, 0, sizeof(scsi_cmd)); |
2325 |
scsi_cmd[0] = ATA_16; |
2326 |
scsi_cmd[1] = (3 << 1); /* Non-data */ |
2327 |
scsi_cmd[2] = 0x20; /* no off.line, or data xfer, request cc */ |
2328 |
scsi_cmd[4] = args[1]; |
2329 |
scsi_cmd[6] = args[2]; |
2330 |
scsi_cmd[8] = args[3]; |
2331 |
scsi_cmd[10] = args[4]; |
2332 |
scsi_cmd[12] = args[5]; |
2333 |
scsi_cmd[14] = args[0]; |
2334 |
|
2335 |
sreq = scsi_allocate_request(sdev, GFP_KERNEL); |
2336 |
if (!sreq) { |
2337 |
rc = -EINTR; |
2338 |
goto error; |
2339 |
} |
2340 |
|
2341 |
sreq->sr_data_direction = DMA_NONE; |
2342 |
|
2343 |
scsi_protect_wait_req(sreq, scsi_cmd, NULL, 0, (10*HZ), 5); |
2344 |
|
2345 |
if (!sreq->sr_result == ((DRIVER_SENSE << 24) + SAM_STAT_CHECK_CONDITION)) { |
2346 |
printk(KERN_DEBUG "scsi_protect_queue(): head NOT parked!..\n"); |
2347 |
scsi_unprotect_queue(q); /* just in case we still managed to block */ |
2348 |
rc = -EIO; |
2349 |
goto error; |
2350 |
} |
2351 |
|
2352 |
sb = sreq->sr_sense_buffer; |
2353 |
desc = sb + 8; |
2354 |
|
2355 |
/* Retrieve data from check condition */ |
2356 |
args[1] = desc[3]; |
2357 |
args[2] = desc[5]; |
2358 |
args[3] = desc[7]; |
2359 |
args[4] = desc[9]; |
2360 |
args[5] = desc[11]; |
2361 |
args[0] = desc[13]; |
2362 |
|
2363 |
if (unload) { |
2364 |
if (args[3] == 0xc4) |
2365 |
printk(KERN_DEBUG "scsi_protect_queue(): head parked..\n"); |
2366 |
else { |
2367 |
/* error parking the head */ |
2368 |
printk(KERN_DEBUG "scsi_protect_queue(): head NOT parked!..\n"); |
2369 |
rc = -EIO; |
2370 |
scsi_unprotect_queue(q); |
2371 |
} |
2372 |
} else |
2373 |
printk(KERN_DEBUG "scsi_protect_queue(): head park not requested, used standby!..\n"); |
2374 |
|
2375 |
error: |
2376 |
scsi_release_request(sreq); |
2377 |
return rc; |
2378 |
} |
2379 |
EXPORT_SYMBOL_GPL(scsi_protect_queue); |
2194 |
|
2380 |
|
2195 |
/** |
2381 |
/** |
2196 |
* scsi_kmap_atomic_sg - find and atomically map an sg-elemnt |
2382 |
* scsi_kmap_atomic_sg - find and atomically map an sg-elemnt |