diff options
Diffstat (limited to 'drivers/scsi/ide-scsi.c')
-rw-r--r-- | drivers/scsi/ide-scsi.c | 302 |
1 files changed, 80 insertions, 222 deletions
diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index 44d8d5163a1a..683bce375c74 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c | |||
@@ -60,6 +60,13 @@ | |||
60 | 60 | ||
61 | #define IDESCSI_DEBUG_LOG 0 | 61 | #define IDESCSI_DEBUG_LOG 0 |
62 | 62 | ||
63 | #if IDESCSI_DEBUG_LOG | ||
64 | #define debug_log(fmt, args...) \ | ||
65 | printk(KERN_INFO "ide-scsi: " fmt, ## args) | ||
66 | #else | ||
67 | #define debug_log(fmt, args...) do {} while (0) | ||
68 | #endif | ||
69 | |||
63 | /* | 70 | /* |
64 | * SCSI command transformation layer | 71 | * SCSI command transformation layer |
65 | */ | 72 | */ |
@@ -129,14 +136,15 @@ static inline idescsi_scsi_t *drive_to_idescsi(ide_drive_t *ide_drive) | |||
129 | #define IDESCSI_PC_RQ 90 | 136 | #define IDESCSI_PC_RQ 90 |
130 | 137 | ||
131 | /* | 138 | /* |
132 | * PIO data transfer routines using the scatter gather table. | 139 | * PIO data transfer routine using the scatter gather table. |
133 | */ | 140 | */ |
134 | static void idescsi_input_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, | 141 | static void ide_scsi_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, |
135 | unsigned int bcount) | 142 | unsigned int bcount, int write) |
136 | { | 143 | { |
137 | ide_hwif_t *hwif = drive->hwif; | 144 | ide_hwif_t *hwif = drive->hwif; |
138 | int count; | 145 | xfer_func_t *xf = write ? hwif->output_data : hwif->input_data; |
139 | char *buf; | 146 | char *buf; |
147 | int count; | ||
140 | 148 | ||
141 | while (bcount) { | 149 | while (bcount) { |
142 | count = min(pc->sg->length - pc->b_count, bcount); | 150 | count = min(pc->sg->length - pc->b_count, bcount); |
@@ -145,13 +153,13 @@ static void idescsi_input_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, | |||
145 | 153 | ||
146 | local_irq_save(flags); | 154 | local_irq_save(flags); |
147 | buf = kmap_atomic(sg_page(pc->sg), KM_IRQ0) + | 155 | buf = kmap_atomic(sg_page(pc->sg), KM_IRQ0) + |
148 | pc->sg->offset; | 156 | pc->sg->offset; |
149 | hwif->input_data(drive, NULL, buf + pc->b_count, count); | 157 | xf(drive, NULL, buf + pc->b_count, count); |
150 | kunmap_atomic(buf - pc->sg->offset, KM_IRQ0); | 158 | kunmap_atomic(buf - pc->sg->offset, KM_IRQ0); |
151 | local_irq_restore(flags); | 159 | local_irq_restore(flags); |
152 | } else { | 160 | } else { |
153 | buf = sg_virt(pc->sg); | 161 | buf = sg_virt(pc->sg); |
154 | hwif->input_data(drive, NULL, buf + pc->b_count, count); | 162 | xf(drive, NULL, buf + pc->b_count, count); |
155 | } | 163 | } |
156 | bcount -= count; pc->b_count += count; | 164 | bcount -= count; pc->b_count += count; |
157 | if (pc->b_count == pc->sg->length) { | 165 | if (pc->b_count == pc->sg->length) { |
@@ -163,51 +171,34 @@ static void idescsi_input_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, | |||
163 | } | 171 | } |
164 | 172 | ||
165 | if (bcount) { | 173 | if (bcount) { |
166 | printk (KERN_ERR "ide-scsi: scatter gather table too small, discarding data\n"); | 174 | printk(KERN_ERR "%s: scatter gather table too small, %s\n", |
167 | ide_pad_transfer(drive, 0, bcount); | 175 | drive->name, write ? "padding with zeros" |
176 | : "discarding data"); | ||
177 | ide_pad_transfer(drive, write, bcount); | ||
168 | } | 178 | } |
169 | } | 179 | } |
170 | 180 | ||
171 | static void idescsi_output_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, | 181 | static void ide_scsi_hex_dump(u8 *data, int len) |
172 | unsigned int bcount) | ||
173 | { | 182 | { |
174 | ide_hwif_t *hwif = drive->hwif; | 183 | print_hex_dump(KERN_CONT, "", DUMP_PREFIX_NONE, 16, 1, data, len, 0); |
175 | int count; | 184 | } |
176 | char *buf; | ||
177 | 185 | ||
178 | while (bcount) { | 186 | static int idescsi_end_request(ide_drive_t *, int, int); |
179 | count = min(pc->sg->length - pc->b_count, bcount); | ||
180 | if (PageHighMem(sg_page(pc->sg))) { | ||
181 | unsigned long flags; | ||
182 | 187 | ||
183 | local_irq_save(flags); | 188 | static void ide_scsi_callback(ide_drive_t *drive) |
184 | buf = kmap_atomic(sg_page(pc->sg), KM_IRQ0) + | 189 | { |
185 | pc->sg->offset; | 190 | idescsi_scsi_t *scsi = drive_to_idescsi(drive); |
186 | hwif->output_data(drive, NULL, buf + pc->b_count, count); | 191 | struct ide_atapi_pc *pc = scsi->pc; |
187 | kunmap_atomic(buf - pc->sg->offset, KM_IRQ0); | ||
188 | local_irq_restore(flags); | ||
189 | } else { | ||
190 | buf = sg_virt(pc->sg); | ||
191 | hwif->output_data(drive, NULL, buf + pc->b_count, count); | ||
192 | } | ||
193 | bcount -= count; pc->b_count += count; | ||
194 | if (pc->b_count == pc->sg->length) { | ||
195 | if (!--pc->sg_cnt) | ||
196 | break; | ||
197 | pc->sg = sg_next(pc->sg); | ||
198 | pc->b_count = 0; | ||
199 | } | ||
200 | } | ||
201 | 192 | ||
202 | if (bcount) { | 193 | if (pc->flags & PC_FLAG_TIMEDOUT) |
203 | printk (KERN_ERR "ide-scsi: scatter gather table too small, padding with zeros\n"); | 194 | debug_log("%s: got timed out packet %lu at %lu\n", __func__, |
204 | ide_pad_transfer(drive, 1, bcount); | 195 | pc->scsi_cmd->serial_number, jiffies); |
205 | } | 196 | /* end this request now - scsi should retry it*/ |
206 | } | 197 | else if (test_bit(IDESCSI_LOG_CMD, &scsi->log)) |
198 | printk(KERN_INFO "Packet command completed, %d bytes" | ||
199 | " transferred\n", pc->xferred); | ||
207 | 200 | ||
208 | static void ide_scsi_hex_dump(u8 *data, int len) | 201 | idescsi_end_request(drive, 1, 0); |
209 | { | ||
210 | print_hex_dump(KERN_CONT, "", DUMP_PREFIX_NONE, 16, 1, data, len, 0); | ||
211 | } | 202 | } |
212 | 203 | ||
213 | static int idescsi_check_condition(ide_drive_t *drive, | 204 | static int idescsi_check_condition(ide_drive_t *drive, |
@@ -228,14 +219,16 @@ static int idescsi_check_condition(ide_drive_t *drive, | |||
228 | kfree(pc); | 219 | kfree(pc); |
229 | return -ENOMEM; | 220 | return -ENOMEM; |
230 | } | 221 | } |
231 | ide_init_drive_cmd(rq); | 222 | blk_rq_init(NULL, rq); |
232 | rq->special = (char *) pc; | 223 | rq->special = (char *) pc; |
233 | pc->rq = rq; | 224 | pc->rq = rq; |
234 | pc->buf = buf; | 225 | pc->buf = buf; |
235 | pc->c[0] = REQUEST_SENSE; | 226 | pc->c[0] = REQUEST_SENSE; |
236 | pc->c[4] = pc->req_xfer = pc->buf_size = SCSI_SENSE_BUFFERSIZE; | 227 | pc->c[4] = pc->req_xfer = pc->buf_size = SCSI_SENSE_BUFFERSIZE; |
237 | rq->cmd_type = REQ_TYPE_SENSE; | 228 | rq->cmd_type = REQ_TYPE_SENSE; |
229 | rq->cmd_flags |= REQ_PREEMPT; | ||
238 | pc->timeout = jiffies + WAIT_READY; | 230 | pc->timeout = jiffies + WAIT_READY; |
231 | pc->callback = ide_scsi_callback; | ||
239 | /* NOTE! Save the failed packet command in "rq->buffer" */ | 232 | /* NOTE! Save the failed packet command in "rq->buffer" */ |
240 | rq->buffer = (void *) failed_cmd->special; | 233 | rq->buffer = (void *) failed_cmd->special; |
241 | pc->scsi_cmd = ((struct ide_atapi_pc *) failed_cmd->special)->scsi_cmd; | 234 | pc->scsi_cmd = ((struct ide_atapi_pc *) failed_cmd->special)->scsi_cmd; |
@@ -244,11 +237,10 @@ static int idescsi_check_condition(ide_drive_t *drive, | |||
244 | ide_scsi_hex_dump(pc->c, 6); | 237 | ide_scsi_hex_dump(pc->c, 6); |
245 | } | 238 | } |
246 | rq->rq_disk = scsi->disk; | 239 | rq->rq_disk = scsi->disk; |
247 | return ide_do_drive_cmd(drive, rq, ide_preempt); | 240 | ide_do_drive_cmd(drive, rq); |
241 | return 0; | ||
248 | } | 242 | } |
249 | 243 | ||
250 | static int idescsi_end_request(ide_drive_t *, int, int); | ||
251 | |||
252 | static ide_startstop_t | 244 | static ide_startstop_t |
253 | idescsi_atapi_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err) | 245 | idescsi_atapi_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err) |
254 | { | 246 | { |
@@ -256,7 +248,7 @@ idescsi_atapi_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err) | |||
256 | 248 | ||
257 | if (ide_read_status(drive) & (BUSY_STAT | DRQ_STAT)) | 249 | if (ide_read_status(drive) & (BUSY_STAT | DRQ_STAT)) |
258 | /* force an abort */ | 250 | /* force an abort */ |
259 | hwif->OUTBSYNC(drive, WIN_IDLEIMMEDIATE, | 251 | hwif->OUTBSYNC(hwif, WIN_IDLEIMMEDIATE, |
260 | hwif->io_ports.command_addr); | 252 | hwif->io_ports.command_addr); |
261 | 253 | ||
262 | rq->errors++; | 254 | rq->errors++; |
@@ -269,10 +261,9 @@ idescsi_atapi_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err) | |||
269 | static ide_startstop_t | 261 | static ide_startstop_t |
270 | idescsi_atapi_abort(ide_drive_t *drive, struct request *rq) | 262 | idescsi_atapi_abort(ide_drive_t *drive, struct request *rq) |
271 | { | 263 | { |
272 | #if IDESCSI_DEBUG_LOG | 264 | debug_log("%s called for %lu\n", __func__, |
273 | printk(KERN_WARNING "idescsi_atapi_abort called for %lu\n", | ||
274 | ((struct ide_atapi_pc *) rq->special)->scsi_cmd->serial_number); | 265 | ((struct ide_atapi_pc *) rq->special)->scsi_cmd->serial_number); |
275 | #endif | 266 | |
276 | rq->errors |= ERROR_MAX; | 267 | rq->errors |= ERROR_MAX; |
277 | 268 | ||
278 | idescsi_end_request(drive, 0, 0); | 269 | idescsi_end_request(drive, 0, 0); |
@@ -351,9 +342,9 @@ static int idescsi_expiry(ide_drive_t *drive) | |||
351 | idescsi_scsi_t *scsi = drive_to_idescsi(drive); | 342 | idescsi_scsi_t *scsi = drive_to_idescsi(drive); |
352 | struct ide_atapi_pc *pc = scsi->pc; | 343 | struct ide_atapi_pc *pc = scsi->pc; |
353 | 344 | ||
354 | #if IDESCSI_DEBUG_LOG | 345 | debug_log("%s called for %lu at %lu\n", __func__, |
355 | printk(KERN_WARNING "idescsi_expiry called for %lu at %lu\n", pc->scsi_cmd->serial_number, jiffies); | 346 | pc->scsi_cmd->serial_number, jiffies); |
356 | #endif | 347 | |
357 | pc->flags |= PC_FLAG_TIMEDOUT; | 348 | pc->flags |= PC_FLAG_TIMEDOUT; |
358 | 349 | ||
359 | return 0; /* we do not want the ide subsystem to retry */ | 350 | return 0; /* we do not want the ide subsystem to retry */ |
@@ -365,141 +356,19 @@ static int idescsi_expiry(ide_drive_t *drive) | |||
365 | static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive) | 356 | static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive) |
366 | { | 357 | { |
367 | idescsi_scsi_t *scsi = drive_to_idescsi(drive); | 358 | idescsi_scsi_t *scsi = drive_to_idescsi(drive); |
368 | ide_hwif_t *hwif = drive->hwif; | ||
369 | struct ide_atapi_pc *pc = scsi->pc; | 359 | struct ide_atapi_pc *pc = scsi->pc; |
370 | struct request *rq = pc->rq; | ||
371 | unsigned int temp; | ||
372 | u16 bcount; | ||
373 | u8 stat, ireason; | ||
374 | |||
375 | #if IDESCSI_DEBUG_LOG | ||
376 | printk (KERN_INFO "ide-scsi: Reached idescsi_pc_intr interrupt handler\n"); | ||
377 | #endif /* IDESCSI_DEBUG_LOG */ | ||
378 | |||
379 | if (pc->flags & PC_FLAG_TIMEDOUT) { | ||
380 | #if IDESCSI_DEBUG_LOG | ||
381 | printk(KERN_WARNING "idescsi_pc_intr: got timed out packet %lu at %lu\n", | ||
382 | pc->scsi_cmd->serial_number, jiffies); | ||
383 | #endif | ||
384 | /* end this request now - scsi should retry it*/ | ||
385 | idescsi_end_request (drive, 1, 0); | ||
386 | return ide_stopped; | ||
387 | } | ||
388 | if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) { | ||
389 | pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS; | ||
390 | #if IDESCSI_DEBUG_LOG | ||
391 | printk ("ide-scsi: %s: DMA complete\n", drive->name); | ||
392 | #endif /* IDESCSI_DEBUG_LOG */ | ||
393 | pc->xferred = pc->req_xfer; | ||
394 | (void)hwif->dma_ops->dma_end(drive); | ||
395 | } | ||
396 | |||
397 | /* Clear the interrupt */ | ||
398 | stat = ide_read_status(drive); | ||
399 | |||
400 | if ((stat & DRQ_STAT) == 0) { | ||
401 | /* No more interrupts */ | ||
402 | if (test_bit(IDESCSI_LOG_CMD, &scsi->log)) | ||
403 | printk(KERN_INFO "Packet command completed, %d bytes" | ||
404 | " transferred\n", pc->xferred); | ||
405 | local_irq_enable_in_hardirq(); | ||
406 | if (stat & ERR_STAT) | ||
407 | rq->errors++; | ||
408 | idescsi_end_request (drive, 1, 0); | ||
409 | return ide_stopped; | ||
410 | } | ||
411 | bcount = (hwif->INB(hwif->io_ports.lbah_addr) << 8) | | ||
412 | hwif->INB(hwif->io_ports.lbam_addr); | ||
413 | ireason = hwif->INB(hwif->io_ports.nsect_addr); | ||
414 | |||
415 | if (ireason & CD) { | ||
416 | printk(KERN_ERR "ide-scsi: CoD != 0 in idescsi_pc_intr\n"); | ||
417 | return ide_do_reset (drive); | ||
418 | } | ||
419 | if (ireason & IO) { | ||
420 | temp = pc->xferred + bcount; | ||
421 | if (temp > pc->req_xfer) { | ||
422 | if (temp > pc->buf_size) { | ||
423 | printk(KERN_ERR "ide-scsi: The scsi wants to " | ||
424 | "send us more data than expected " | ||
425 | "- discarding data\n"); | ||
426 | temp = pc->buf_size - pc->xferred; | ||
427 | if (temp) { | ||
428 | pc->flags &= ~PC_FLAG_WRITING; | ||
429 | if (pc->sg) | ||
430 | idescsi_input_buffers(drive, pc, | ||
431 | temp); | ||
432 | else | ||
433 | hwif->input_data(drive, NULL, | ||
434 | pc->cur_pos, temp); | ||
435 | printk(KERN_ERR "ide-scsi: transferred" | ||
436 | " %d of %d bytes\n", | ||
437 | temp, bcount); | ||
438 | } | ||
439 | pc->xferred += temp; | ||
440 | pc->cur_pos += temp; | ||
441 | ide_pad_transfer(drive, 0, bcount - temp); | ||
442 | ide_set_handler(drive, &idescsi_pc_intr, get_timeout(pc), idescsi_expiry); | ||
443 | return ide_started; | ||
444 | } | ||
445 | #if IDESCSI_DEBUG_LOG | ||
446 | printk (KERN_NOTICE "ide-scsi: The scsi wants to send us more data than expected - allowing transfer\n"); | ||
447 | #endif /* IDESCSI_DEBUG_LOG */ | ||
448 | } | ||
449 | } | ||
450 | if (ireason & IO) { | ||
451 | pc->flags &= ~PC_FLAG_WRITING; | ||
452 | if (pc->sg) | ||
453 | idescsi_input_buffers(drive, pc, bcount); | ||
454 | else | ||
455 | hwif->input_data(drive, NULL, pc->cur_pos, bcount); | ||
456 | } else { | ||
457 | pc->flags |= PC_FLAG_WRITING; | ||
458 | if (pc->sg) | ||
459 | idescsi_output_buffers(drive, pc, bcount); | ||
460 | else | ||
461 | hwif->output_data(drive, NULL, pc->cur_pos, bcount); | ||
462 | } | ||
463 | /* Update the current position */ | ||
464 | pc->xferred += bcount; | ||
465 | pc->cur_pos += bcount; | ||
466 | 360 | ||
467 | /* And set the interrupt handler again */ | 361 | return ide_pc_intr(drive, pc, idescsi_pc_intr, get_timeout(pc), |
468 | ide_set_handler(drive, &idescsi_pc_intr, get_timeout(pc), idescsi_expiry); | 362 | idescsi_expiry, NULL, NULL, NULL, |
469 | return ide_started; | 363 | ide_scsi_io_buffers); |
470 | } | 364 | } |
471 | 365 | ||
472 | static ide_startstop_t idescsi_transfer_pc(ide_drive_t *drive) | 366 | static ide_startstop_t idescsi_transfer_pc(ide_drive_t *drive) |
473 | { | 367 | { |
474 | ide_hwif_t *hwif = drive->hwif; | ||
475 | idescsi_scsi_t *scsi = drive_to_idescsi(drive); | 368 | idescsi_scsi_t *scsi = drive_to_idescsi(drive); |
476 | struct ide_atapi_pc *pc = scsi->pc; | ||
477 | ide_startstop_t startstop; | ||
478 | u8 ireason; | ||
479 | 369 | ||
480 | if (ide_wait_stat(&startstop,drive,DRQ_STAT,BUSY_STAT,WAIT_READY)) { | 370 | return ide_transfer_pc(drive, scsi->pc, idescsi_pc_intr, |
481 | printk(KERN_ERR "ide-scsi: Strange, packet command " | 371 | get_timeout(scsi->pc), idescsi_expiry); |
482 | "initiated yet DRQ isn't asserted\n"); | ||
483 | return startstop; | ||
484 | } | ||
485 | ireason = hwif->INB(hwif->io_ports.nsect_addr); | ||
486 | if ((ireason & CD) == 0 || (ireason & IO)) { | ||
487 | printk(KERN_ERR "ide-scsi: (IO,CoD) != (0,1) while " | ||
488 | "issuing a packet command\n"); | ||
489 | return ide_do_reset (drive); | ||
490 | } | ||
491 | BUG_ON(HWGROUP(drive)->handler != NULL); | ||
492 | /* Set the interrupt routine */ | ||
493 | ide_set_handler(drive, &idescsi_pc_intr, get_timeout(pc), idescsi_expiry); | ||
494 | |||
495 | /* Send the actual packet */ | ||
496 | hwif->output_data(drive, NULL, scsi->pc->c, 12); | ||
497 | |||
498 | if (pc->flags & PC_FLAG_DMA_OK) { | ||
499 | pc->flags |= PC_FLAG_DMA_IN_PROGRESS; | ||
500 | hwif->dma_ops->dma_start(drive); | ||
501 | } | ||
502 | return ide_started; | ||
503 | } | 372 | } |
504 | 373 | ||
505 | static inline int idescsi_set_direction(struct ide_atapi_pc *pc) | 374 | static inline int idescsi_set_direction(struct ide_atapi_pc *pc) |
@@ -545,38 +414,12 @@ static ide_startstop_t idescsi_issue_pc(ide_drive_t *drive, | |||
545 | struct ide_atapi_pc *pc) | 414 | struct ide_atapi_pc *pc) |
546 | { | 415 | { |
547 | idescsi_scsi_t *scsi = drive_to_idescsi(drive); | 416 | idescsi_scsi_t *scsi = drive_to_idescsi(drive); |
548 | ide_hwif_t *hwif = drive->hwif; | ||
549 | u16 bcount; | ||
550 | u8 dma = 0; | ||
551 | 417 | ||
552 | /* Set the current packet command */ | 418 | /* Set the current packet command */ |
553 | scsi->pc = pc; | 419 | scsi->pc = pc; |
554 | /* We haven't transferred any data yet */ | ||
555 | pc->xferred = 0; | ||
556 | pc->cur_pos = pc->buf; | ||
557 | /* Request to transfer the entire buffer at once */ | ||
558 | bcount = min(pc->req_xfer, 63 * 1024); | ||
559 | |||
560 | if (drive->using_dma && !idescsi_map_sg(drive, pc)) { | ||
561 | hwif->sg_mapped = 1; | ||
562 | dma = !hwif->dma_ops->dma_setup(drive); | ||
563 | hwif->sg_mapped = 0; | ||
564 | } | ||
565 | |||
566 | ide_pktcmd_tf_load(drive, IDE_TFLAG_NO_SELECT_MASK, bcount, dma); | ||
567 | 420 | ||
568 | if (dma) | 421 | return ide_issue_pc(drive, pc, idescsi_transfer_pc, |
569 | pc->flags |= PC_FLAG_DMA_OK; | 422 | get_timeout(pc), idescsi_expiry); |
570 | |||
571 | if (test_bit(IDESCSI_DRQ_INTERRUPT, &scsi->flags)) { | ||
572 | ide_execute_command(drive, WIN_PACKETCMD, &idescsi_transfer_pc, | ||
573 | get_timeout(pc), idescsi_expiry); | ||
574 | return ide_started; | ||
575 | } else { | ||
576 | /* Issue the packet command */ | ||
577 | ide_execute_pkt_cmd(drive); | ||
578 | return idescsi_transfer_pc(drive); | ||
579 | } | ||
580 | } | 423 | } |
581 | 424 | ||
582 | /* | 425 | /* |
@@ -584,14 +427,22 @@ static ide_startstop_t idescsi_issue_pc(ide_drive_t *drive, | |||
584 | */ | 427 | */ |
585 | static ide_startstop_t idescsi_do_request (ide_drive_t *drive, struct request *rq, sector_t block) | 428 | static ide_startstop_t idescsi_do_request (ide_drive_t *drive, struct request *rq, sector_t block) |
586 | { | 429 | { |
587 | #if IDESCSI_DEBUG_LOG | 430 | debug_log("dev: %s, cmd: %x, errors: %d\n", rq->rq_disk->disk_name, |
588 | printk (KERN_INFO "dev: %s, cmd: %x, errors: %d\n", rq->rq_disk->disk_name,rq->cmd[0],rq->errors); | 431 | rq->cmd[0], rq->errors); |
589 | printk (KERN_INFO "sector: %ld, nr_sectors: %ld, current_nr_sectors: %d\n",rq->sector,rq->nr_sectors,rq->current_nr_sectors); | 432 | debug_log("sector: %ld, nr_sectors: %ld, current_nr_sectors: %d\n", |
590 | #endif /* IDESCSI_DEBUG_LOG */ | 433 | rq->sector, rq->nr_sectors, rq->current_nr_sectors); |
591 | 434 | ||
592 | if (blk_sense_request(rq) || blk_special_request(rq)) { | 435 | if (blk_sense_request(rq) || blk_special_request(rq)) { |
593 | return idescsi_issue_pc(drive, | 436 | struct ide_atapi_pc *pc = (struct ide_atapi_pc *)rq->special; |
594 | (struct ide_atapi_pc *) rq->special); | 437 | idescsi_scsi_t *scsi = drive_to_idescsi(drive); |
438 | |||
439 | if (test_bit(IDESCSI_DRQ_INTERRUPT, &scsi->flags)) | ||
440 | pc->flags |= PC_FLAG_DRQ_INTERRUPT; | ||
441 | |||
442 | if (drive->using_dma && !idescsi_map_sg(drive, pc)) | ||
443 | pc->flags |= PC_FLAG_DMA_OK; | ||
444 | |||
445 | return idescsi_issue_pc(drive, pc); | ||
595 | } | 446 | } |
596 | blk_dump_rq_flags(rq, "ide-scsi: unsup command"); | 447 | blk_dump_rq_flags(rq, "ide-scsi: unsup command"); |
597 | idescsi_end_request (drive, 0, 0); | 448 | idescsi_end_request (drive, 0, 0); |
@@ -646,6 +497,8 @@ static void ide_scsi_remove(ide_drive_t *drive) | |||
646 | put_disk(g); | 497 | put_disk(g); |
647 | 498 | ||
648 | ide_scsi_put(scsi); | 499 | ide_scsi_put(scsi); |
500 | |||
501 | drive->scsi = 0; | ||
649 | } | 502 | } |
650 | 503 | ||
651 | static int ide_scsi_probe(ide_drive_t *); | 504 | static int ide_scsi_probe(ide_drive_t *); |
@@ -765,6 +618,8 @@ static int idescsi_queue (struct scsi_cmnd *cmd, | |||
765 | 618 | ||
766 | memset (pc->c, 0, 12); | 619 | memset (pc->c, 0, 12); |
767 | pc->flags = 0; | 620 | pc->flags = 0; |
621 | if (cmd->sc_data_direction == DMA_TO_DEVICE) | ||
622 | pc->flags |= PC_FLAG_WRITING; | ||
768 | pc->rq = rq; | 623 | pc->rq = rq; |
769 | memcpy (pc->c, cmd->cmnd, cmd->cmd_len); | 624 | memcpy (pc->c, cmd->cmnd, cmd->cmd_len); |
770 | pc->buf = NULL; | 625 | pc->buf = NULL; |
@@ -775,6 +630,7 @@ static int idescsi_queue (struct scsi_cmnd *cmd, | |||
775 | pc->scsi_cmd = cmd; | 630 | pc->scsi_cmd = cmd; |
776 | pc->done = done; | 631 | pc->done = done; |
777 | pc->timeout = jiffies + cmd->timeout_per_command; | 632 | pc->timeout = jiffies + cmd->timeout_per_command; |
633 | pc->callback = ide_scsi_callback; | ||
778 | 634 | ||
779 | if (test_bit(IDESCSI_LOG_CMD, &scsi->log)) { | 635 | if (test_bit(IDESCSI_LOG_CMD, &scsi->log)) { |
780 | printk ("ide-scsi: %s: que %lu, cmd = ", drive->name, cmd->serial_number); | 636 | printk ("ide-scsi: %s: que %lu, cmd = ", drive->name, cmd->serial_number); |
@@ -785,12 +641,11 @@ static int idescsi_queue (struct scsi_cmnd *cmd, | |||
785 | } | 641 | } |
786 | } | 642 | } |
787 | 643 | ||
788 | ide_init_drive_cmd (rq); | 644 | blk_rq_init(NULL, rq); |
789 | rq->special = (char *) pc; | 645 | rq->special = (char *) pc; |
790 | rq->cmd_type = REQ_TYPE_SPECIAL; | 646 | rq->cmd_type = REQ_TYPE_SPECIAL; |
791 | spin_unlock_irq(host->host_lock); | 647 | spin_unlock_irq(host->host_lock); |
792 | rq->rq_disk = scsi->disk; | 648 | blk_execute_rq_nowait(drive->queue, scsi->disk, rq, 0, NULL); |
793 | (void) ide_do_drive_cmd (drive, rq, ide_end); | ||
794 | spin_lock_irq(host->host_lock); | 649 | spin_lock_irq(host->host_lock); |
795 | return 0; | 650 | return 0; |
796 | abort: | 651 | abort: |
@@ -985,6 +840,8 @@ static int ide_scsi_probe(ide_drive_t *drive) | |||
985 | !(host = scsi_host_alloc(&idescsi_template,sizeof(idescsi_scsi_t)))) | 840 | !(host = scsi_host_alloc(&idescsi_template,sizeof(idescsi_scsi_t)))) |
986 | return -ENODEV; | 841 | return -ENODEV; |
987 | 842 | ||
843 | drive->scsi = 1; | ||
844 | |||
988 | g = alloc_disk(1 << PARTN_BITS); | 845 | g = alloc_disk(1 << PARTN_BITS); |
989 | if (!g) | 846 | if (!g) |
990 | goto out_host_put; | 847 | goto out_host_put; |
@@ -993,10 +850,10 @@ static int ide_scsi_probe(ide_drive_t *drive) | |||
993 | 850 | ||
994 | host->max_id = 1; | 851 | host->max_id = 1; |
995 | 852 | ||
996 | #if IDESCSI_DEBUG_LOG | ||
997 | if (drive->id->last_lun) | 853 | if (drive->id->last_lun) |
998 | printk(KERN_NOTICE "%s: id->last_lun=%u\n", drive->name, drive->id->last_lun); | 854 | debug_log("%s: id->last_lun=%u\n", drive->name, |
999 | #endif | 855 | drive->id->last_lun); |
856 | |||
1000 | if ((drive->id->last_lun & 0x7) != 7) | 857 | if ((drive->id->last_lun & 0x7) != 7) |
1001 | host->max_lun = (drive->id->last_lun & 0x7) + 1; | 858 | host->max_lun = (drive->id->last_lun & 0x7) + 1; |
1002 | else | 859 | else |
@@ -1025,6 +882,7 @@ static int ide_scsi_probe(ide_drive_t *drive) | |||
1025 | 882 | ||
1026 | put_disk(g); | 883 | put_disk(g); |
1027 | out_host_put: | 884 | out_host_put: |
885 | drive->scsi = 0; | ||
1028 | scsi_host_put(host); | 886 | scsi_host_put(host); |
1029 | return err; | 887 | return err; |
1030 | } | 888 | } |