Subject: [PATCH 00/22] ide: more work on generic ATAPI support


Just some more work on generic ATAPI layer...

- code unifications here and there

- move IDEFLOPPY_IOCTL_FORMAT_* support to a separate file

- ide_pc_intr() no longer requires zillion of arguments

Applies on top of current pata tree, tested with ide-scsi.

diffstat:
drivers/ide/Makefile | 3
drivers/ide/ide-atapi.c | 323 +++++++++++++++--
drivers/ide/ide-floppy.c | 739 ++++++-----------------------------------
drivers/ide/ide-floppy.h | 72 +++
drivers/ide/ide-floppy_ioctl.c | 245 +++++++++++++
drivers/ide/ide-tape.c | 396 ++++++---------------
drivers/scsi/ide-scsi.c | 178 ++-------
include/linux/ide.h | 266 +++++++++-----
8 files changed, 1035 insertions(+), 1187 deletions(-)


Subject: [PATCH 01/22] ide-floppy: fixup ide_floppy_io_buffers()

map hwif->sg_{table,nents} on pc->{sg,sg_cnt} (multi-IRQs-per-sg fix)

Cc: Borislav Petkov <[email protected]>
Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
I will fold this into the original patch later.

drivers/ide/ide-floppy.c | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)

Index: b/drivers/ide/ide-floppy.c
===================================================================
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -213,12 +213,11 @@ static void ide_floppy_io_buffers(ide_dr
ide_hwif_t *hwif = drive->hwif;
const struct ide_tp_ops *tp_ops = hwif->tp_ops;
xfer_func_t *xf = direction ? tp_ops->output_data : tp_ops->input_data;
- struct scatterlist *sg = hwif->sg_table;
+ struct scatterlist *sg = pc->sg;
char *buf;
int count, done = 0;

while (bcount) {
-
count = min(sg->length - pc->b_count, bcount);
if (PageHighMem(sg_page(sg))) {
unsigned long flags;
@@ -237,9 +236,9 @@ static void ide_floppy_io_buffers(ide_dr
done += count;

if (pc->b_count == sg->length) {
- if (!--hwif->sg_nents)
+ if (!--pc->sg_cnt)
break;
- sg = sg_next(sg);
+ pc->sg = sg = sg_next(sg);
pc->b_count = 0;
}
}
@@ -576,6 +575,7 @@ static ide_startstop_t idefloppy_do_requ
struct request *rq, sector_t block_s)
{
idefloppy_floppy_t *floppy = drive->driver_data;
+ ide_hwif_t *hwif = drive->hwif;
struct ide_atapi_pc *pc;
unsigned long block = (unsigned long)block_s;

@@ -618,11 +618,14 @@ static ide_startstop_t idefloppy_do_requ
return ide_stopped;
}

- pc->rq = rq;
-
ide_init_sg_cmd(drive, rq);
ide_map_sg(drive, rq);

+ pc->sg = hwif->sg_table;
+ pc->sg_cnt = hwif->sg_nents;
+
+ pc->rq = rq;
+
return idefloppy_issue_pc(drive, pc);
}

Subject: [PATCH 02/22] ide-scsi: cleanup ide_scsi_io_buffers()

Preparation for ide_{floppy,scsi}_io_buffers() unification.

Cc: Borislav Petkov <[email protected]>
Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
drivers/scsi/ide-scsi.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)

Index: b/drivers/scsi/ide-scsi.c
===================================================================
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -139,29 +139,29 @@ static void ide_scsi_io_buffers(ide_driv
ide_hwif_t *hwif = drive->hwif;
const struct ide_tp_ops *tp_ops = hwif->tp_ops;
xfer_func_t *xf = write ? tp_ops->output_data : tp_ops->input_data;
+ struct scatterlist *sg = pc->sg;
char *buf;
int count;

while (bcount) {
- count = min(pc->sg->length - pc->b_count, bcount);
- if (PageHighMem(sg_page(pc->sg))) {
+ count = min(sg->length - pc->b_count, bcount);
+ if (PageHighMem(sg_page(sg))) {
unsigned long flags;

local_irq_save(flags);
- buf = kmap_atomic(sg_page(pc->sg), KM_IRQ0) +
- pc->sg->offset;
+ buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
xf(drive, NULL, buf + pc->b_count, count);
- kunmap_atomic(buf - pc->sg->offset, KM_IRQ0);
+ kunmap_atomic(buf - sg->offset, KM_IRQ0);
local_irq_restore(flags);
} else {
- buf = sg_virt(pc->sg);
+ buf = sg_virt(sg);
xf(drive, NULL, buf + pc->b_count, count);
}
bcount -= count; pc->b_count += count;
- if (pc->b_count == pc->sg->length) {
+ if (pc->b_count == sg->length) {
if (!--pc->sg_cnt)
break;
- pc->sg = sg_next(pc->sg);
+ pc->sg = sg = sg_next(sg);
pc->b_count = 0;
}
}

Subject: [PATCH 03/22] ide: add ide_io_buffers() helper

* Make ->io_buffers method return number of bytes transferred.

* Use ide_end_request() instead of idefloppy_end_request()
in ide_floppy_io_buffers() and then move the call out to
ide_pc_intr().

* Add ide_io_buffers() helper and convert ide-{floppy,scsi}.c
to use it instead of ide*_io_buffers().

There should be no functional changes caused by this patch.

Cc: Borislav Petkov <[email protected]>
Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
drivers/ide/ide-atapi.c | 63 ++++++++++++++++++++++++++++++++++++++++++++---
drivers/ide/ide-floppy.c | 47 -----------------------------------
drivers/ide/ide-tape.c | 4 ++
drivers/scsi/ide-scsi.c | 46 ----------------------------------
include/linux/ide.h | 4 ++
5 files changed, 67 insertions(+), 97 deletions(-)

Index: b/drivers/ide/ide-atapi.c
===================================================================
--- a/drivers/ide/ide-atapi.c
+++ b/drivers/ide/ide-atapi.c
@@ -61,12 +61,62 @@ int ide_check_atapi_device(ide_drive_t *
}
EXPORT_SYMBOL_GPL(ide_check_atapi_device);

+/* PIO data transfer routine using the scatter gather table. */
+int ide_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
+ unsigned int bcount, int write)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ const struct ide_tp_ops *tp_ops = hwif->tp_ops;
+ xfer_func_t *xf = write ? tp_ops->output_data : tp_ops->input_data;
+ struct scatterlist *sg = pc->sg;
+ char *buf;
+ int count, done = 0;
+
+ while (bcount) {
+ count = min(sg->length - pc->b_count, bcount);
+
+ if (PageHighMem(sg_page(sg))) {
+ unsigned long flags;
+
+ local_irq_save(flags);
+ buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
+ xf(drive, NULL, buf + pc->b_count, count);
+ kunmap_atomic(buf - sg->offset, KM_IRQ0);
+ local_irq_restore(flags);
+ } else {
+ buf = sg_virt(sg);
+ xf(drive, NULL, buf + pc->b_count, count);
+ }
+
+ bcount -= count;
+ pc->b_count += count;
+ done += count;
+
+ if (pc->b_count == sg->length) {
+ if (!--pc->sg_cnt)
+ break;
+ pc->sg = sg = sg_next(sg);
+ pc->b_count = 0;
+ }
+ }
+
+ if (bcount) {
+ printk(KERN_ERR "%s: %d leftover bytes, %s\n", drive->name,
+ bcount, write ? "padding with zeros"
+ : "discarding data");
+ ide_pad_transfer(drive, write, bcount);
+ }
+
+ return done;
+}
+EXPORT_SYMBOL_GPL(ide_io_buffers);
+
/* TODO: unify the code thus making some arguments go away */
ide_startstop_t ide_pc_intr(ide_drive_t *drive, struct ide_atapi_pc *pc,
ide_handler_t *handler, unsigned int timeout, ide_expiry_t *expiry,
void (*update_buffers)(ide_drive_t *, struct ide_atapi_pc *),
void (*retry_pc)(ide_drive_t *), void (*dsc_handle)(ide_drive_t *),
- void (*io_buffers)(ide_drive_t *, struct ide_atapi_pc *, unsigned, int))
+ int (*io_buffers)(ide_drive_t *, struct ide_atapi_pc *, unsigned, int))
{
ide_hwif_t *hwif = drive->hwif;
struct request *rq = hwif->hwgroup->rq;
@@ -219,9 +269,14 @@ cmd_finished:

if ((drive->media == ide_floppy && !scsi && !pc->buf) ||
(drive->media == ide_tape && !scsi && pc->bh) ||
- (scsi && pc->sg))
- io_buffers(drive, pc, bcount, !!(pc->flags & PC_FLAG_WRITING));
- else
+ (scsi && pc->sg)) {
+ int done = io_buffers(drive, pc, bcount,
+ !!(pc->flags & PC_FLAG_WRITING));
+
+ /* FIXME: don't do partial completions */
+ if (drive->media == ide_floppy && !scsi)
+ ide_end_request(drive, 1, done >> 9);
+ } else
xferfunc(drive, NULL, pc->cur_pos, bcount);

/* Update the current position */
Index: b/drivers/ide/ide-floppy.c
===================================================================
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -207,51 +207,6 @@ static int idefloppy_end_request(ide_dri
return 0;
}

-static void ide_floppy_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
- unsigned int bcount, int direction)
-{
- ide_hwif_t *hwif = drive->hwif;
- const struct ide_tp_ops *tp_ops = hwif->tp_ops;
- xfer_func_t *xf = direction ? tp_ops->output_data : tp_ops->input_data;
- struct scatterlist *sg = pc->sg;
- char *buf;
- int count, done = 0;
-
- while (bcount) {
- count = min(sg->length - pc->b_count, bcount);
- if (PageHighMem(sg_page(sg))) {
- unsigned long flags;
-
- local_irq_save(flags);
- buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
- xf(drive, NULL, buf + pc->b_count, count);
- kunmap_atomic(buf - sg->offset, KM_IRQ0);
- local_irq_restore(flags);
- } else {
- buf = sg_virt(sg);
- xf(drive, NULL, buf + pc->b_count, count);
- }
- bcount -= count;
- pc->b_count += count;
- done += count;
-
- if (pc->b_count == sg->length) {
- if (!--pc->sg_cnt)
- break;
- pc->sg = sg = sg_next(sg);
- pc->b_count = 0;
- }
- }
-
- idefloppy_end_request(drive, 1, done >> 9);
-
- if (bcount) {
- printk(KERN_ERR "%s: leftover data in %s, bcount == %d\n",
- drive->name, __func__, bcount);
- ide_pad_transfer(drive, direction, bcount);
- }
-}
-
static void idefloppy_update_buffers(ide_drive_t *drive,
struct ide_atapi_pc *pc)
{
@@ -355,7 +310,7 @@ static ide_startstop_t idefloppy_pc_intr

return ide_pc_intr(drive, floppy->pc, idefloppy_pc_intr,
IDEFLOPPY_WAIT_CMD, NULL, idefloppy_update_buffers,
- idefloppy_retry_pc, NULL, ide_floppy_io_buffers);
+ idefloppy_retry_pc, NULL, ide_io_buffers);
}

/*
Index: b/drivers/ide/ide-tape.c
===================================================================
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -693,13 +693,15 @@ static void ide_tape_handle_dsc(ide_driv
idetape_postpone_request(drive);
}

-static void ide_tape_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
+static int ide_tape_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
unsigned int bcount, int write)
{
if (write)
idetape_output_buffers(drive, pc, bcount);
else
idetape_input_buffers(drive, pc, bcount);
+
+ return bcount;
}

/*
Index: b/drivers/scsi/ide-scsi.c
===================================================================
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -130,50 +130,6 @@ static inline idescsi_scsi_t *drive_to_i
return scsihost_to_idescsi(ide_drive->driver_data);
}

-/*
- * PIO data transfer routine using the scatter gather table.
- */
-static void ide_scsi_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
- unsigned int bcount, int write)
-{
- ide_hwif_t *hwif = drive->hwif;
- const struct ide_tp_ops *tp_ops = hwif->tp_ops;
- xfer_func_t *xf = write ? tp_ops->output_data : tp_ops->input_data;
- struct scatterlist *sg = pc->sg;
- char *buf;
- int count;
-
- while (bcount) {
- count = min(sg->length - pc->b_count, bcount);
- if (PageHighMem(sg_page(sg))) {
- unsigned long flags;
-
- local_irq_save(flags);
- buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
- xf(drive, NULL, buf + pc->b_count, count);
- kunmap_atomic(buf - sg->offset, KM_IRQ0);
- local_irq_restore(flags);
- } else {
- buf = sg_virt(sg);
- xf(drive, NULL, buf + pc->b_count, count);
- }
- bcount -= count; pc->b_count += count;
- if (pc->b_count == sg->length) {
- if (!--pc->sg_cnt)
- break;
- pc->sg = sg = sg_next(sg);
- pc->b_count = 0;
- }
- }
-
- if (bcount) {
- printk(KERN_ERR "%s: scatter gather table too small, %s\n",
- drive->name, write ? "padding with zeros"
- : "discarding data");
- ide_pad_transfer(drive, write, bcount);
- }
-}
-
static void ide_scsi_hex_dump(u8 *data, int len)
{
print_hex_dump(KERN_CONT, "", DUMP_PREFIX_NONE, 16, 1, data, len, 0);
@@ -343,7 +299,7 @@ static ide_startstop_t idescsi_pc_intr (

return ide_pc_intr(drive, pc, idescsi_pc_intr, get_timeout(pc),
idescsi_expiry, NULL, NULL, NULL,
- ide_scsi_io_buffers);
+ ide_io_buffers);
}

static ide_startstop_t idescsi_transfer_pc(ide_drive_t *drive)
Index: b/include/linux/ide.h
===================================================================
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -1097,6 +1097,8 @@ void ide_tf_read(ide_drive_t *, ide_task
void ide_input_data(ide_drive_t *, struct request *, void *, unsigned int);
void ide_output_data(ide_drive_t *, struct request *, void *, unsigned int);

+int ide_io_buffers(ide_drive_t *, struct ide_atapi_pc *, unsigned int, int);
+
extern void SELECT_DRIVE(ide_drive_t *);
void SELECT_MASK(ide_drive_t *, int);

@@ -1113,7 +1115,7 @@ ide_startstop_t ide_pc_intr(ide_drive_t
ide_handler_t *handler, unsigned int timeout, ide_expiry_t *expiry,
void (*update_buffers)(ide_drive_t *, struct ide_atapi_pc *),
void (*retry_pc)(ide_drive_t *), void (*dsc_handle)(ide_drive_t *),
- void (*io_buffers)(ide_drive_t *, struct ide_atapi_pc *, unsigned int,
+ int (*io_buffers)(ide_drive_t *, struct ide_atapi_pc *, unsigned int,
int));
ide_startstop_t ide_transfer_pc(ide_drive_t *, struct ide_atapi_pc *,
ide_handler_t *, unsigned int, ide_expiry_t *);

Subject: [PATCH 04/22] ide-floppy: add ide_floppy_set_media_lock() helper

Add ide_floppy_set_media_lock() helper and convert idefloppy_open(),
idefloppy_release() and ide_floppy_lockdoor() to use it.

There should be no functional changes caused by this patch.

Cc: Borislav Petkov <[email protected]>
Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
drivers/ide/ide-floppy.c | 39 ++++++++++++++++-----------------------
1 file changed, 16 insertions(+), 23 deletions(-)

Index: b/drivers/ide/ide-floppy.c
===================================================================
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -1037,6 +1037,17 @@ static ide_driver_t idefloppy_driver = {
#endif
};

+static void ide_floppy_set_media_lock(ide_drive_t *drive, int on)
+{
+ struct ide_atapi_pc pc;
+
+ /* IOMEGA Clik! drives do not support lock/unlock commands */
+ if ((drive->atapi_flags & IDE_AFLAG_CLIK_DRIVE) == 0) {
+ idefloppy_create_prevent_cmd(&pc, on);
+ (void)idefloppy_queue_pc_tail(drive, &pc);
+ }
+}
+
static int idefloppy_open(struct inode *inode, struct file *filp)
{
struct gendisk *disk = inode->i_bdev->bd_disk;
@@ -1083,12 +1094,9 @@ static int idefloppy_open(struct inode *
ret = -EROFS;
goto out_put_floppy;
}
+
drive->atapi_flags |= IDE_AFLAG_MEDIA_CHANGED;
- /* IOMEGA Clik! drives do not support lock/unlock commands */
- if (!(drive->atapi_flags & IDE_AFLAG_CLIK_DRIVE)) {
- idefloppy_create_prevent_cmd(&pc, 1);
- (void) idefloppy_queue_pc_tail(drive, &pc);
- }
+ ide_floppy_set_media_lock(drive, 1);
check_disk_change(inode->i_bdev);
} else if (drive->atapi_flags & IDE_AFLAG_FORMAT_IN_PROGRESS) {
ret = -EBUSY;
@@ -1107,17 +1115,11 @@ static int idefloppy_release(struct inod
struct gendisk *disk = inode->i_bdev->bd_disk;
struct ide_floppy_obj *floppy = ide_floppy_g(disk);
ide_drive_t *drive = floppy->drive;
- struct ide_atapi_pc pc;

debug_log("Reached %s\n", __func__);

if (floppy->openers == 1) {
- /* IOMEGA Clik! drives do not support lock/unlock commands */
- if (!(drive->atapi_flags & IDE_AFLAG_CLIK_DRIVE)) {
- idefloppy_create_prevent_cmd(&pc, 0);
- (void) idefloppy_queue_pc_tail(drive, &pc);
- }
-
+ ide_floppy_set_media_lock(drive, 0);
drive->atapi_flags &= ~IDE_AFLAG_FORMAT_IN_PROGRESS;
}

@@ -1143,21 +1145,12 @@ static int ide_floppy_lockdoor(ide_drive
unsigned long arg, unsigned int cmd)
{
idefloppy_floppy_t *floppy = drive->driver_data;
+ int prevent = (arg && cmd != CDROMEJECT) ? 1 : 0;

if (floppy->openers > 1)
return -EBUSY;

- /* The IOMEGA Clik! Drive doesn't support this command -
- * no room for an eject mechanism */
- if (!(drive->atapi_flags & IDE_AFLAG_CLIK_DRIVE)) {
- int prevent = arg ? 1 : 0;
-
- if (cmd == CDROMEJECT)
- prevent = 0;
-
- idefloppy_create_prevent_cmd(pc, prevent);
- (void) idefloppy_queue_pc_tail(floppy->drive, pc);
- }
+ ide_floppy_set_media_lock(drive, prevent);

if (cmd == CDROMEJECT) {
idefloppy_create_start_stop_cmd(pc, 2);

Subject: [PATCH 05/22] ide-tape: add ide_tape_set_media_lock() helper

Add ide_tape_set_media_lock() helper and convert idetape_mtioctop(),
idetape_chrdev_open() and idetape_chrdev_release() to use it.

There should be no functional changes caused by this patch (it is
OK to modify ->door_locked if idetape_create_prevent_cmd() fails).

Cc: Borislav Petkov <[email protected]>
Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
drivers/ide/ide-tape.c | 39 +++++++++++++++++++--------------------
1 file changed, 19 insertions(+), 20 deletions(-)

Index: b/drivers/ide/ide-tape.c
===================================================================
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -1298,6 +1298,16 @@ static int idetape_create_prevent_cmd(id
return 1;
}

+static int ide_tape_set_media_lock(ide_drive_t *drive, int on)
+{
+ struct ide_atapi_pc pc;
+
+ if (!idetape_create_prevent_cmd(drive, &pc, on))
+ return 0;
+
+ return idetape_queue_pc_tail(drive, &pc);
+}
+
static void __ide_tape_discard_merge_buffer(ide_drive_t *drive)
{
idetape_tape_t *tape = drive->driver_data;
@@ -1926,9 +1936,8 @@ static int idetape_mtioctop(ide_drive_t
* attempting to eject.
*/
if (tape->door_locked) {
- if (idetape_create_prevent_cmd(drive, &pc, 0))
- if (!idetape_queue_pc_tail(drive, &pc))
- tape->door_locked = DOOR_UNLOCKED;
+ if (!ide_tape_set_media_lock(drive, 0))
+ tape->door_locked = DOOR_UNLOCKED;
}
ide_tape_discard_merge_buffer(drive, 0);
idetape_create_load_unload_cmd(drive, &pc,
@@ -1972,17 +1981,13 @@ static int idetape_mtioctop(ide_drive_t
case MTFSR:
case MTBSR:
case MTLOCK:
- if (!idetape_create_prevent_cmd(drive, &pc, 1))
- return 0;
- retval = idetape_queue_pc_tail(drive, &pc);
+ retval = ide_tape_set_media_lock(drive, 1);
if (retval)
return retval;
tape->door_locked = DOOR_EXPLICITLY_LOCKED;
return 0;
case MTUNLOCK:
- if (!idetape_create_prevent_cmd(drive, &pc, 0))
- return 0;
- retval = idetape_queue_pc_tail(drive, &pc);
+ retval = ide_tape_set_media_lock(drive, 0);
if (retval)
return retval;
tape->door_locked = DOOR_UNLOCKED;
@@ -2084,7 +2089,6 @@ static int idetape_chrdev_open(struct in
unsigned int minor = iminor(inode), i = minor & ~0xc0;
ide_drive_t *drive;
idetape_tape_t *tape;
- struct ide_atapi_pc pc;
int retval;

if (i >= MAX_HWIFS * MAX_DRIVES)
@@ -2147,11 +2151,9 @@ static int idetape_chrdev_open(struct in

/* Lock the tape drive door so user can't eject. */
if (tape->chrdev_dir == IDETAPE_DIR_NONE) {
- if (idetape_create_prevent_cmd(drive, &pc, 1)) {
- if (!idetape_queue_pc_tail(drive, &pc)) {
- if (tape->door_locked != DOOR_EXPLICITLY_LOCKED)
- tape->door_locked = DOOR_LOCKED;
- }
+ if (!ide_tape_set_media_lock(drive, 1)) {
+ if (tape->door_locked != DOOR_EXPLICITLY_LOCKED)
+ tape->door_locked = DOOR_LOCKED;
}
}
unlock_kernel();
@@ -2184,7 +2186,6 @@ static int idetape_chrdev_release(struct
{
struct ide_tape_obj *tape = ide_tape_f(filp);
ide_drive_t *drive = tape->drive;
- struct ide_atapi_pc pc;
unsigned int minor = iminor(inode);

lock_kernel();
@@ -2203,10 +2204,8 @@ static int idetape_chrdev_release(struct
(void) idetape_rewind_tape(drive);
if (tape->chrdev_dir == IDETAPE_DIR_NONE) {
if (tape->door_locked == DOOR_LOCKED) {
- if (idetape_create_prevent_cmd(drive, &pc, 0)) {
- if (!idetape_queue_pc_tail(drive, &pc))
- tape->door_locked = DOOR_UNLOCKED;
- }
+ if (!ide_tape_set_media_lock(drive, 0))
+ tape->door_locked = DOOR_UNLOCKED;
}
}
clear_bit(IDE_AFLAG_BUSY, &drive->atapi_flags);

Subject: [PATCH 06/22] ide: add ide_init_pc() helper

* Add IDE_PC_BUFFER_SIZE define.

* Add ide_init_pc() and convert ide-{floppy,tape}.c to use it
instead of ide*_init_pc().

* Remove no longer used IDE*_PC_BUFFER_SIZE and ide*_init_pc().

There should be no functional changes caused by this patch.

Cc: Borislav Petkov <[email protected]>
Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
drivers/ide/ide-atapi.c | 8 ++++++++
drivers/ide/ide-floppy.c | 31 +++++++++----------------------
drivers/ide/ide-tape.c | 44 +++++++++++++-------------------------------
include/linux/ide.h | 10 +++++++++-
4 files changed, 39 insertions(+), 54 deletions(-)

Index: b/drivers/ide/ide-atapi.c
===================================================================
--- a/drivers/ide/ide-atapi.c
+++ b/drivers/ide/ide-atapi.c
@@ -111,6 +111,14 @@ int ide_io_buffers(ide_drive_t *drive, s
}
EXPORT_SYMBOL_GPL(ide_io_buffers);

+void ide_init_pc(struct ide_atapi_pc *pc)
+{
+ memset(pc, 0, sizeof(*pc));
+ pc->buf = pc->pc_buf;
+ pc->buf_size = IDE_PC_BUFFER_SIZE;
+}
+EXPORT_SYMBOL_GPL(ide_init_pc);
+
/* TODO: unify the code thus making some arguments go away */
ide_startstop_t ide_pc_intr(ide_drive_t *drive, struct ide_atapi_pc *pc,
ide_handler_t *handler, unsigned int timeout, ide_expiry_t *expiry,
Index: b/drivers/ide/ide-floppy.c
===================================================================
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -68,12 +68,6 @@
*/
#define IDEFLOPPY_MAX_PC_RETRIES 3

-/*
- * With each packet command, we allocate a buffer of IDEFLOPPY_PC_BUFFER_SIZE
- * bytes.
- */
-#define IDEFLOPPY_PC_BUFFER_SIZE 256
-
/* format capacities descriptor codes */
#define CAPACITY_INVALID 0x00
#define CAPACITY_UNFORMATTED 0x01
@@ -273,16 +267,9 @@ static void ide_floppy_callback(ide_driv
idefloppy_end_request(drive, uptodate, 0);
}

-static void idefloppy_init_pc(struct ide_atapi_pc *pc)
-{
- memset(pc, 0, sizeof(*pc));
- pc->buf = pc->pc_buf;
- pc->buf_size = IDEFLOPPY_PC_BUFFER_SIZE;
-}
-
static void idefloppy_create_request_sense_cmd(struct ide_atapi_pc *pc)
{
- idefloppy_init_pc(pc);
+ ide_init_pc(pc);
pc->c[0] = GPCMD_REQUEST_SENSE;
pc->c[4] = 255;
pc->req_xfer = 18;
@@ -412,14 +399,14 @@ static void idefloppy_create_prevent_cmd
{
debug_log("creating prevent removal command, prevent = %d\n", prevent);

- idefloppy_init_pc(pc);
+ ide_init_pc(pc);
pc->c[0] = GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL;
pc->c[4] = prevent;
}

static void idefloppy_create_read_capacity_cmd(struct ide_atapi_pc *pc)
{
- idefloppy_init_pc(pc);
+ ide_init_pc(pc);
pc->c[0] = GPCMD_READ_FORMAT_CAPACITIES;
pc->c[7] = 255;
pc->c[8] = 255;
@@ -429,7 +416,7 @@ static void idefloppy_create_read_capaci
static void idefloppy_create_format_unit_cmd(struct ide_atapi_pc *pc, int b,
int l, int flags)
{
- idefloppy_init_pc(pc);
+ ide_init_pc(pc);
pc->c[0] = GPCMD_FORMAT_UNIT;
pc->c[1] = 0x17;

@@ -453,7 +440,7 @@ static void idefloppy_create_mode_sense_
{
u16 length = 8; /* sizeof(Mode Parameter Header) = 8 Bytes */

- idefloppy_init_pc(pc);
+ ide_init_pc(pc);
pc->c[0] = GPCMD_MODE_SENSE_10;
pc->c[1] = 0;
pc->c[2] = page_code;
@@ -475,7 +462,7 @@ static void idefloppy_create_mode_sense_

static void idefloppy_create_start_stop_cmd(struct ide_atapi_pc *pc, int start)
{
- idefloppy_init_pc(pc);
+ ide_init_pc(pc);
pc->c[0] = GPCMD_START_STOP_UNIT;
pc->c[4] = start;
}
@@ -491,7 +478,7 @@ static void idefloppy_create_rw_cmd(idef
debug_log("create_rw10_cmd: block == %d, blocks == %d\n",
block, blocks);

- idefloppy_init_pc(pc);
+ ide_init_pc(pc);
pc->c[0] = cmd == READ ? GPCMD_READ_10 : GPCMD_WRITE_10;
put_unaligned(cpu_to_be16(blocks), (unsigned short *)&pc->c[7]);
put_unaligned(cpu_to_be32(block), (unsigned int *) &pc->c[2]);
@@ -510,7 +497,7 @@ static void idefloppy_create_rw_cmd(idef
static void idefloppy_blockpc_cmd(idefloppy_floppy_t *floppy,
struct ide_atapi_pc *pc, struct request *rq)
{
- idefloppy_init_pc(pc);
+ ide_init_pc(pc);
memcpy(pc->c, rq->cmd, sizeof(pc->c));
pc->rq = rq;
pc->b_count = 0;
@@ -1070,7 +1057,7 @@ static int idefloppy_open(struct inode *
drive->atapi_flags &= ~IDE_AFLAG_FORMAT_IN_PROGRESS;
/* Just in case */

- idefloppy_init_pc(&pc);
+ ide_init_pc(&pc);
pc.c[0] = GPCMD_TEST_UNIT_READY;

if (idefloppy_queue_pc_tail(drive, &pc)) {
Index: b/drivers/ide/ide-tape.c
===================================================================
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -81,12 +81,6 @@ enum {
#define IDETAPE_MAX_PC_RETRIES 3

/*
- * With each packet command, we allocate a buffer of IDETAPE_PC_BUFFER_SIZE
- * bytes. This is used for several packet commands (Not for READ/WRITE commands)
- */
-#define IDETAPE_PC_BUFFER_SIZE 256
-
-/*
* Some drives (for example, Seagate STT3401A Travan) require a very long
* timeout, because they don't return an interrupt or clear their busy bit
* until after the command completes (even retension commands).
@@ -610,21 +604,9 @@ static void ide_tape_callback(ide_drive_
idetape_end_request(drive, uptodate, 0);
}

-static void idetape_init_pc(struct ide_atapi_pc *pc)
-{
- memset(pc->c, 0, 12);
- pc->retries = 0;
- pc->flags = 0;
- pc->req_xfer = 0;
- pc->buf = pc->pc_buf;
- pc->buf_size = IDETAPE_PC_BUFFER_SIZE;
- pc->bh = NULL;
- pc->b_data = NULL;
-}
-
static void idetape_create_request_sense_cmd(struct ide_atapi_pc *pc)
{
- idetape_init_pc(pc);
+ ide_init_pc(pc);
pc->c[0] = REQUEST_SENSE;
pc->c[4] = 20;
pc->req_xfer = 20;
@@ -816,7 +798,7 @@ static ide_startstop_t idetape_issue_pc(
/* A mode sense command is used to "sense" tape parameters. */
static void idetape_create_mode_sense_cmd(struct ide_atapi_pc *pc, u8 page_code)
{
- idetape_init_pc(pc);
+ ide_init_pc(pc);
pc->c[0] = MODE_SENSE;
if (page_code != IDETAPE_BLOCK_DESCRIPTOR)
/* DBD = 1 - Don't return block descriptors */
@@ -875,7 +857,7 @@ static void ide_tape_create_rw_cmd(ideta
struct idetape_bh *bh = (struct idetape_bh *)rq->special;
unsigned int length = rq->current_nr_sectors;

- idetape_init_pc(pc);
+ ide_init_pc(pc);
put_unaligned(cpu_to_be32(length), (unsigned int *) &pc->c[1]);
pc->c[1] = 1;
pc->bh = bh;
@@ -1164,7 +1146,7 @@ static void idetape_init_merge_buffer(id
static void idetape_create_write_filemark_cmd(ide_drive_t *drive,
struct ide_atapi_pc *pc, int write_filemark)
{
- idetape_init_pc(pc);
+ ide_init_pc(pc);
pc->c[0] = WRITE_FILEMARKS;
pc->c[4] = write_filemark;
pc->flags |= PC_FLAG_WAIT_FOR_DSC;
@@ -1172,7 +1154,7 @@ static void idetape_create_write_filemar

static void idetape_create_test_unit_ready_cmd(struct ide_atapi_pc *pc)
{
- idetape_init_pc(pc);
+ ide_init_pc(pc);
pc->c[0] = TEST_UNIT_READY;
}

@@ -1199,7 +1181,7 @@ static int idetape_queue_pc_tail(ide_dri
static void idetape_create_load_unload_cmd(ide_drive_t *drive,
struct ide_atapi_pc *pc, int cmd)
{
- idetape_init_pc(pc);
+ ide_init_pc(pc);
pc->c[0] = START_STOP;
pc->c[4] = cmd;
pc->flags |= PC_FLAG_WAIT_FOR_DSC;
@@ -1251,7 +1233,7 @@ static int idetape_flush_tape_buffers(id

static void idetape_create_read_position_cmd(struct ide_atapi_pc *pc)
{
- idetape_init_pc(pc);
+ ide_init_pc(pc);
pc->c[0] = READ_POSITION;
pc->req_xfer = 20;
}
@@ -1275,7 +1257,7 @@ static void idetape_create_locate_cmd(id
struct ide_atapi_pc *pc,
unsigned int block, u8 partition, int skip)
{
- idetape_init_pc(pc);
+ ide_init_pc(pc);
pc->c[0] = POSITION_TO_ELEMENT;
pc->c[1] = 2;
put_unaligned(cpu_to_be32(block), (unsigned int *) &pc->c[3]);
@@ -1292,7 +1274,7 @@ static int idetape_create_prevent_cmd(id
if (!(tape->caps[6] & 0x01))
return 0;

- idetape_init_pc(pc);
+ ide_init_pc(pc);
pc->c[0] = ALLOW_MEDIUM_REMOVAL;
pc->c[4] = prevent;
return 1;
@@ -1407,7 +1389,7 @@ static int idetape_queue_rw_tail(ide_dri

static void idetape_create_inquiry_cmd(struct ide_atapi_pc *pc)
{
- idetape_init_pc(pc);
+ ide_init_pc(pc);
pc->c[0] = INQUIRY;
pc->c[4] = 254;
pc->req_xfer = 254;
@@ -1416,14 +1398,14 @@ static void idetape_create_inquiry_cmd(s
static void idetape_create_rewind_cmd(ide_drive_t *drive,
struct ide_atapi_pc *pc)
{
- idetape_init_pc(pc);
+ ide_init_pc(pc);
pc->c[0] = REZERO_UNIT;
pc->flags |= PC_FLAG_WAIT_FOR_DSC;
}

static void idetape_create_erase_cmd(struct ide_atapi_pc *pc)
{
- idetape_init_pc(pc);
+ ide_init_pc(pc);
pc->c[0] = ERASE;
pc->c[1] = 1;
pc->flags |= PC_FLAG_WAIT_FOR_DSC;
@@ -1431,7 +1413,7 @@ static void idetape_create_erase_cmd(str

static void idetape_create_space_cmd(struct ide_atapi_pc *pc, int count, u8 cmd)
{
- idetape_init_pc(pc);
+ ide_init_pc(pc);
pc->c[0] = SPACE;
put_unaligned(cpu_to_be32(count), (unsigned int *) &pc->c[1]);
pc->c[1] = cmd;
Index: b/include/linux/ide.h
===================================================================
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -722,6 +722,12 @@ enum {
PC_FLAG_TIMEDOUT = (1 << 7),
};

+/*
+ * With each packet command, we allocate a buffer of IDE_PC_BUFFER_SIZE bytes.
+ * This is used for several packet commands (not for READ/WRITE commands).
+ */
+#define IDE_PC_BUFFER_SIZE 256
+
struct ide_atapi_pc {
/* actual packet bytes */
u8 c[12];
@@ -751,7 +757,7 @@ struct ide_atapi_pc {
* those are more or less driver-specific and some of them are subject
* to change/removal later.
*/
- u8 pc_buf[256];
+ u8 pc_buf[IDE_PC_BUFFER_SIZE];

/* idetape only */
struct idetape_bh *bh;
@@ -1111,6 +1117,8 @@ void ide_pktcmd_tf_load(ide_drive_t *, u

int ide_check_atapi_device(ide_drive_t *, const char *);

+void ide_init_pc(struct ide_atapi_pc *);
+
ide_startstop_t ide_pc_intr(ide_drive_t *drive, struct ide_atapi_pc *pc,
ide_handler_t *handler, unsigned int timeout, ide_expiry_t *expiry,
void (*update_buffers)(ide_drive_t *, struct ide_atapi_pc *),

Subject: [PATCH 07/22] ide: add ide_queue_pc_head() helper

* Move REQ_IDETAPE_* enums to <linux/ide.h>.

* Add ide_queue_pc_head() and convert ide-{floppy,tape}.c to use it
instead of ide*_queue_pc_head().

* Remove no longer used ide*_queue_pc_head().

There should be no functional changes caused by this patch.

Cc: Borislav Petkov <[email protected]>
Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
drivers/ide/ide-atapi.c | 20 ++++++++++++++++++++
drivers/ide/ide-floppy.c | 21 +--------------------
drivers/ide/ide-tape.c | 36 +-----------------------------------
include/linux/ide.h | 16 ++++++++++++++++
4 files changed, 38 insertions(+), 55 deletions(-)

Index: b/drivers/ide/ide-atapi.c
===================================================================
--- a/drivers/ide/ide-atapi.c
+++ b/drivers/ide/ide-atapi.c
@@ -119,6 +119,26 @@ void ide_init_pc(struct ide_atapi_pc *pc
}
EXPORT_SYMBOL_GPL(ide_init_pc);

+/*
+ * Generate a new packet command request in front of the request queue, before
+ * the current request, so that it will be processed immediately, on the next
+ * pass through the driver.
+ */
+void ide_queue_pc_head(ide_drive_t *drive, struct gendisk *disk,
+ struct ide_atapi_pc *pc, struct request *rq)
+{
+ blk_rq_init(NULL, rq);
+ rq->cmd_type = REQ_TYPE_SPECIAL;
+ rq->cmd_flags |= REQ_PREEMPT;
+ rq->buffer = (char *)pc;
+ rq->rq_disk = disk;
+ memcpy(rq->cmd, pc->c, 12);
+ if (drive->media == ide_tape)
+ rq->cmd[13] = REQ_IDETAPE_PC1;
+ ide_do_drive_cmd(drive, rq);
+}
+EXPORT_SYMBOL_GPL(ide_queue_pc_head);
+
/* TODO: unify the code thus making some arguments go away */
ide_startstop_t ide_pc_intr(ide_drive_t *drive, struct ide_atapi_pc *pc,
ide_handler_t *handler, unsigned int timeout, ide_expiry_t *expiry,
Index: b/drivers/ide/ide-floppy.c
===================================================================
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -211,25 +211,6 @@ static void idefloppy_update_buffers(ide
idefloppy_end_request(drive, 1, 0);
}

-/*
- * Generate a new packet command request in front of the request queue, before
- * the current request so that it will be processed immediately, on the next
- * pass through the driver.
- */
-static void idefloppy_queue_pc_head(ide_drive_t *drive, struct ide_atapi_pc *pc,
- struct request *rq)
-{
- struct ide_floppy_obj *floppy = drive->driver_data;
-
- blk_rq_init(NULL, rq);
- rq->buffer = (char *) pc;
- rq->cmd_type = REQ_TYPE_SPECIAL;
- rq->cmd_flags |= REQ_PREEMPT;
- rq->rq_disk = floppy->disk;
- memcpy(rq->cmd, pc->c, 12);
- ide_do_drive_cmd(drive, rq);
-}
-
static void ide_floppy_callback(ide_drive_t *drive)
{
idefloppy_floppy_t *floppy = drive->driver_data;
@@ -287,7 +268,7 @@ static void idefloppy_retry_pc(ide_drive

(void)ide_read_error(drive);
idefloppy_create_request_sense_cmd(pc);
- idefloppy_queue_pc_head(drive, pc, rq);
+ ide_queue_pc_head(drive, floppy->disk, pc, rq);
}

/* The usual interrupt handler called during a packet command. */
Index: b/drivers/ide/ide-tape.c
===================================================================
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -159,20 +159,6 @@ struct idetape_bh {
#define IDETAPE_LU_RETENSION_MASK 2
#define IDETAPE_LU_EOT_MASK 4

-/*
- * Special requests for our block device strategy routine.
- *
- * In order to service a character device command, we add special requests to
- * the tail of our block device request queue and wait for their completion.
- */
-
-enum {
- REQ_IDETAPE_PC1 = (1 << 0), /* packet command (first stage) */
- REQ_IDETAPE_PC2 = (1 << 1), /* packet command (second stage) */
- REQ_IDETAPE_READ = (1 << 2),
- REQ_IDETAPE_WRITE = (1 << 3),
-};
-
/* Error codes returned in rq->errors to the higher part of the driver. */
#define IDETAPE_ERROR_GENERAL 101
#define IDETAPE_ERROR_FILEMARK 102
@@ -613,26 +599,6 @@ static void idetape_create_request_sense
}

/*
- * Generate a new packet command request in front of the request queue, before
- * the current request, so that it will be processed immediately, on the next
- * pass through the driver.
- */
-static void idetape_queue_pc_head(ide_drive_t *drive, struct ide_atapi_pc *pc,
- struct request *rq)
-{
- struct ide_tape_obj *tape = drive->driver_data;
-
- blk_rq_init(NULL, rq);
- rq->cmd_type = REQ_TYPE_SPECIAL;
- rq->cmd_flags |= REQ_PREEMPT;
- rq->buffer = (char *) pc;
- rq->rq_disk = tape->disk;
- memcpy(rq->cmd, pc->c, 12);
- rq->cmd[13] = REQ_IDETAPE_PC1;
- ide_do_drive_cmd(drive, rq);
-}
-
-/*
* idetape_retry_pc is called when an error was detected during the
* last packet command. We queue a request sense packet command in
* the head of the request list.
@@ -646,7 +612,7 @@ static void idetape_retry_pc(ide_drive_t
(void)ide_read_error(drive);
idetape_create_request_sense_cmd(pc);
set_bit(IDE_AFLAG_IGNORE_DSC, &drive->atapi_flags);
- idetape_queue_pc_head(drive, pc, rq);
+ ide_queue_pc_head(drive, tape->disk, pc, rq);
}

/*
Index: b/include/linux/ide.h
===================================================================
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -1119,6 +1119,22 @@ int ide_check_atapi_device(ide_drive_t *

void ide_init_pc(struct ide_atapi_pc *);

+/*
+ * Special requests for ide-tape block device strategy routine.
+ *
+ * In order to service a character device command, we add special requests to
+ * the tail of our block device request queue and wait for their completion.
+ */
+enum {
+ REQ_IDETAPE_PC1 = (1 << 0), /* packet command (first stage) */
+ REQ_IDETAPE_PC2 = (1 << 1), /* packet command (second stage) */
+ REQ_IDETAPE_READ = (1 << 2),
+ REQ_IDETAPE_WRITE = (1 << 3),
+};
+
+void ide_queue_pc_head(ide_drive_t *, struct gendisk *, struct ide_atapi_pc *,
+ struct request *);
+
ide_startstop_t ide_pc_intr(ide_drive_t *drive, struct ide_atapi_pc *pc,
ide_handler_t *handler, unsigned int timeout, ide_expiry_t *expiry,
void (*update_buffers)(ide_drive_t *, struct ide_atapi_pc *),

Subject: [PATCH 08/22] ide: add ide_queue_pc_tail() helper

* Add ide_queue_pc_tail() and convert ide-{floppy,tape}.c to use it
instead of ide*_queue_pc_tail().

* Remove no longer used ide*_queue_pc_tail().

There should be no functional changes caused by this patch.

Cc: Borislav Petkov <[email protected]>
Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
drivers/ide/ide-atapi.c | 23 +++++++++++++++
drivers/ide/ide-floppy.c | 49 +++++++++++----------------------
drivers/ide/ide-tape.c | 69 +++++++++++++++++++----------------------------
include/linux/ide.h | 1
4 files changed, 69 insertions(+), 73 deletions(-)

Index: b/drivers/ide/ide-atapi.c
===================================================================
--- a/drivers/ide/ide-atapi.c
+++ b/drivers/ide/ide-atapi.c
@@ -139,6 +139,29 @@ void ide_queue_pc_head(ide_drive_t *driv
}
EXPORT_SYMBOL_GPL(ide_queue_pc_head);

+/*
+ * Add a special packet command request to the tail of the request queue,
+ * and wait for it to be serviced.
+ */
+int ide_queue_pc_tail(ide_drive_t *drive, struct gendisk *disk,
+ struct ide_atapi_pc *pc)
+{
+ struct request *rq;
+ int error;
+
+ rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
+ rq->cmd_type = REQ_TYPE_SPECIAL;
+ rq->buffer = (char *)pc;
+ memcpy(rq->cmd, pc->c, 12);
+ if (drive->media == ide_tape)
+ rq->cmd[13] = REQ_IDETAPE_PC1;
+ error = blk_execute_rq(drive->queue, disk, rq, 0);
+ blk_put_request(rq);
+
+ return error;
+}
+EXPORT_SYMBOL_GPL(ide_queue_pc_tail);
+
/* TODO: unify the code thus making some arguments go away */
ide_startstop_t ide_pc_intr(ide_drive_t *drive, struct ide_atapi_pc *pc,
ide_handler_t *handler, unsigned int timeout, ide_expiry_t *expiry,
Index: b/drivers/ide/ide-floppy.c
===================================================================
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -553,32 +553,13 @@ static ide_startstop_t idefloppy_do_requ
}

/*
- * Add a special packet command request to the tail of the request queue,
- * and wait for it to be serviced.
- */
-static int idefloppy_queue_pc_tail(ide_drive_t *drive, struct ide_atapi_pc *pc)
-{
- struct ide_floppy_obj *floppy = drive->driver_data;
- struct request *rq;
- int error;
-
- rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
- rq->buffer = (char *) pc;
- rq->cmd_type = REQ_TYPE_SPECIAL;
- memcpy(rq->cmd, pc->c, 12);
- error = blk_execute_rq(drive->queue, floppy->disk, rq, 0);
- blk_put_request(rq);
-
- return error;
-}
-
-/*
* Look at the flexible disk page parameters. We ignore the CHS capacity
* parameters and use the LBA parameters instead.
*/
static int ide_floppy_get_flexible_disk_page(ide_drive_t *drive)
{
idefloppy_floppy_t *floppy = drive->driver_data;
+ struct gendisk *disk = floppy->disk;
struct ide_atapi_pc pc;
u8 *page;
int capacity, lba_capacity;
@@ -587,13 +568,13 @@ static int ide_floppy_get_flexible_disk_

idefloppy_create_mode_sense_cmd(&pc, IDEFLOPPY_FLEXIBLE_DISK_PAGE);

- if (idefloppy_queue_pc_tail(drive, &pc)) {
+ if (ide_queue_pc_tail(drive, disk, &pc)) {
printk(KERN_ERR "ide-floppy: Can't get flexible disk page"
" parameters\n");
return 1;
}
floppy->wp = !!(pc.buf[3] & 0x80);
- set_disk_ro(floppy->disk, floppy->wp);
+ set_disk_ro(disk, floppy->wp);
page = &pc.buf[8];

transfer_rate = be16_to_cpup((__be16 *)&pc.buf[8 + 2]);
@@ -637,7 +618,7 @@ static int idefloppy_get_sfrp_bit(ide_dr
idefloppy_create_mode_sense_cmd(&pc, IDEFLOPPY_CAPABILITIES_PAGE);
pc.flags |= PC_FLAG_SUPPRESS_ERROR;

- if (idefloppy_queue_pc_tail(drive, &pc))
+ if (ide_queue_pc_tail(drive, floppy->disk, &pc))
return 1;

floppy->srfp = pc.buf[8 + 2] & 0x40;
@@ -651,6 +632,7 @@ static int idefloppy_get_sfrp_bit(ide_dr
static int ide_floppy_get_capacity(ide_drive_t *drive)
{
idefloppy_floppy_t *floppy = drive->driver_data;
+ struct gendisk *disk = floppy->disk;
struct ide_atapi_pc pc;
u8 *cap_desc;
u8 header_len, desc_cnt;
@@ -663,7 +645,7 @@ static int ide_floppy_get_capacity(ide_d
set_capacity(floppy->disk, 0);

idefloppy_create_read_capacity_cmd(&pc);
- if (idefloppy_queue_pc_tail(drive, &pc)) {
+ if (ide_queue_pc_tail(drive, disk, &pc)) {
printk(KERN_ERR "ide-floppy: Can't get floppy parameters\n");
return 1;
}
@@ -738,7 +720,8 @@ static int ide_floppy_get_capacity(ide_d
if (!(drive->atapi_flags & IDE_AFLAG_CLIK_DRIVE))
(void) ide_floppy_get_flexible_disk_page(drive);

- set_capacity(floppy->disk, floppy->blocks * floppy->bs_factor);
+ set_capacity(disk, floppy->blocks * floppy->bs_factor);
+
return rc;
}

@@ -763,6 +746,7 @@ static int ide_floppy_get_capacity(ide_d

static int ide_floppy_get_format_capacities(ide_drive_t *drive, int __user *arg)
{
+ struct ide_floppy_obj *floppy = drive->driver_data;
struct ide_atapi_pc pc;
u8 header_len, desc_cnt;
int i, blocks, length, u_array_size, u_index;
@@ -775,7 +759,7 @@ static int ide_floppy_get_format_capacit
return -EINVAL;

idefloppy_create_read_capacity_cmd(&pc);
- if (idefloppy_queue_pc_tail(drive, &pc)) {
+ if (ide_queue_pc_tail(drive, floppy->disk, &pc)) {
printk(KERN_ERR "ide-floppy: Can't get floppy parameters\n");
return -EIO;
}
@@ -837,7 +821,7 @@ static int ide_floppy_get_format_progres

if (floppy->srfp) {
idefloppy_create_request_sense_cmd(&pc);
- if (idefloppy_queue_pc_tail(drive, &pc))
+ if (ide_queue_pc_tail(drive, floppy->disk, &pc))
return -EIO;

if (floppy->sense_key == 2 &&
@@ -1007,12 +991,13 @@ static ide_driver_t idefloppy_driver = {

static void ide_floppy_set_media_lock(ide_drive_t *drive, int on)
{
+ struct ide_floppy_obj *floppy = drive->driver_data;
struct ide_atapi_pc pc;

/* IOMEGA Clik! drives do not support lock/unlock commands */
if ((drive->atapi_flags & IDE_AFLAG_CLIK_DRIVE) == 0) {
idefloppy_create_prevent_cmd(&pc, on);
- (void)idefloppy_queue_pc_tail(drive, &pc);
+ (void)ide_queue_pc_tail(drive, floppy->disk, &pc);
}
}

@@ -1041,9 +1026,9 @@ static int idefloppy_open(struct inode *
ide_init_pc(&pc);
pc.c[0] = GPCMD_TEST_UNIT_READY;

- if (idefloppy_queue_pc_tail(drive, &pc)) {
+ if (ide_queue_pc_tail(drive, disk, &pc)) {
idefloppy_create_start_stop_cmd(&pc, 1);
- (void) idefloppy_queue_pc_tail(drive, &pc);
+ (void)ide_queue_pc_tail(drive, disk, &pc);
}

if (ide_floppy_get_capacity(drive)
@@ -1122,7 +1107,7 @@ static int ide_floppy_lockdoor(ide_drive

if (cmd == CDROMEJECT) {
idefloppy_create_start_stop_cmd(pc, 2);
- (void) idefloppy_queue_pc_tail(floppy->drive, pc);
+ (void)ide_queue_pc_tail(drive, floppy->disk, pc);
}

return 0;
@@ -1167,7 +1152,7 @@ static int ide_floppy_format_unit(ide_dr
(void) idefloppy_get_sfrp_bit(drive);
idefloppy_create_format_unit_cmd(&pc, blocks, length, flags);

- if (idefloppy_queue_pc_tail(drive, &pc))
+ if (ide_queue_pc_tail(drive, floppy->disk, &pc))
err = -EIO;

out:
Index: b/drivers/ide/ide-tape.c
===================================================================
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -1124,26 +1124,6 @@ static void idetape_create_test_unit_rea
pc->c[0] = TEST_UNIT_READY;
}

-/*
- * We add a special packet command request to the tail of the request queue, and
- * wait for it to be serviced.
- */
-static int idetape_queue_pc_tail(ide_drive_t *drive, struct ide_atapi_pc *pc)
-{
- struct ide_tape_obj *tape = drive->driver_data;
- struct request *rq;
- int error;
-
- rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
- rq->cmd_type = REQ_TYPE_SPECIAL;
- rq->cmd[13] = REQ_IDETAPE_PC1;
- rq->buffer = (char *)pc;
- memcpy(rq->cmd, pc->c, 12);
- error = blk_execute_rq(drive->queue, tape->disk, rq, 0);
- blk_put_request(rq);
- return error;
-}
-
static void idetape_create_load_unload_cmd(ide_drive_t *drive,
struct ide_atapi_pc *pc, int cmd)
{
@@ -1156,6 +1136,7 @@ static void idetape_create_load_unload_c
static int idetape_wait_ready(ide_drive_t *drive, unsigned long timeout)
{
idetape_tape_t *tape = drive->driver_data;
+ struct gendisk *disk = tape->disk;
struct ide_atapi_pc pc;
int load_attempted = 0;

@@ -1164,7 +1145,7 @@ static int idetape_wait_ready(ide_drive_
timeout += jiffies;
while (time_before(jiffies, timeout)) {
idetape_create_test_unit_ready_cmd(&pc);
- if (!idetape_queue_pc_tail(drive, &pc))
+ if (!ide_queue_pc_tail(drive, disk, &pc))
return 0;
if ((tape->sense_key == 2 && tape->asc == 4 && tape->ascq == 2)
|| (tape->asc == 0x3A)) {
@@ -1173,7 +1154,7 @@ static int idetape_wait_ready(ide_drive_
return -ENOMEDIUM;
idetape_create_load_unload_cmd(drive, &pc,
IDETAPE_LU_LOAD_MASK);
- idetape_queue_pc_tail(drive, &pc);
+ ide_queue_pc_tail(drive, disk, &pc);
load_attempted = 1;
/* not about to be ready */
} else if (!(tape->sense_key == 2 && tape->asc == 4 &&
@@ -1186,11 +1167,12 @@ static int idetape_wait_ready(ide_drive_

static int idetape_flush_tape_buffers(ide_drive_t *drive)
{
+ struct ide_tape_obj *tape = drive->driver_data;
struct ide_atapi_pc pc;
int rc;

idetape_create_write_filemark_cmd(drive, &pc, 0);
- rc = idetape_queue_pc_tail(drive, &pc);
+ rc = ide_queue_pc_tail(drive, tape->disk, &pc);
if (rc)
return rc;
idetape_wait_ready(drive, 60 * 5 * HZ);
@@ -1213,7 +1195,7 @@ static int idetape_read_position(ide_dri
debug_log(DBG_PROCS, "Enter %s\n", __func__);

idetape_create_read_position_cmd(&pc);
- if (idetape_queue_pc_tail(drive, &pc))
+ if (ide_queue_pc_tail(drive, tape->disk, &pc))
return -1;
position = tape->first_frame;
return position;
@@ -1248,12 +1230,13 @@ static int idetape_create_prevent_cmd(id

static int ide_tape_set_media_lock(ide_drive_t *drive, int on)
{
+ struct ide_tape_obj *tape = drive->driver_data;
struct ide_atapi_pc pc;

if (!idetape_create_prevent_cmd(drive, &pc, on))
return 0;

- return idetape_queue_pc_tail(drive, &pc);
+ return ide_queue_pc_tail(drive, tape->disk, &pc);
}

static void __ide_tape_discard_merge_buffer(ide_drive_t *drive)
@@ -1283,6 +1266,7 @@ static int idetape_position_tape(ide_dri
u8 partition, int skip)
{
idetape_tape_t *tape = drive->driver_data;
+ struct gendisk *disk = tape->disk;
int retval;
struct ide_atapi_pc pc;

@@ -1290,12 +1274,12 @@ static int idetape_position_tape(ide_dri
__ide_tape_discard_merge_buffer(drive);
idetape_wait_ready(drive, 60 * 5 * HZ);
idetape_create_locate_cmd(drive, &pc, block, partition, skip);
- retval = idetape_queue_pc_tail(drive, &pc);
+ retval = ide_queue_pc_tail(drive, disk, &pc);
if (retval)
return (retval);

idetape_create_read_position_cmd(&pc);
- return (idetape_queue_pc_tail(drive, &pc));
+ return ide_queue_pc_tail(drive, disk, &pc);
}

static void ide_tape_discard_merge_buffer(ide_drive_t *drive,
@@ -1542,20 +1526,20 @@ static void idetape_pad_zeros(ide_drive_
*/
static int idetape_rewind_tape(ide_drive_t *drive)
{
+ struct ide_tape_obj *tape = drive->driver_data;
+ struct gendisk *disk = tape->disk;
int retval;
struct ide_atapi_pc pc;
- idetape_tape_t *tape;
- tape = drive->driver_data;

debug_log(DBG_SENSE, "Enter %s\n", __func__);

idetape_create_rewind_cmd(drive, &pc);
- retval = idetape_queue_pc_tail(drive, &pc);
+ retval = ide_queue_pc_tail(drive, disk, &pc);
if (retval)
return retval;

idetape_create_read_position_cmd(&pc);
- retval = idetape_queue_pc_tail(drive, &pc);
+ retval = ide_queue_pc_tail(drive, disk, &pc);
if (retval)
return retval;
return 0;
@@ -1598,6 +1582,7 @@ static int idetape_space_over_filemarks(
int mt_count)
{
idetape_tape_t *tape = drive->driver_data;
+ struct gendisk *disk = tape->disk;
struct ide_atapi_pc pc;
int retval, count = 0;
int sprev = !!(tape->caps[4] & 0x20);
@@ -1622,7 +1607,7 @@ static int idetape_space_over_filemarks(
case MTBSF:
idetape_create_space_cmd(&pc, mt_count - count,
IDETAPE_SPACE_OVER_FILEMARK);
- return idetape_queue_pc_tail(drive, &pc);
+ return ide_queue_pc_tail(drive, disk, &pc);
case MTFSFM:
case MTBSFM:
if (!sprev)
@@ -1811,11 +1796,12 @@ static ssize_t idetape_chrdev_write(stru

static int idetape_write_filemark(ide_drive_t *drive)
{
+ struct ide_tape_obj *tape = drive->driver_data;
struct ide_atapi_pc pc;

/* Write a filemark */
idetape_create_write_filemark_cmd(drive, &pc, 1);
- if (idetape_queue_pc_tail(drive, &pc)) {
+ if (ide_queue_pc_tail(drive, tape->disk, &pc)) {
printk(KERN_ERR "ide-tape: Couldn't write a filemark\n");
return -EIO;
}
@@ -1838,6 +1824,7 @@ static int idetape_write_filemark(ide_dr
static int idetape_mtioctop(ide_drive_t *drive, short mt_op, int mt_count)
{
idetape_tape_t *tape = drive->driver_data;
+ struct gendisk *disk = tape->disk;
struct ide_atapi_pc pc;
int i, retval;

@@ -1876,7 +1863,7 @@ static int idetape_mtioctop(ide_drive_t
ide_tape_discard_merge_buffer(drive, 0);
idetape_create_load_unload_cmd(drive, &pc,
IDETAPE_LU_LOAD_MASK);
- return idetape_queue_pc_tail(drive, &pc);
+ return ide_queue_pc_tail(drive, disk, &pc);
case MTUNLOAD:
case MTOFFL:
/*
@@ -1890,7 +1877,7 @@ static int idetape_mtioctop(ide_drive_t
ide_tape_discard_merge_buffer(drive, 0);
idetape_create_load_unload_cmd(drive, &pc,
!IDETAPE_LU_LOAD_MASK);
- retval = idetape_queue_pc_tail(drive, &pc);
+ retval = ide_queue_pc_tail(drive, disk, &pc);
if (!retval)
clear_bit(IDE_AFLAG_MEDIUM_PRESENT, &drive->atapi_flags);
return retval;
@@ -1901,14 +1888,14 @@ static int idetape_mtioctop(ide_drive_t
ide_tape_discard_merge_buffer(drive, 0);
idetape_create_load_unload_cmd(drive, &pc,
IDETAPE_LU_RETENSION_MASK | IDETAPE_LU_LOAD_MASK);
- return idetape_queue_pc_tail(drive, &pc);
+ return ide_queue_pc_tail(drive, disk, &pc);
case MTEOM:
idetape_create_space_cmd(&pc, 0, IDETAPE_SPACE_TO_EOD);
- return idetape_queue_pc_tail(drive, &pc);
+ return ide_queue_pc_tail(drive, disk, &pc);
case MTERASE:
(void)idetape_rewind_tape(drive);
idetape_create_erase_cmd(&pc);
- return idetape_queue_pc_tail(drive, &pc);
+ return ide_queue_pc_tail(drive, disk, &pc);
case MTSETBLK:
if (mt_count) {
if (mt_count < tape->blk_size ||
@@ -2017,7 +2004,7 @@ static void ide_tape_get_bsize_from_bdes
struct ide_atapi_pc pc;

idetape_create_mode_sense_cmd(&pc, IDETAPE_BLOCK_DESCRIPTOR);
- if (idetape_queue_pc_tail(drive, &pc)) {
+ if (ide_queue_pc_tail(drive, tape->disk, &pc)) {
printk(KERN_ERR "ide-tape: Can't get block descriptor\n");
if (tape->blk_size == 0) {
printk(KERN_WARNING "ide-tape: Cannot deal with zero "
@@ -2169,7 +2156,7 @@ static void idetape_get_inquiry_results(
char fw_rev[6], vendor_id[10], product_id[18];

idetape_create_inquiry_cmd(&pc);
- if (idetape_queue_pc_tail(drive, &pc)) {
+ if (ide_queue_pc_tail(drive, tape->disk, &pc)) {
printk(KERN_ERR "ide-tape: %s: can't get INQUIRY results\n",
tape->name);
return;
@@ -2198,7 +2185,7 @@ static void idetape_get_mode_sense_resul
u8 speed, max_speed;

idetape_create_mode_sense_cmd(&pc, IDETAPE_CAPABILITIES_PAGE);
- if (idetape_queue_pc_tail(drive, &pc)) {
+ if (ide_queue_pc_tail(drive, tape->disk, &pc)) {
printk(KERN_ERR "ide-tape: Can't get tape parameters - assuming"
" some default values\n");
tape->blk_size = 512;
Index: b/include/linux/ide.h
===================================================================
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -1134,6 +1134,7 @@ enum {

void ide_queue_pc_head(ide_drive_t *, struct gendisk *, struct ide_atapi_pc *,
struct request *);
+int ide_queue_pc_tail(ide_drive_t *, struct gendisk *, struct ide_atapi_pc *);

ide_startstop_t ide_pc_intr(ide_drive_t *drive, struct ide_atapi_pc *pc,
ide_handler_t *handler, unsigned int timeout, ide_expiry_t *expiry,

Subject: [PATCH 09/22] ide-floppy: ->{srfp,wp} -> IDE_AFLAG_{SRFP,WP}

Add IDE_AFLAG_{SRFP,WP} drive->atapi_flags and use them
instead of ->{srfp,wp} struct ide_floppy_obj fields.

There should be no functional changes caused by this patch.

Cc: Borislav Petkov <[email protected]>
Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
drivers/ide/ide-floppy.c | 24 ++++++++++++++----------
include/linux/ide.h | 16 ++++++++++------
2 files changed, 24 insertions(+), 16 deletions(-)

Index: b/drivers/ide/ide-floppy.c
===================================================================
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -109,10 +109,6 @@ typedef struct ide_floppy_obj {
u8 cap_desc[8];
/* Copy of the flexible disk page */
u8 flexible_disk_page[32];
- /* Write protect */
- int wp;
- /* Supports format progress report */
- int srfp;
} idefloppy_floppy_t;

#define IDEFLOPPY_TICKS_DELAY HZ/20 /* default delay for ZIP 100 (50ms) */
@@ -573,8 +569,14 @@ static int ide_floppy_get_flexible_disk_
" parameters\n");
return 1;
}
- floppy->wp = !!(pc.buf[3] & 0x80);
- set_disk_ro(disk, floppy->wp);
+
+ if (pc.buf[3] & 0x80)
+ drive->atapi_flags |= IDE_AFLAG_WP;
+ else
+ drive->atapi_flags &= ~IDE_AFLAG_WP;
+
+ set_disk_ro(disk, !!(drive->atapi_flags & IDE_AFLAG_WP));
+
page = &pc.buf[8];

transfer_rate = be16_to_cpup((__be16 *)&pc.buf[8 + 2]);
@@ -613,7 +615,7 @@ static int idefloppy_get_sfrp_bit(ide_dr
idefloppy_floppy_t *floppy = drive->driver_data;
struct ide_atapi_pc pc;

- floppy->srfp = 0;
+ drive->atapi_flags &= ~IDE_AFLAG_SRFP;

idefloppy_create_mode_sense_cmd(&pc, IDEFLOPPY_CAPABILITIES_PAGE);
pc.flags |= PC_FLAG_SUPPRESS_ERROR;
@@ -621,7 +623,9 @@ static int idefloppy_get_sfrp_bit(ide_dr
if (ide_queue_pc_tail(drive, floppy->disk, &pc))
return 1;

- floppy->srfp = pc.buf[8 + 2] & 0x40;
+ if (pc.buf[8 + 2] & 0x40)
+ drive->atapi_flags |= IDE_AFLAG_SRFP;
+
return 0;
}

@@ -819,7 +823,7 @@ static int ide_floppy_get_format_progres
struct ide_atapi_pc pc;
int progress_indication = 0x10000;

- if (floppy->srfp) {
+ if (drive->atapi_flags & IDE_AFLAG_SRFP) {
idefloppy_create_request_sense_cmd(&pc);
if (ide_queue_pc_tail(drive, floppy->disk, &pc))
return -EIO;
@@ -1043,7 +1047,7 @@ static int idefloppy_open(struct inode *
goto out_put_floppy;
}

- if (floppy->wp && (filp->f_mode & 2)) {
+ if ((drive->atapi_flags & IDE_AFLAG_WP) && (filp->f_mode & 2)) {
ret = -EROFS;
goto out_put_floppy;
}
Index: b/include/linux/ide.h
===================================================================
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -356,19 +356,23 @@ enum {
IDE_AFLAG_CLIK_DRIVE = (1 << 19),
/* Requires BH algorithm for packets */
IDE_AFLAG_ZIP_DRIVE = (1 << 20),
+ /* Write protect */
+ IDE_AFLAG_WP = (1 << 21),
+ /* Supports format progress report */
+ IDE_AFLAG_SRFP = (1 << 22),

/* ide-tape */
- IDE_AFLAG_IGNORE_DSC = (1 << 21),
+ IDE_AFLAG_IGNORE_DSC = (1 << 23),
/* 0 When the tape position is unknown */
- IDE_AFLAG_ADDRESS_VALID = (1 << 22),
+ IDE_AFLAG_ADDRESS_VALID = (1 << 24),
/* Device already opened */
- IDE_AFLAG_BUSY = (1 << 23),
+ IDE_AFLAG_BUSY = (1 << 25),
/* Attempt to auto-detect the current user block size */
- IDE_AFLAG_DETECT_BS = (1 << 24),
+ IDE_AFLAG_DETECT_BS = (1 << 26),
/* Currently on a filemark */
- IDE_AFLAG_FILEMARK = (1 << 25),
+ IDE_AFLAG_FILEMARK = (1 << 27),
/* 0 = no tape is loaded, so we don't rewind after ejecting */
- IDE_AFLAG_MEDIUM_PRESENT = (1 << 26)
+ IDE_AFLAG_MEDIUM_PRESENT = (1 << 28)
};

struct ide_drive_s {

Subject: [PATCH 10/22] ide-floppy: move floppy ioctls handling to ide-floppy_ioctl.c

While at it:

- idefloppy_create_read_capacity_cmd() -> ide_floppy_create_read_capacity_cmd()
- idefloppy_create_mode_sense_cmd() -> ide_floppy_create_mode_sense_cmd()
- idefloppy_create_request_sense_cmd() -> ide_floppy_create_request_sense_cmd()
- idefloppy_create_format_unit_cmd() -> ide_floppy_create_format_unit_cmd()
- idefloppy_get_sfrp_bit() -> ide_floppy_get_sfrp_bit()

Cc: Borislav Petkov <[email protected]>
Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
drivers/ide/Makefile | 3
drivers/ide/ide-floppy.c | 296 +----------------------------------------
drivers/ide/ide-floppy.h | 63 ++++++++
drivers/ide/ide-floppy_ioctl.c | 243 +++++++++++++++++++++++++++++++++
4 files changed, 317 insertions(+), 288 deletions(-)

Index: b/drivers/ide/Makefile
===================================================================
--- a/drivers/ide/Makefile
+++ b/drivers/ide/Makefile
@@ -37,11 +37,12 @@ obj-$(CONFIG_IDE_GENERIC) += ide-generi
obj-$(CONFIG_BLK_DEV_IDEPNP) += ide-pnp.o

ide-cd_mod-y += ide-cd.o ide-cd_ioctl.o ide-cd_verbose.o
+ide-floppy_mod-y += ide-floppy.o ide-floppy_ioctl.o

obj-$(CONFIG_BLK_DEV_IDEDISK) += ide-disk.o
obj-$(CONFIG_BLK_DEV_IDECD) += ide-cd_mod.o
+obj-$(CONFIG_BLK_DEV_IDEFLOPPY) += ide-floppy_mod.o
obj-$(CONFIG_BLK_DEV_IDETAPE) += ide-tape.o
-obj-$(CONFIG_BLK_DEV_IDEFLOPPY) += ide-floppy.o

ifeq ($(CONFIG_BLK_DEV_IDECS), y)
ide-cs-core-y += legacy/ide-cs.o
Index: b/drivers/ide/ide-floppy.c
===================================================================
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -45,6 +45,8 @@
#include <linux/io.h>
#include <asm/unaligned.h>

+#include "ide-floppy.h"
+
/* define to see debug info */
#define IDEFLOPPY_DEBUG_LOG 0

@@ -74,61 +76,11 @@
#define CAPACITY_CURRENT 0x02
#define CAPACITY_NO_CARTRIDGE 0x03

-/*
- * Most of our global data which we need to save even as we leave the driver
- * due to an interrupt or a timer event is stored in a variable of type
- * idefloppy_floppy_t, defined below.
- */
-typedef struct ide_floppy_obj {
- ide_drive_t *drive;
- ide_driver_t *driver;
- struct gendisk *disk;
- struct kref kref;
- unsigned int openers; /* protected by BKL for now */
-
- /* Current packet command */
- struct ide_atapi_pc *pc;
- /* Last failed packet command */
- struct ide_atapi_pc *failed_pc;
- /* used for blk_{fs,pc}_request() requests */
- struct ide_atapi_pc queued_pc;
-
- struct ide_atapi_pc request_sense_pc;
- struct request request_sense_rq;
-
- /* Last error information */
- u8 sense_key, asc, ascq;
- /* delay this long before sending packet command */
- u8 ticks;
- int progress_indication;
-
- /* Device information */
- /* Current format */
- int blocks, block_size, bs_factor;
- /* Last format capacity descriptor */
- u8 cap_desc[8];
- /* Copy of the flexible disk page */
- u8 flexible_disk_page[32];
-} idefloppy_floppy_t;
-
#define IDEFLOPPY_TICKS_DELAY HZ/20 /* default delay for ZIP 100 (50ms) */

-/* IOCTLs used in low-level formatting. */
-#define IDEFLOPPY_IOCTL_FORMAT_SUPPORTED 0x4600
-#define IDEFLOPPY_IOCTL_FORMAT_GET_CAPACITY 0x4601
-#define IDEFLOPPY_IOCTL_FORMAT_START 0x4602
-#define IDEFLOPPY_IOCTL_FORMAT_GET_PROGRESS 0x4603
-
/* Error code returned in rq->errors to the higher part of the driver. */
#define IDEFLOPPY_ERROR_GENERAL 101

-/*
- * Pages of the SELECT SENSE / MODE SENSE packet commands.
- * See SFF-8070i spec.
- */
-#define IDEFLOPPY_CAPABILITIES_PAGE 0x1b
-#define IDEFLOPPY_FLEXIBLE_DISK_PAGE 0x05
-
static DEFINE_MUTEX(idefloppy_ref_mutex);

#define to_ide_floppy(obj) container_of(obj, struct ide_floppy_obj, kref)
@@ -244,7 +196,7 @@ static void ide_floppy_callback(ide_driv
idefloppy_end_request(drive, uptodate, 0);
}

-static void idefloppy_create_request_sense_cmd(struct ide_atapi_pc *pc)
+void ide_floppy_create_request_sense_cmd(struct ide_atapi_pc *pc)
{
ide_init_pc(pc);
pc->c[0] = GPCMD_REQUEST_SENSE;
@@ -263,7 +215,7 @@ static void idefloppy_retry_pc(ide_drive
struct ide_atapi_pc *pc = &floppy->request_sense_pc;

(void)ide_read_error(drive);
- idefloppy_create_request_sense_cmd(pc);
+ ide_floppy_create_request_sense_cmd(pc);
ide_queue_pc_head(drive, floppy->disk, pc, rq);
}

@@ -381,7 +333,7 @@ static void idefloppy_create_prevent_cmd
pc->c[4] = prevent;
}

-static void idefloppy_create_read_capacity_cmd(struct ide_atapi_pc *pc)
+void ide_floppy_create_read_capacity_cmd(struct ide_atapi_pc *pc)
{
ide_init_pc(pc);
pc->c[0] = GPCMD_READ_FORMAT_CAPACITIES;
@@ -390,30 +342,8 @@ static void idefloppy_create_read_capaci
pc->req_xfer = 255;
}

-static void idefloppy_create_format_unit_cmd(struct ide_atapi_pc *pc, int b,
- int l, int flags)
-{
- ide_init_pc(pc);
- pc->c[0] = GPCMD_FORMAT_UNIT;
- pc->c[1] = 0x17;
-
- memset(pc->buf, 0, 12);
- pc->buf[1] = 0xA2;
- /* Default format list header, u8 1: FOV/DCRT/IMM bits set */
-
- if (flags & 1) /* Verify bit on... */
- pc->buf[1] ^= 0x20; /* ... turn off DCRT bit */
- pc->buf[3] = 8;
-
- put_unaligned(cpu_to_be32(b), (unsigned int *)(&pc->buf[4]));
- put_unaligned(cpu_to_be32(l), (unsigned int *)(&pc->buf[8]));
- pc->buf_size = 12;
- pc->flags |= PC_FLAG_WRITING;
-}
-
/* A mode sense command is used to "sense" floppy parameters. */
-static void idefloppy_create_mode_sense_cmd(struct ide_atapi_pc *pc,
- u8 page_code)
+void ide_floppy_create_mode_sense_cmd(struct ide_atapi_pc *pc, u8 page_code)
{
u16 length = 8; /* sizeof(Mode Parameter Header) = 8 Bytes */

@@ -562,7 +492,7 @@ static int ide_floppy_get_flexible_disk_
u16 transfer_rate, sector_size, cyls, rpm;
u8 heads, sectors;

- idefloppy_create_mode_sense_cmd(&pc, IDEFLOPPY_FLEXIBLE_DISK_PAGE);
+ ide_floppy_create_mode_sense_cmd(&pc, IDEFLOPPY_FLEXIBLE_DISK_PAGE);

if (ide_queue_pc_tail(drive, disk, &pc)) {
printk(KERN_ERR "ide-floppy: Can't get flexible disk page"
@@ -610,25 +540,6 @@ static int ide_floppy_get_flexible_disk_
return 0;
}

-static int idefloppy_get_sfrp_bit(ide_drive_t *drive)
-{
- idefloppy_floppy_t *floppy = drive->driver_data;
- struct ide_atapi_pc pc;
-
- drive->atapi_flags &= ~IDE_AFLAG_SRFP;
-
- idefloppy_create_mode_sense_cmd(&pc, IDEFLOPPY_CAPABILITIES_PAGE);
- pc.flags |= PC_FLAG_SUPPRESS_ERROR;
-
- if (ide_queue_pc_tail(drive, floppy->disk, &pc))
- return 1;
-
- if (pc.buf[8 + 2] & 0x40)
- drive->atapi_flags |= IDE_AFLAG_SRFP;
-
- return 0;
-}
-
/*
* Determine if a media is present in the floppy drive, and if so, its LBA
* capacity.
@@ -648,7 +559,7 @@ static int ide_floppy_get_capacity(ide_d
floppy->bs_factor = 1;
set_capacity(floppy->disk, 0);

- idefloppy_create_read_capacity_cmd(&pc);
+ ide_floppy_create_read_capacity_cmd(&pc);
if (ide_queue_pc_tail(drive, disk, &pc)) {
printk(KERN_ERR "ide-floppy: Can't get floppy parameters\n");
return 1;
@@ -729,129 +640,6 @@ static int ide_floppy_get_capacity(ide_d
return rc;
}

-/*
- * Obtain the list of formattable capacities.
- * Very similar to ide_floppy_get_capacity, except that we push the capacity
- * descriptors to userland, instead of our own structures.
- *
- * Userland gives us the following structure:
- *
- * struct idefloppy_format_capacities {
- * int nformats;
- * struct {
- * int nblocks;
- * int blocksize;
- * } formats[];
- * };
- *
- * userland initializes nformats to the number of allocated formats[] records.
- * On exit we set nformats to the number of records we've actually initialized.
- */
-
-static int ide_floppy_get_format_capacities(ide_drive_t *drive, int __user *arg)
-{
- struct ide_floppy_obj *floppy = drive->driver_data;
- struct ide_atapi_pc pc;
- u8 header_len, desc_cnt;
- int i, blocks, length, u_array_size, u_index;
- int __user *argp;
-
- if (get_user(u_array_size, arg))
- return -EFAULT;
-
- if (u_array_size <= 0)
- return -EINVAL;
-
- idefloppy_create_read_capacity_cmd(&pc);
- if (ide_queue_pc_tail(drive, floppy->disk, &pc)) {
- printk(KERN_ERR "ide-floppy: Can't get floppy parameters\n");
- return -EIO;
- }
-
- header_len = pc.buf[3];
- desc_cnt = header_len / 8; /* capacity descriptor of 8 bytes */
-
- u_index = 0;
- argp = arg + 1;
-
- /*
- * We always skip the first capacity descriptor. That's the current
- * capacity. We are interested in the remaining descriptors, the
- * formattable capacities.
- */
- for (i = 1; i < desc_cnt; i++) {
- unsigned int desc_start = 4 + i*8;
-
- if (u_index >= u_array_size)
- break; /* User-supplied buffer too small */
-
- blocks = be32_to_cpup((__be32 *)&pc.buf[desc_start]);
- length = be16_to_cpup((__be16 *)&pc.buf[desc_start + 6]);
-
- if (put_user(blocks, argp))
- return -EFAULT;
-
- ++argp;
-
- if (put_user(length, argp))
- return -EFAULT;
-
- ++argp;
-
- ++u_index;
- }
-
- if (put_user(u_index, arg))
- return -EFAULT;
-
- return 0;
-}
-
-/*
- * Get ATAPI_FORMAT_UNIT progress indication.
- *
- * Userland gives a pointer to an int. The int is set to a progress
- * indicator 0-65536, with 65536=100%.
- *
- * If the drive does not support format progress indication, we just check
- * the dsc bit, and return either 0 or 65536.
- */
-
-static int ide_floppy_get_format_progress(ide_drive_t *drive, int __user *arg)
-{
- idefloppy_floppy_t *floppy = drive->driver_data;
- struct ide_atapi_pc pc;
- int progress_indication = 0x10000;
-
- if (drive->atapi_flags & IDE_AFLAG_SRFP) {
- idefloppy_create_request_sense_cmd(&pc);
- if (ide_queue_pc_tail(drive, floppy->disk, &pc))
- return -EIO;
-
- if (floppy->sense_key == 2 &&
- floppy->asc == 4 &&
- floppy->ascq == 4)
- progress_indication = floppy->progress_indication;
-
- /* Else assume format_unit has finished, and we're at 0x10000 */
- } else {
- ide_hwif_t *hwif = drive->hwif;
- unsigned long flags;
- u8 stat;
-
- local_irq_save(flags);
- stat = hwif->tp_ops->read_status(hwif);
- local_irq_restore(flags);
-
- progress_indication = ((stat & ATA_DSC) == 0) ? 0 : 0x10000;
- }
-
- if (put_user(progress_indication, arg))
- return -EFAULT;
-
- return 0;
-}
-
static sector_t idefloppy_capacity(ide_drive_t *drive)
{
idefloppy_floppy_t *floppy = drive->driver_data;
@@ -1117,73 +905,6 @@ static int ide_floppy_lockdoor(ide_drive
return 0;
}

-static int ide_floppy_format_unit(ide_drive_t *drive, int __user *arg)
-{
- idefloppy_floppy_t *floppy = drive->driver_data;
- struct ide_atapi_pc pc;
- int blocks, length, flags, err = 0;
-
- if (floppy->openers > 1) {
- /* Don't format if someone is using the disk */
- drive->atapi_flags &= ~IDE_AFLAG_FORMAT_IN_PROGRESS;
- return -EBUSY;
- }
-
- drive->atapi_flags |= IDE_AFLAG_FORMAT_IN_PROGRESS;
-
- /*
- * Send ATAPI_FORMAT_UNIT to the drive.
- *
- * Userland gives us the following structure:
- *
- * struct idefloppy_format_command {
- * int nblocks;
- * int blocksize;
- * int flags;
- * } ;
- *
- * flags is a bitmask, currently, the only defined flag is:
- *
- * 0x01 - verify media after format.
- */
- if (get_user(blocks, arg) ||
- get_user(length, arg+1) ||
- get_user(flags, arg+2)) {
- err = -EFAULT;
- goto out;
- }
-
- (void) idefloppy_get_sfrp_bit(drive);
- idefloppy_create_format_unit_cmd(&pc, blocks, length, flags);
-
- if (ide_queue_pc_tail(drive, floppy->disk, &pc))
- err = -EIO;
-
-out:
- if (err)
- drive->atapi_flags &= ~IDE_AFLAG_FORMAT_IN_PROGRESS;
- return err;
-}
-
-static int ide_floppy_format_ioctl(ide_drive_t *drive, struct file *file,
- unsigned int cmd, void __user *argp)
-{
- switch (cmd) {
- case IDEFLOPPY_IOCTL_FORMAT_SUPPORTED:
- return 0;
- case IDEFLOPPY_IOCTL_FORMAT_GET_CAPACITY:
- return ide_floppy_get_format_capacities(drive, argp);
- case IDEFLOPPY_IOCTL_FORMAT_START:
- if (!(file->f_mode & 2))
- return -EPERM;
- return ide_floppy_format_unit(drive, (int __user *)argp);
- case IDEFLOPPY_IOCTL_FORMAT_GET_PROGRESS:
- return ide_floppy_get_format_progress(drive, argp);
- default:
- return -ENOTTY;
- }
-}
-
static int idefloppy_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
@@ -1315,6 +1036,7 @@ static int __init idefloppy_init(void)
}

MODULE_ALIAS("ide:*m-floppy*");
+MODULE_ALIAS("ide-floppy");
module_init(idefloppy_init);
module_exit(idefloppy_exit);
MODULE_LICENSE("GPL");
Index: b/drivers/ide/ide-floppy.h
===================================================================
--- /dev/null
+++ b/drivers/ide/ide-floppy.h
@@ -0,0 +1,63 @@
+#ifndef __IDE_FLOPPY_H
+#define __IDE_FLOPPY_H
+
+/*
+ * Most of our global data which we need to save even as we leave the driver
+ * due to an interrupt or a timer event is stored in a variable of type
+ * idefloppy_floppy_t, defined below.
+ */
+typedef struct ide_floppy_obj {
+ ide_drive_t *drive;
+ ide_driver_t *driver;
+ struct gendisk *disk;
+ struct kref kref;
+ unsigned int openers; /* protected by BKL for now */
+
+ /* Current packet command */
+ struct ide_atapi_pc *pc;
+ /* Last failed packet command */
+ struct ide_atapi_pc *failed_pc;
+ /* used for blk_{fs,pc}_request() requests */
+ struct ide_atapi_pc queued_pc;
+
+ struct ide_atapi_pc request_sense_pc;
+ struct request request_sense_rq;
+
+ /* Last error information */
+ u8 sense_key, asc, ascq;
+ /* delay this long before sending packet command */
+ u8 ticks;
+ int progress_indication;
+
+ /* Device information */
+ /* Current format */
+ int blocks, block_size, bs_factor;
+ /* Last format capacity descriptor */
+ u8 cap_desc[8];
+ /* Copy of the flexible disk page */
+ u8 flexible_disk_page[32];
+} idefloppy_floppy_t;
+
+/*
+ * Pages of the SELECT SENSE / MODE SENSE packet commands.
+ * See SFF-8070i spec.
+ */
+#define IDEFLOPPY_CAPABILITIES_PAGE 0x1b
+#define IDEFLOPPY_FLEXIBLE_DISK_PAGE 0x05
+
+/* IOCTLs used in low-level formatting. */
+#define IDEFLOPPY_IOCTL_FORMAT_SUPPORTED 0x4600
+#define IDEFLOPPY_IOCTL_FORMAT_GET_CAPACITY 0x4601
+#define IDEFLOPPY_IOCTL_FORMAT_START 0x4602
+#define IDEFLOPPY_IOCTL_FORMAT_GET_PROGRESS 0x4603
+
+/* ide-floppy.c */
+void ide_floppy_create_mode_sense_cmd(struct ide_atapi_pc *, u8);
+void ide_floppy_create_read_capacity_cmd(struct ide_atapi_pc *);
+void ide_floppy_create_request_sense_cmd(struct ide_atapi_pc *);
+
+/* ide-floppy_ioctl.c */
+int ide_floppy_format_ioctl(ide_drive_t *, struct file *, unsigned int,
+ void __user *);
+
+#endif /*__IDE_FLOPPY_H */
Index: b/drivers/ide/ide-floppy_ioctl.c
===================================================================
--- /dev/null
+++ b/drivers/ide/ide-floppy_ioctl.c
@@ -0,0 +1,243 @@
+/*
+ * ide-floppy IOCTLs handling.
+ */
+
+#include <linux/kernel.h>
+#include <linux/ide.h>
+#include <linux/cdrom.h>
+
+#include <asm/unaligned.h>
+
+#include <scsi/scsi_ioctl.h>
+
+#include "ide-floppy.h"
+
+/*
+ * Obtain the list of formattable capacities.
+ * Very similar to ide_floppy_get_capacity, except that we push the capacity
+ * descriptors to userland, instead of our own structures.
+ *
+ * Userland gives us the following structure:
+ *
+ * struct idefloppy_format_capacities {
+ * int nformats;
+ * struct {
+ * int nblocks;
+ * int blocksize;
+ * } formats[];
+ * };
+ *
+ * userland initializes nformats to the number of allocated formats[] records.
+ * On exit we set nformats to the number of records we've actually initialized.
+ */
+
+static int ide_floppy_get_format_capacities(ide_drive_t *drive, int __user *arg)
+{
+ struct ide_floppy_obj *floppy = drive->driver_data;
+ struct ide_atapi_pc pc;
+ u8 header_len, desc_cnt;
+ int i, blocks, length, u_array_size, u_index;
+ int __user *argp;
+
+ if (get_user(u_array_size, arg))
+ return -EFAULT;
+
+ if (u_array_size <= 0)
+ return -EINVAL;
+
+ ide_floppy_create_read_capacity_cmd(&pc);
+ if (ide_queue_pc_tail(drive, floppy->disk, &pc)) {
+ printk(KERN_ERR "ide-floppy: Can't get floppy parameters\n");
+ return -EIO;
+ }
+
+ header_len = pc.buf[3];
+ desc_cnt = header_len / 8; /* capacity descriptor of 8 bytes */
+
+ u_index = 0;
+ argp = arg + 1;
+
+ /*
+ * We always skip the first capacity descriptor. That's the current
+ * capacity. We are interested in the remaining descriptors, the
+ * formattable capacities.
+ */
+ for (i = 1; i < desc_cnt; i++) {
+ unsigned int desc_start = 4 + i*8;
+
+ if (u_index >= u_array_size)
+ break; /* User-supplied buffer too small */
+
+ blocks = be32_to_cpup((__be32 *)&pc.buf[desc_start]);
+ length = be16_to_cpup((__be16 *)&pc.buf[desc_start + 6]);
+
+ if (put_user(blocks, argp))
+ return -EFAULT;
+
+ ++argp;
+
+ if (put_user(length, argp))
+ return -EFAULT;
+
+ ++argp;
+
+ ++u_index;
+ }
+
+ if (put_user(u_index, arg))
+ return -EFAULT;
+
+ return 0;
+}
+
+static void ide_floppy_create_format_unit_cmd(struct ide_atapi_pc *pc, int b,
+ int l, int flags)
+{
+ ide_init_pc(pc);
+ pc->c[0] = GPCMD_FORMAT_UNIT;
+ pc->c[1] = 0x17;
+
+ memset(pc->buf, 0, 12);
+ pc->buf[1] = 0xA2;
+ /* Default format list header, u8 1: FOV/DCRT/IMM bits set */
+
+ if (flags & 1) /* Verify bit on... */
+ pc->buf[1] ^= 0x20; /* ... turn off DCRT bit */
+ pc->buf[3] = 8;
+
+ put_unaligned(cpu_to_be32(b), (unsigned int *)(&pc->buf[4]));
+ put_unaligned(cpu_to_be32(l), (unsigned int *)(&pc->buf[8]));
+ pc->buf_size = 12;
+ pc->flags |= PC_FLAG_WRITING;
+}
+
+static int ide_floppy_get_sfrp_bit(ide_drive_t *drive)
+{
+ idefloppy_floppy_t *floppy = drive->driver_data;
+ struct ide_atapi_pc pc;
+
+ drive->atapi_flags &= ~IDE_AFLAG_SRFP;
+
+ ide_floppy_create_mode_sense_cmd(&pc, IDEFLOPPY_CAPABILITIES_PAGE);
+ pc.flags |= PC_FLAG_SUPPRESS_ERROR;
+
+ if (ide_queue_pc_tail(drive, floppy->disk, &pc))
+ return 1;
+
+ if (pc.buf[8 + 2] & 0x40)
+ drive->atapi_flags |= IDE_AFLAG_SRFP;
+
+ return 0;
+}
+
+static int ide_floppy_format_unit(ide_drive_t *drive, int __user *arg)
+{
+ idefloppy_floppy_t *floppy = drive->driver_data;
+ struct ide_atapi_pc pc;
+ int blocks, length, flags, err = 0;
+
+ if (floppy->openers > 1) {
+ /* Don't format if someone is using the disk */
+ drive->atapi_flags &= ~IDE_AFLAG_FORMAT_IN_PROGRESS;
+ return -EBUSY;
+ }
+
+ drive->atapi_flags |= IDE_AFLAG_FORMAT_IN_PROGRESS;
+
+ /*
+ * Send ATAPI_FORMAT_UNIT to the drive.
+ *
+ * Userland gives us the following structure:
+ *
+ * struct idefloppy_format_command {
+ * int nblocks;
+ * int blocksize;
+ * int flags;
+ * } ;
+ *
+ * flags is a bitmask, currently, the only defined flag is:
+ *
+ * 0x01 - verify media after format.
+ */
+ if (get_user(blocks, arg) ||
+ get_user(length, arg+1) ||
+ get_user(flags, arg+2)) {
+ err = -EFAULT;
+ goto out;
+ }
+
+ (void)ide_floppy_get_sfrp_bit(drive);
+ ide_floppy_create_format_unit_cmd(&pc, blocks, length, flags);
+
+ if (ide_queue_pc_tail(drive, floppy->disk, &pc))
+ err = -EIO;
+
+out:
+ if (err)
+ drive->atapi_flags &= ~IDE_AFLAG_FORMAT_IN_PROGRESS;
+ return err;
+}
+
+/*
+ * Get ATAPI_FORMAT_UNIT progress indication.
+ *
+ * Userland gives a pointer to an int. The int is set to a progress
+ * indicator 0-65536, with 65536=100%.
+ *
+ * If the drive does not support format progress indication, we just check
+ * the dsc bit, and return either 0 or 65536.
+ */
+
+static int ide_floppy_get_format_progress(ide_drive_t *drive, int __user *arg)
+{
+ idefloppy_floppy_t *floppy = drive->driver_data;
+ struct ide_atapi_pc pc;
+ int progress_indication = 0x10000;
+
+ if (drive->atapi_flags & IDE_AFLAG_SRFP) {
+ ide_floppy_create_request_sense_cmd(&pc);
+ if (ide_queue_pc_tail(drive, floppy->disk, &pc))
+ return -EIO;
+
+ if (floppy->sense_key == 2 &&
+ floppy->asc == 4 &&
+ floppy->ascq == 4)
+ progress_indication = floppy->progress_indication;
+
+ /* Else assume format_unit has finished, and we're at 0x10000 */
+ } else {
+ ide_hwif_t *hwif = drive->hwif;
+ unsigned long flags;
+ u8 stat;
+
+ local_irq_save(flags);
+ stat = hwif->tp_ops->read_status(hwif);
+ local_irq_restore(flags);
+
+ progress_indication = ((stat & ATA_DSC) == 0) ? 0 : 0x10000;
+ }
+
+ if (put_user(progress_indication, arg))
+ return -EFAULT;
+
+ return 0;
+}
+
+int ide_floppy_format_ioctl(ide_drive_t *drive, struct file *file,
+ unsigned int cmd, void __user *argp)
+{
+ switch (cmd) {
+ case IDEFLOPPY_IOCTL_FORMAT_SUPPORTED:
+ return 0;
+ case IDEFLOPPY_IOCTL_FORMAT_GET_CAPACITY:
+ return ide_floppy_get_format_capacities(drive, argp);
+ case IDEFLOPPY_IOCTL_FORMAT_START:
+ if (!(file->f_mode & 2))
+ return -EPERM;
+ return ide_floppy_format_unit(drive, (int __user *)argp);
+ case IDEFLOPPY_IOCTL_FORMAT_GET_PROGRESS:
+ return ide_floppy_get_format_progress(drive, argp);
+ default:
+ return -ENOTTY;
+ }
+}

Subject: [PATCH 11/22] ide: add ide_set_media_lock() helper

* Set IDE_AFLAG_NO_DOORLOCK in idetape_get_mode_sense_result(), check it
in ide_tape_set_media_lock() and cleanup idetape_create_prevent_cmd().

* Set IDE_AFLAG_NO_DOORLOCK in ide_floppy_create_read_capacity_cmd() and
check it instead of IDE_AFLAG_CLIK_DRIVE in ide_floppy_set_media_lock().

* Add ide_set_media_lock() helper and convert ide-{floppy,tape}.c to use it.

* Remove no longer used ide*_create_prevent_cmd()/ide*_set_media_lock().

* Update comment in <linux/ide.h> accordingly.

Cc: Borislav Petkov <[email protected]>
Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
drivers/ide/ide-atapi.c | 15 +++++++++++++++
drivers/ide/ide-floppy.c | 32 +++++++-------------------------
drivers/ide/ide-tape.c | 41 ++++++++++-------------------------------
include/linux/ide.h | 6 ++++--
4 files changed, 36 insertions(+), 58 deletions(-)

Index: b/drivers/ide/ide-atapi.c
===================================================================
--- a/drivers/ide/ide-atapi.c
+++ b/drivers/ide/ide-atapi.c
@@ -162,6 +162,21 @@ int ide_queue_pc_tail(ide_drive_t *drive
}
EXPORT_SYMBOL_GPL(ide_queue_pc_tail);

+int ide_set_media_lock(ide_drive_t *drive, struct gendisk *disk, int on)
+{
+ struct ide_atapi_pc pc;
+
+ if (drive->atapi_flags & IDE_AFLAG_NO_DOORLOCK)
+ return 0;
+
+ ide_init_pc(&pc);
+ pc.c[0] = ALLOW_MEDIUM_REMOVAL;
+ pc.c[4] = on;
+
+ return ide_queue_pc_tail(drive, disk, &pc);
+}
+EXPORT_SYMBOL_GPL(ide_set_media_lock);
+
/* TODO: unify the code thus making some arguments go away */
ide_startstop_t ide_pc_intr(ide_drive_t *drive, struct ide_atapi_pc *pc,
ide_handler_t *handler, unsigned int timeout, ide_expiry_t *expiry,
Index: b/drivers/ide/ide-floppy.c
===================================================================
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -324,15 +324,6 @@ static ide_startstop_t idefloppy_issue_p
IDEFLOPPY_WAIT_CMD, NULL);
}

-static void idefloppy_create_prevent_cmd(struct ide_atapi_pc *pc, int prevent)
-{
- debug_log("creating prevent removal command, prevent = %d\n", prevent);
-
- ide_init_pc(pc);
- pc->c[0] = GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL;
- pc->c[4] = prevent;
-}
-
void ide_floppy_create_read_capacity_cmd(struct ide_atapi_pc *pc)
{
ide_init_pc(pc);
@@ -711,6 +702,8 @@ static void idefloppy_setup(ide_drive_t
if (strncmp((char *)&id[ATA_ID_PROD], "IOMEGA Clik!", 11) == 0) {
blk_queue_max_sectors(drive->queue, 64);
drive->atapi_flags |= IDE_AFLAG_CLIK_DRIVE;
+ /* IOMEGA Clik! drives do not support lock/unlock commands */
+ drive->atapi_flags |= IDE_AFLAG_NO_DOORLOCK;
}

(void) ide_floppy_get_capacity(drive);
@@ -781,18 +774,6 @@ static ide_driver_t idefloppy_driver = {
#endif
};

-static void ide_floppy_set_media_lock(ide_drive_t *drive, int on)
-{
- struct ide_floppy_obj *floppy = drive->driver_data;
- struct ide_atapi_pc pc;
-
- /* IOMEGA Clik! drives do not support lock/unlock commands */
- if ((drive->atapi_flags & IDE_AFLAG_CLIK_DRIVE) == 0) {
- idefloppy_create_prevent_cmd(&pc, on);
- (void)ide_queue_pc_tail(drive, floppy->disk, &pc);
- }
-}
-
static int idefloppy_open(struct inode *inode, struct file *filp)
{
struct gendisk *disk = inode->i_bdev->bd_disk;
@@ -841,7 +822,7 @@ static int idefloppy_open(struct inode *
}

drive->atapi_flags |= IDE_AFLAG_MEDIA_CHANGED;
- ide_floppy_set_media_lock(drive, 1);
+ ide_set_media_lock(drive, disk, 1);
check_disk_change(inode->i_bdev);
} else if (drive->atapi_flags & IDE_AFLAG_FORMAT_IN_PROGRESS) {
ret = -EBUSY;
@@ -864,7 +845,7 @@ static int idefloppy_release(struct inod
debug_log("Reached %s\n", __func__);

if (floppy->openers == 1) {
- ide_floppy_set_media_lock(drive, 0);
+ ide_set_media_lock(drive, disk, 0);
drive->atapi_flags &= ~IDE_AFLAG_FORMAT_IN_PROGRESS;
}

@@ -890,16 +871,17 @@ static int ide_floppy_lockdoor(ide_drive
unsigned long arg, unsigned int cmd)
{
idefloppy_floppy_t *floppy = drive->driver_data;
+ struct gendisk *disk = floppy->disk;
int prevent = (arg && cmd != CDROMEJECT) ? 1 : 0;

if (floppy->openers > 1)
return -EBUSY;

- ide_floppy_set_media_lock(drive, prevent);
+ ide_set_media_lock(drive, disk, prevent);

if (cmd == CDROMEJECT) {
idefloppy_create_start_stop_cmd(pc, 2);
- (void)ide_queue_pc_tail(drive, floppy->disk, pc);
+ (void)ide_queue_pc_tail(drive, disk, pc);
}

return 0;
Index: b/drivers/ide/ide-tape.c
===================================================================
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -1213,32 +1213,6 @@ static void idetape_create_locate_cmd(id
pc->flags |= PC_FLAG_WAIT_FOR_DSC;
}

-static int idetape_create_prevent_cmd(ide_drive_t *drive,
- struct ide_atapi_pc *pc, int prevent)
-{
- idetape_tape_t *tape = drive->driver_data;
-
- /* device supports locking according to capabilities page */
- if (!(tape->caps[6] & 0x01))
- return 0;
-
- ide_init_pc(pc);
- pc->c[0] = ALLOW_MEDIUM_REMOVAL;
- pc->c[4] = prevent;
- return 1;
-}
-
-static int ide_tape_set_media_lock(ide_drive_t *drive, int on)
-{
- struct ide_tape_obj *tape = drive->driver_data;
- struct ide_atapi_pc pc;
-
- if (!idetape_create_prevent_cmd(drive, &pc, on))
- return 0;
-
- return ide_queue_pc_tail(drive, tape->disk, &pc);
-}
-
static void __ide_tape_discard_merge_buffer(ide_drive_t *drive)
{
idetape_tape_t *tape = drive->driver_data;
@@ -1871,7 +1845,7 @@ static int idetape_mtioctop(ide_drive_t
* attempting to eject.
*/
if (tape->door_locked) {
- if (!ide_tape_set_media_lock(drive, 0))
+ if (!ide_set_media_lock(drive, disk, 0))
tape->door_locked = DOOR_UNLOCKED;
}
ide_tape_discard_merge_buffer(drive, 0);
@@ -1916,13 +1890,13 @@ static int idetape_mtioctop(ide_drive_t
case MTFSR:
case MTBSR:
case MTLOCK:
- retval = ide_tape_set_media_lock(drive, 1);
+ retval = ide_set_media_lock(drive, disk, 1);
if (retval)
return retval;
tape->door_locked = DOOR_EXPLICITLY_LOCKED;
return 0;
case MTUNLOCK:
- retval = ide_tape_set_media_lock(drive, 0);
+ retval = ide_set_media_lock(drive, disk, 0);
if (retval)
return retval;
tape->door_locked = DOOR_UNLOCKED;
@@ -2086,7 +2060,7 @@ static int idetape_chrdev_open(struct in

/* Lock the tape drive door so user can't eject. */
if (tape->chrdev_dir == IDETAPE_DIR_NONE) {
- if (!ide_tape_set_media_lock(drive, 1)) {
+ if (!ide_set_media_lock(drive, tape->disk, 1)) {
if (tape->door_locked != DOOR_EXPLICITLY_LOCKED)
tape->door_locked = DOOR_LOCKED;
}
@@ -2139,7 +2113,7 @@ static int idetape_chrdev_release(struct
(void) idetape_rewind_tape(drive);
if (tape->chrdev_dir == IDETAPE_DIR_NONE) {
if (tape->door_locked == DOOR_LOCKED) {
- if (!ide_tape_set_media_lock(drive, 0))
+ if (!ide_set_media_lock(drive, tape->disk, 0))
tape->door_locked = DOOR_UNLOCKED;
}
}
@@ -2217,6 +2191,11 @@ static void idetape_get_mode_sense_resul
}

memcpy(&tape->caps, caps, 20);
+
+ /* device lacks locking support according to capabilities page */
+ if ((caps[6] & 1) == 0)
+ drive->atapi_flags |= IDE_AFLAG_NO_DOORLOCK;
+
if (caps[7] & 0x02)
tape->blk_size = 512;
else if (caps[7] & 0x04)
Index: b/include/linux/ide.h
===================================================================
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -317,10 +317,10 @@ struct ide_acpi_hwif_link;
enum {
IDE_AFLAG_DRQ_INTERRUPT = (1 << 0),
IDE_AFLAG_MEDIA_CHANGED = (1 << 1),
-
- /* ide-cd */
/* Drive cannot lock the door. */
IDE_AFLAG_NO_DOORLOCK = (1 << 2),
+
+ /* ide-cd */
/* Drive cannot eject the disc. */
IDE_AFLAG_NO_EJECT = (1 << 3),
/* Drive is a pre ATAPI 1.2 drive. */
@@ -1140,6 +1140,8 @@ void ide_queue_pc_head(ide_drive_t *, st
struct request *);
int ide_queue_pc_tail(ide_drive_t *, struct gendisk *, struct ide_atapi_pc *);

+int ide_set_media_lock(ide_drive_t *, struct gendisk *, int);
+
ide_startstop_t ide_pc_intr(ide_drive_t *drive, struct ide_atapi_pc *pc,
ide_handler_t *handler, unsigned int timeout, ide_expiry_t *expiry,
void (*update_buffers)(ide_drive_t *, struct ide_atapi_pc *),

Subject: [PATCH 12/22] ide: add ide_do_start_stop() helper

* Add ide_do_start_stop() helper and convert ide-{floppy,tape}.c
to use it.

* Remove no longer used idefloppy_create_start_stop_cmd()
and idetape_create_load_unload_cmd().

There should be no functional changes caused by this patch.

Cc: Borislav Petkov <[email protected]>
Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
drivers/ide/ide-atapi.c | 15 +++++++++++++++
drivers/ide/ide-floppy.c | 19 ++++---------------
drivers/ide/ide-tape.c | 24 ++++--------------------
include/linux/ide.h | 1 +
4 files changed, 24 insertions(+), 35 deletions(-)

Index: b/drivers/ide/ide-atapi.c
===================================================================
--- a/drivers/ide/ide-atapi.c
+++ b/drivers/ide/ide-atapi.c
@@ -162,6 +162,21 @@ int ide_queue_pc_tail(ide_drive_t *drive
}
EXPORT_SYMBOL_GPL(ide_queue_pc_tail);

+int ide_do_start_stop(ide_drive_t *drive, struct gendisk *disk, int start)
+{
+ struct ide_atapi_pc pc;
+
+ ide_init_pc(&pc);
+ pc.c[0] = START_STOP;
+ pc.c[4] = start;
+
+ if (drive->media == ide_tape)
+ pc.flags |= PC_FLAG_WAIT_FOR_DSC;
+
+ return ide_queue_pc_tail(drive, disk, &pc);
+}
+EXPORT_SYMBOL_GPL(ide_do_start_stop);
+
int ide_set_media_lock(ide_drive_t *drive, struct gendisk *disk, int on)
{
struct ide_atapi_pc pc;
Index: b/drivers/ide/ide-floppy.c
===================================================================
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -358,13 +358,6 @@ void ide_floppy_create_mode_sense_cmd(st
pc->req_xfer = length;
}

-static void idefloppy_create_start_stop_cmd(struct ide_atapi_pc *pc, int start)
-{
- ide_init_pc(pc);
- pc->c[0] = GPCMD_START_STOP_UNIT;
- pc->c[4] = start;
-}
-
static void idefloppy_create_rw_cmd(idefloppy_floppy_t *floppy,
struct ide_atapi_pc *pc, struct request *rq,
unsigned long sector)
@@ -799,10 +792,8 @@ static int idefloppy_open(struct inode *
ide_init_pc(&pc);
pc.c[0] = GPCMD_TEST_UNIT_READY;

- if (ide_queue_pc_tail(drive, disk, &pc)) {
- idefloppy_create_start_stop_cmd(&pc, 1);
- (void)ide_queue_pc_tail(drive, disk, &pc);
- }
+ if (ide_queue_pc_tail(drive, disk, &pc))
+ ide_do_start_stop(drive, disk, 1);

if (ide_floppy_get_capacity(drive)
&& (filp->f_flags & O_NDELAY) == 0
@@ -879,10 +870,8 @@ static int ide_floppy_lockdoor(ide_drive

ide_set_media_lock(drive, disk, prevent);

- if (cmd == CDROMEJECT) {
- idefloppy_create_start_stop_cmd(pc, 2);
- (void)ide_queue_pc_tail(drive, disk, pc);
- }
+ if (cmd == CDROMEJECT)
+ ide_do_start_stop(drive, disk, 2);

return 0;
}
Index: b/drivers/ide/ide-tape.c
===================================================================
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -1124,15 +1124,6 @@ static void idetape_create_test_unit_rea
pc->c[0] = TEST_UNIT_READY;
}

-static void idetape_create_load_unload_cmd(ide_drive_t *drive,
- struct ide_atapi_pc *pc, int cmd)
-{
- ide_init_pc(pc);
- pc->c[0] = START_STOP;
- pc->c[4] = cmd;
- pc->flags |= PC_FLAG_WAIT_FOR_DSC;
-}
-
static int idetape_wait_ready(ide_drive_t *drive, unsigned long timeout)
{
idetape_tape_t *tape = drive->driver_data;
@@ -1152,9 +1143,7 @@ static int idetape_wait_ready(ide_drive_
/* no media */
if (load_attempted)
return -ENOMEDIUM;
- idetape_create_load_unload_cmd(drive, &pc,
- IDETAPE_LU_LOAD_MASK);
- ide_queue_pc_tail(drive, disk, &pc);
+ ide_do_start_stop(drive, disk, IDETAPE_LU_LOAD_MASK);
load_attempted = 1;
/* not about to be ready */
} else if (!(tape->sense_key == 2 && tape->asc == 4 &&
@@ -1835,9 +1824,7 @@ static int idetape_mtioctop(ide_drive_t
return 0;
case MTLOAD:
ide_tape_discard_merge_buffer(drive, 0);
- idetape_create_load_unload_cmd(drive, &pc,
- IDETAPE_LU_LOAD_MASK);
- return ide_queue_pc_tail(drive, disk, &pc);
+ return ide_do_start_stop(drive, disk, IDETAPE_LU_LOAD_MASK);
case MTUNLOAD:
case MTOFFL:
/*
@@ -1849,9 +1836,7 @@ static int idetape_mtioctop(ide_drive_t
tape->door_locked = DOOR_UNLOCKED;
}
ide_tape_discard_merge_buffer(drive, 0);
- idetape_create_load_unload_cmd(drive, &pc,
- !IDETAPE_LU_LOAD_MASK);
- retval = ide_queue_pc_tail(drive, disk, &pc);
+ retval = ide_do_start_stop(drive, disk, !IDETAPE_LU_LOAD_MASK);
if (!retval)
clear_bit(IDE_AFLAG_MEDIUM_PRESENT, &drive->atapi_flags);
return retval;
@@ -1860,9 +1845,8 @@ static int idetape_mtioctop(ide_drive_t
return idetape_flush_tape_buffers(drive);
case MTRETEN:
ide_tape_discard_merge_buffer(drive, 0);
- idetape_create_load_unload_cmd(drive, &pc,
+ return ide_do_start_stop(drive, disk,
IDETAPE_LU_RETENSION_MASK | IDETAPE_LU_LOAD_MASK);
- return ide_queue_pc_tail(drive, disk, &pc);
case MTEOM:
idetape_create_space_cmd(&pc, 0, IDETAPE_SPACE_TO_EOD);
return ide_queue_pc_tail(drive, disk, &pc);
Index: b/include/linux/ide.h
===================================================================
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -1140,6 +1140,7 @@ void ide_queue_pc_head(ide_drive_t *, st
struct request *);
int ide_queue_pc_tail(ide_drive_t *, struct gendisk *, struct ide_atapi_pc *);

+int ide_do_start_stop(ide_drive_t *, struct gendisk *, int);
int ide_set_media_lock(ide_drive_t *, struct gendisk *, int);

ide_startstop_t ide_pc_intr(ide_drive_t *drive, struct ide_atapi_pc *pc,

Subject: [PATCH 13/22] ide: add ide_do_test_unit_ready() helper

* Add ide_do_test_unit_ready() helper and convert ide-{floppy,tape}.c
to use it.

* Remove no longer used idetape_create_test_unit_ready_cmd().

There should be no functional changes caused by this patch.

Cc: Borislav Petkov <[email protected]>
Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
drivers/ide/ide-atapi.c | 11 +++++++++++
drivers/ide/ide-floppy.c | 6 +-----
drivers/ide/ide-tape.c | 10 +---------
include/linux/ide.h | 1 +
4 files changed, 14 insertions(+), 14 deletions(-)

Index: b/drivers/ide/ide-atapi.c
===================================================================
--- a/drivers/ide/ide-atapi.c
+++ b/drivers/ide/ide-atapi.c
@@ -162,6 +162,17 @@ int ide_queue_pc_tail(ide_drive_t *drive
}
EXPORT_SYMBOL_GPL(ide_queue_pc_tail);

+int ide_do_test_unit_ready(ide_drive_t *drive, struct gendisk *disk)
+{
+ struct ide_atapi_pc pc;
+
+ ide_init_pc(&pc);
+ pc.c[0] = TEST_UNIT_READY;
+
+ return ide_queue_pc_tail(drive, disk, &pc);
+}
+EXPORT_SYMBOL_GPL(ide_do_test_unit_ready);
+
int ide_do_start_stop(ide_drive_t *drive, struct gendisk *disk, int start)
{
struct ide_atapi_pc pc;
Index: b/drivers/ide/ide-floppy.c
===================================================================
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -772,7 +772,6 @@ static int idefloppy_open(struct inode *
struct gendisk *disk = inode->i_bdev->bd_disk;
struct ide_floppy_obj *floppy;
ide_drive_t *drive;
- struct ide_atapi_pc pc;
int ret = 0;

debug_log("Reached %s\n", __func__);
@@ -789,10 +788,7 @@ static int idefloppy_open(struct inode *
drive->atapi_flags &= ~IDE_AFLAG_FORMAT_IN_PROGRESS;
/* Just in case */

- ide_init_pc(&pc);
- pc.c[0] = GPCMD_TEST_UNIT_READY;
-
- if (ide_queue_pc_tail(drive, disk, &pc))
+ if (ide_do_test_unit_ready(drive, disk))
ide_do_start_stop(drive, disk, 1);

if (ide_floppy_get_capacity(drive)
Index: b/drivers/ide/ide-tape.c
===================================================================
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -1118,25 +1118,17 @@ static void idetape_create_write_filemar
pc->flags |= PC_FLAG_WAIT_FOR_DSC;
}

-static void idetape_create_test_unit_ready_cmd(struct ide_atapi_pc *pc)
-{
- ide_init_pc(pc);
- pc->c[0] = TEST_UNIT_READY;
-}
-
static int idetape_wait_ready(ide_drive_t *drive, unsigned long timeout)
{
idetape_tape_t *tape = drive->driver_data;
struct gendisk *disk = tape->disk;
- struct ide_atapi_pc pc;
int load_attempted = 0;

/* Wait for the tape to become ready */
set_bit(IDE_AFLAG_MEDIUM_PRESENT, &drive->atapi_flags);
timeout += jiffies;
while (time_before(jiffies, timeout)) {
- idetape_create_test_unit_ready_cmd(&pc);
- if (!ide_queue_pc_tail(drive, disk, &pc))
+ if (ide_do_test_unit_ready(drive, disk) == 0)
return 0;
if ((tape->sense_key == 2 && tape->asc == 4 && tape->ascq == 2)
|| (tape->asc == 0x3A)) {
Index: b/include/linux/ide.h
===================================================================
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -1140,6 +1140,7 @@ void ide_queue_pc_head(ide_drive_t *, st
struct request *);
int ide_queue_pc_tail(ide_drive_t *, struct gendisk *, struct ide_atapi_pc *);

+int ide_do_test_unit_ready(ide_drive_t *, struct gendisk *);
int ide_do_start_stop(ide_drive_t *, struct gendisk *, int);
int ide_set_media_lock(ide_drive_t *, struct gendisk *, int);

Subject: [PATCH 14/22] ide: move IDE{FLOPPY,TAPE}_WAIT_CMD defines to <linux/ide.h>

While at it:

* IDE{FLOPPY,TAPE}_WAIT_CMD -> WAIT_{FLOPPY,TAPE}_CMD

* Use enum for WAIT_* defines.

There should be no functional changes caused by this patch.

Cc: Borislav Petkov <[email protected]>
Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
drivers/ide/ide-floppy.c | 13 ++++---------
drivers/ide/ide-tape.c | 13 +++----------
include/linux/ide.h | 28 ++++++++++++++++++++++------
3 files changed, 29 insertions(+), 25 deletions(-)

Index: b/drivers/ide/ide-floppy.c
===================================================================
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -60,10 +60,6 @@
#define debug_log(fmt, args...) do {} while (0)
#endif

-
-/* Some drives require a longer irq timeout. */
-#define IDEFLOPPY_WAIT_CMD (5 * WAIT_CMD)
-
/*
* After each failed packet command we issue a request sense command and retry
* the packet command IDEFLOPPY_MAX_PC_RETRIES times.
@@ -225,7 +221,7 @@ static ide_startstop_t idefloppy_pc_intr
idefloppy_floppy_t *floppy = drive->driver_data;

return ide_pc_intr(drive, floppy->pc, idefloppy_pc_intr,
- IDEFLOPPY_WAIT_CMD, NULL, idefloppy_update_buffers,
+ WAIT_FLOPPY_CMD, NULL, idefloppy_update_buffers,
idefloppy_retry_pc, NULL, ide_io_buffers);
}

@@ -243,10 +239,9 @@ static int idefloppy_transfer_pc(ide_dri
drive->hwif->tp_ops->output_data(drive, NULL, floppy->pc->c, 12);

/* Timeout for the packet command */
- return IDEFLOPPY_WAIT_CMD;
+ return WAIT_FLOPPY_CMD;
}

-
/*
* Called as an interrupt (or directly). When the device says it's ready for a
* packet, we schedule the packet transfer to occur about 2-3 ticks later in
@@ -271,7 +266,7 @@ static ide_startstop_t idefloppy_start_p
timeout = floppy->ticks;
expiry = &idefloppy_transfer_pc;
} else {
- timeout = IDEFLOPPY_WAIT_CMD;
+ timeout = WAIT_FLOPPY_CMD;
expiry = NULL;
}

@@ -321,7 +316,7 @@ static ide_startstop_t idefloppy_issue_p
pc->retries++;

return ide_issue_pc(drive, pc, idefloppy_start_pc_transfer,
- IDEFLOPPY_WAIT_CMD, NULL);
+ WAIT_FLOPPY_CMD, NULL);
}

void ide_floppy_create_read_capacity_cmd(struct ide_atapi_pc *pc)
Index: b/drivers/ide/ide-tape.c
===================================================================
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -81,13 +81,6 @@ enum {
#define IDETAPE_MAX_PC_RETRIES 3

/*
- * Some drives (for example, Seagate STT3401A Travan) require a very long
- * timeout, because they don't return an interrupt or clear their busy bit
- * until after the command completes (even retension commands).
- */
-#define IDETAPE_WAIT_CMD (900*HZ)
-
-/*
* The following parameter is used to select the point in the internal tape fifo
* in which we will start to refill the buffer. Decreasing the following
* parameter will improve the system's latency and interactive response, while
@@ -663,7 +656,7 @@ static ide_startstop_t idetape_pc_intr(i
{
idetape_tape_t *tape = drive->driver_data;

- return ide_pc_intr(drive, tape->pc, idetape_pc_intr, IDETAPE_WAIT_CMD,
+ return ide_pc_intr(drive, tape->pc, idetape_pc_intr, WAIT_TAPE_CMD,
NULL, idetape_update_buffers, idetape_retry_pc,
ide_tape_handle_dsc, ide_tape_io_buffers);
}
@@ -709,7 +702,7 @@ static ide_startstop_t idetape_transfer_
idetape_tape_t *tape = drive->driver_data;

return ide_transfer_pc(drive, tape->pc, idetape_pc_intr,
- IDETAPE_WAIT_CMD, NULL);
+ WAIT_TAPE_CMD, NULL);
}

static ide_startstop_t idetape_issue_pc(ide_drive_t *drive,
@@ -758,7 +751,7 @@ static ide_startstop_t idetape_issue_pc(
pc->retries++;

return ide_issue_pc(drive, pc, idetape_transfer_pc,
- IDETAPE_WAIT_CMD, NULL);
+ WAIT_TAPE_CMD, NULL);
}

/* A mode sense command is used to "sense" tape parameters. */
Index: b/include/linux/ide.h
===================================================================
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -133,12 +133,28 @@ struct ide_io_ports {
/*
* Timeouts for various operations:
*/
-#define WAIT_DRQ (HZ/10) /* 100msec - spec allows up to 20ms */
-#define WAIT_READY (5*HZ) /* 5sec - some laptops are very slow */
-#define WAIT_PIDENTIFY (10*HZ) /* 10sec - should be less than 3ms (?), if all ATAPI CD is closed at boot */
-#define WAIT_WORSTCASE (30*HZ) /* 30sec - worst case when spinning up */
-#define WAIT_CMD (10*HZ) /* 10sec - maximum wait for an IRQ to happen */
-#define WAIT_MIN_SLEEP (2*HZ/100) /* 20msec - minimum sleep time */
+enum {
+ /* spec allows up to 20ms */
+ WAIT_DRQ = HZ / 10, /* 100ms */
+ /* some laptops are very slow */
+ WAIT_READY = 5 * HZ, /* 5s */
+ /* should be less than 3ms (?), if all ATAPI CD is closed at boot */
+ WAIT_PIDENTIFY = 10 * HZ, /* 10s */
+ /* worst case when spinning up */
+ WAIT_WORSTCASE = 30 * HZ, /* 30s */
+ /* maximum wait for an IRQ to happen */
+ WAIT_CMD = 10 * HZ, /* 10s */
+ /* Some drives require a longer IRQ timeout. */
+ WAIT_FLOPPY_CMD = 50 * HZ, /* 50s */
+ /*
+ * Some drives (for example, Seagate STT3401A Travan) require a very
+ * long timeout, because they don't return an interrupt or clear their
+ * BSY bit until after the command completes (even retension commands).
+ */
+ WAIT_TAPE_CMD = 900 * HZ, /* 900s */
+ /* minimum sleep time */
+ WAIT_MIN_SLEEP = HZ / 50, /* 20ms */
+};

/*
* Op codes for special requests to be handled by ide_special_rq().

Subject: [PATCH 15/22] ide: drop dsc_handle argument from ide_pc_intr()

* Add 'int dsc' argument to ->pc_callback method.

* Call ide_tape_handle_dsc() internally in ide_tape_callback()
if dsc argument is set and update ide_pc_intr() accordingly.

There should be no functional changes caused by this patch.

Cc: Borislav Petkov <[email protected]>
Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
drivers/ide/ide-atapi.c | 16 +++++++---------
drivers/ide/ide-floppy.c | 6 +++---
drivers/ide/ide-tape.c | 13 +++++++++----
drivers/scsi/ide-scsi.c | 5 ++---
include/linux/ide.h | 4 ++--
5 files changed, 23 insertions(+), 21 deletions(-)

Index: b/drivers/ide/ide-atapi.c
===================================================================
--- a/drivers/ide/ide-atapi.c
+++ b/drivers/ide/ide-atapi.c
@@ -207,7 +207,7 @@ EXPORT_SYMBOL_GPL(ide_set_media_lock);
ide_startstop_t ide_pc_intr(ide_drive_t *drive, struct ide_atapi_pc *pc,
ide_handler_t *handler, unsigned int timeout, ide_expiry_t *expiry,
void (*update_buffers)(ide_drive_t *, struct ide_atapi_pc *),
- void (*retry_pc)(ide_drive_t *), void (*dsc_handle)(ide_drive_t *),
+ void (*retry_pc)(ide_drive_t *),
int (*io_buffers)(ide_drive_t *, struct ide_atapi_pc *, unsigned, int))
{
ide_hwif_t *hwif = drive->hwif;
@@ -216,12 +216,12 @@ ide_startstop_t ide_pc_intr(ide_drive_t
xfer_func_t *xferfunc;
unsigned int temp;
u16 bcount;
- u8 stat, ireason, scsi = drive->scsi;
+ u8 stat, ireason, scsi = drive->scsi, dsc = 0;

debug_log("Enter %s - interrupt handler\n", __func__);

if (pc->flags & PC_FLAG_TIMEDOUT) {
- drive->pc_callback(drive);
+ drive->pc_callback(drive, 0);
return ide_stopped;
}

@@ -283,14 +283,12 @@ ide_startstop_t ide_pc_intr(ide_drive_t
}
cmd_finished:
pc->error = 0;
- if ((pc->flags & PC_FLAG_WAIT_FOR_DSC) &&
- (stat & ATA_DSC) == 0) {
- dsc_handle(drive);
- return ide_stopped;
- }
+
+ if ((pc->flags & PC_FLAG_WAIT_FOR_DSC) && (stat & ATA_DSC) == 0)
+ dsc = 1;

/* Command finished - Call the callback function */
- drive->pc_callback(drive);
+ drive->pc_callback(drive, dsc);

return ide_stopped;
}
Index: b/drivers/ide/ide-floppy.c
===================================================================
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -155,7 +155,7 @@ static void idefloppy_update_buffers(ide
idefloppy_end_request(drive, 1, 0);
}

-static void ide_floppy_callback(ide_drive_t *drive)
+static void ide_floppy_callback(ide_drive_t *drive, int dsc)
{
idefloppy_floppy_t *floppy = drive->driver_data;
struct ide_atapi_pc *pc = floppy->pc;
@@ -222,7 +222,7 @@ static ide_startstop_t idefloppy_pc_intr

return ide_pc_intr(drive, floppy->pc, idefloppy_pc_intr,
WAIT_FLOPPY_CMD, NULL, idefloppy_update_buffers,
- idefloppy_retry_pc, NULL, ide_io_buffers);
+ idefloppy_retry_pc, ide_io_buffers);
}

/*
@@ -307,7 +307,7 @@ static ide_startstop_t idefloppy_issue_p
pc->error = IDEFLOPPY_ERROR_GENERAL;

floppy->failed_pc = NULL;
- drive->pc_callback(drive);
+ drive->pc_callback(drive, 0);
return ide_stopped;
}

Index: b/drivers/ide/ide-tape.c
===================================================================
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -522,7 +522,9 @@ static int idetape_end_request(ide_drive
return 0;
}

-static void ide_tape_callback(ide_drive_t *drive)
+static void ide_tape_handle_dsc(ide_drive_t *);
+
+static void ide_tape_callback(ide_drive_t *drive, int dsc)
{
idetape_tape_t *tape = drive->driver_data;
struct ide_atapi_pc *pc = tape->pc;
@@ -530,6 +532,9 @@ static void ide_tape_callback(ide_drive_

debug_log(DBG_PROCS, "Enter %s\n", __func__);

+ if (dsc)
+ ide_tape_handle_dsc(drive);
+
if (tape->failed_pc == pc)
tape->failed_pc = NULL;

@@ -658,7 +663,7 @@ static ide_startstop_t idetape_pc_intr(i

return ide_pc_intr(drive, tape->pc, idetape_pc_intr, WAIT_TAPE_CMD,
NULL, idetape_update_buffers, idetape_retry_pc,
- ide_tape_handle_dsc, ide_tape_io_buffers);
+ ide_tape_io_buffers);
}

/*
@@ -743,7 +748,7 @@ static ide_startstop_t idetape_issue_pc(
pc->error = IDETAPE_ERROR_GENERAL;
}
tape->failed_pc = NULL;
- drive->pc_callback(drive);
+ drive->pc_callback(drive, 0);
return ide_stopped;
}
debug_log(DBG_SENSE, "Retry #%d, cmd = %02X\n", pc->retries, pc->c[0]);
@@ -805,7 +810,7 @@ static ide_startstop_t idetape_media_acc
pc->error = IDETAPE_ERROR_GENERAL;
tape->failed_pc = NULL;
}
- drive->pc_callback(drive);
+ drive->pc_callback(drive, 0);
return ide_stopped;
}

Index: b/drivers/scsi/ide-scsi.c
===================================================================
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -137,7 +137,7 @@ static void ide_scsi_hex_dump(u8 *data,

static int idescsi_end_request(ide_drive_t *, int, int);

-static void ide_scsi_callback(ide_drive_t *drive)
+static void ide_scsi_callback(ide_drive_t *drive, int dsc)
{
idescsi_scsi_t *scsi = drive_to_idescsi(drive);
struct ide_atapi_pc *pc = scsi->pc;
@@ -298,8 +298,7 @@ static ide_startstop_t idescsi_pc_intr (
struct ide_atapi_pc *pc = scsi->pc;

return ide_pc_intr(drive, pc, idescsi_pc_intr, get_timeout(pc),
- idescsi_expiry, NULL, NULL, NULL,
- ide_io_buffers);
+ idescsi_expiry, NULL, NULL, ide_io_buffers);
}

static ide_startstop_t idescsi_transfer_pc(ide_drive_t *drive)
Index: b/include/linux/ide.h
===================================================================
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -482,7 +482,7 @@ struct ide_drive_s {
struct completion gendev_rel_comp; /* to deal with device release() */

/* callback for packet commands */
- void (*pc_callback)(struct ide_drive_s *);
+ void (*pc_callback)(struct ide_drive_s *, int);

unsigned long atapi_flags;
};
@@ -1163,7 +1163,7 @@ int ide_set_media_lock(ide_drive_t *, st
ide_startstop_t ide_pc_intr(ide_drive_t *drive, struct ide_atapi_pc *pc,
ide_handler_t *handler, unsigned int timeout, ide_expiry_t *expiry,
void (*update_buffers)(ide_drive_t *, struct ide_atapi_pc *),
- void (*retry_pc)(ide_drive_t *), void (*dsc_handle)(ide_drive_t *),
+ void (*retry_pc)(ide_drive_t *),
int (*io_buffers)(ide_drive_t *, struct ide_atapi_pc *, unsigned int,
int));
ide_startstop_t ide_transfer_pc(ide_drive_t *, struct ide_atapi_pc *,

Subject: [PATCH 16/22] ide: add pointer to the current packet command to ide_drive_t

* Add pointer to the current packet command (struct ide_atapi_pc *pc)
to ide_drive_t and use it instead of the pointer in struct ide_*_obj.

* Use drive->pc in ide_{issue,transfer}_pc() and ide_pc_intr()
instead of 'pc' argument.

There should be no functional changes caused by this patch.

Cc: Borislav Petkov <[email protected]>
Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
drivers/ide/ide-atapi.c | 9 ++++---
drivers/ide/ide-floppy.c | 20 ++++++----------
drivers/ide/ide-floppy.h | 2 -
drivers/ide/ide-tape.c | 31 ++++++++-----------------
drivers/scsi/ide-scsi.c | 58 ++++++++++++++++++++++-------------------------
include/linux/ide.h | 10 +++++---
6 files changed, 60 insertions(+), 70 deletions(-)

Index: b/drivers/ide/ide-atapi.c
===================================================================
--- a/drivers/ide/ide-atapi.c
+++ b/drivers/ide/ide-atapi.c
@@ -204,12 +204,13 @@ int ide_set_media_lock(ide_drive_t *driv
EXPORT_SYMBOL_GPL(ide_set_media_lock);

/* TODO: unify the code thus making some arguments go away */
-ide_startstop_t ide_pc_intr(ide_drive_t *drive, struct ide_atapi_pc *pc,
+ide_startstop_t ide_pc_intr(ide_drive_t *drive,
ide_handler_t *handler, unsigned int timeout, ide_expiry_t *expiry,
void (*update_buffers)(ide_drive_t *, struct ide_atapi_pc *),
void (*retry_pc)(ide_drive_t *),
int (*io_buffers)(ide_drive_t *, struct ide_atapi_pc *, unsigned, int))
{
+ struct ide_atapi_pc *pc = drive->pc;
ide_hwif_t *hwif = drive->hwif;
struct request *rq = hwif->hwgroup->rq;
const struct ide_tp_ops *tp_ops = hwif->tp_ops;
@@ -416,10 +417,11 @@ static u8 ide_wait_ireason(ide_drive_t *
return ireason;
}

-ide_startstop_t ide_transfer_pc(ide_drive_t *drive, struct ide_atapi_pc *pc,
+ide_startstop_t ide_transfer_pc(ide_drive_t *drive,
ide_handler_t *handler, unsigned int timeout,
ide_expiry_t *expiry)
{
+ struct ide_atapi_pc *pc = drive->pc;
ide_hwif_t *hwif = drive->hwif;
struct request *rq = hwif->hwgroup->rq;
ide_startstop_t startstop;
@@ -458,10 +460,11 @@ ide_startstop_t ide_transfer_pc(ide_driv
}
EXPORT_SYMBOL_GPL(ide_transfer_pc);

-ide_startstop_t ide_issue_pc(ide_drive_t *drive, struct ide_atapi_pc *pc,
+ide_startstop_t ide_issue_pc(ide_drive_t *drive,
ide_handler_t *handler, unsigned int timeout,
ide_expiry_t *expiry)
{
+ struct ide_atapi_pc *pc = drive->pc;
ide_hwif_t *hwif = drive->hwif;
u16 bcount;
u8 dma = 0;
Index: b/drivers/ide/ide-floppy.c
===================================================================
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -158,7 +158,7 @@ static void idefloppy_update_buffers(ide
static void ide_floppy_callback(ide_drive_t *drive, int dsc)
{
idefloppy_floppy_t *floppy = drive->driver_data;
- struct ide_atapi_pc *pc = floppy->pc;
+ struct ide_atapi_pc *pc = drive->pc;
int uptodate = pc->error ? 0 : 1;

debug_log("Reached %s\n", __func__);
@@ -170,7 +170,7 @@ static void ide_floppy_callback(ide_driv
(pc->rq && blk_pc_request(pc->rq)))
uptodate = 1; /* FIXME */
else if (pc->c[0] == GPCMD_REQUEST_SENSE) {
- u8 *buf = floppy->pc->buf;
+ u8 *buf = pc->buf;

if (!pc->error) {
floppy->sense_key = buf[2] & 0x0F;
@@ -218,9 +218,7 @@ static void idefloppy_retry_pc(ide_drive
/* The usual interrupt handler called during a packet command. */
static ide_startstop_t idefloppy_pc_intr(ide_drive_t *drive)
{
- idefloppy_floppy_t *floppy = drive->driver_data;
-
- return ide_pc_intr(drive, floppy->pc, idefloppy_pc_intr,
+ return ide_pc_intr(drive, idefloppy_pc_intr,
WAIT_FLOPPY_CMD, NULL, idefloppy_update_buffers,
idefloppy_retry_pc, ide_io_buffers);
}
@@ -233,10 +231,8 @@ static ide_startstop_t idefloppy_pc_intr
*/
static int idefloppy_transfer_pc(ide_drive_t *drive)
{
- idefloppy_floppy_t *floppy = drive->driver_data;
-
/* Send the actual packet */
- drive->hwif->tp_ops->output_data(drive, NULL, floppy->pc->c, 12);
+ drive->hwif->tp_ops->output_data(drive, NULL, drive->pc->c, 12);

/* Timeout for the packet command */
return WAIT_FLOPPY_CMD;
@@ -250,7 +246,6 @@ static int idefloppy_transfer_pc(ide_dri
static ide_startstop_t idefloppy_start_pc_transfer(ide_drive_t *drive)
{
idefloppy_floppy_t *floppy = drive->driver_data;
- struct ide_atapi_pc *pc = floppy->pc;
ide_expiry_t *expiry;
unsigned int timeout;

@@ -270,7 +265,7 @@ static ide_startstop_t idefloppy_start_p
expiry = NULL;
}

- return ide_transfer_pc(drive, pc, idefloppy_pc_intr, timeout, expiry);
+ return ide_transfer_pc(drive, idefloppy_pc_intr, timeout, expiry);
}

static void ide_floppy_report_error(idefloppy_floppy_t *floppy,
@@ -297,8 +292,9 @@ static ide_startstop_t idefloppy_issue_p
if (floppy->failed_pc == NULL &&
pc->c[0] != GPCMD_REQUEST_SENSE)
floppy->failed_pc = pc;
+
/* Set the current packet command */
- floppy->pc = pc;
+ drive->pc = pc;

if (pc->retries > IDEFLOPPY_MAX_PC_RETRIES) {
if (!(pc->flags & PC_FLAG_SUPPRESS_ERROR))
@@ -315,7 +311,7 @@ static ide_startstop_t idefloppy_issue_p

pc->retries++;

- return ide_issue_pc(drive, pc, idefloppy_start_pc_transfer,
+ return ide_issue_pc(drive, idefloppy_start_pc_transfer,
WAIT_FLOPPY_CMD, NULL);
}

Index: b/drivers/ide/ide-floppy.h
===================================================================
--- a/drivers/ide/ide-floppy.h
+++ b/drivers/ide/ide-floppy.h
@@ -13,8 +13,6 @@ typedef struct ide_floppy_obj {
struct kref kref;
unsigned int openers; /* protected by BKL for now */

- /* Current packet command */
- struct ide_atapi_pc *pc;
/* Last failed packet command */
struct ide_atapi_pc *failed_pc;
/* used for blk_{fs,pc}_request() requests */
Index: b/drivers/ide/ide-tape.c
===================================================================
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -172,15 +172,11 @@ typedef struct ide_tape_obj {
struct kref kref;

/*
- * pc points to the current processed packet command.
- *
* failed_pc points to the last failed packet command, or contains
* NULL if we do not need to retry any packet command. This is
* required since an additional packet command is needed before the
* retry, to get detailed information on what went wrong.
*/
- /* Current packet command */
- struct ide_atapi_pc *pc;
/* Last failed packet command */
struct ide_atapi_pc *failed_pc;
/* used by REQ_IDETAPE_{READ,WRITE} requests */
@@ -527,7 +523,7 @@ static void ide_tape_handle_dsc(ide_driv
static void ide_tape_callback(ide_drive_t *drive, int dsc)
{
idetape_tape_t *tape = drive->driver_data;
- struct ide_atapi_pc *pc = tape->pc;
+ struct ide_atapi_pc *pc = drive->pc;
int uptodate = pc->error ? 0 : 1;

debug_log(DBG_PROCS, "Enter %s\n", __func__);
@@ -563,7 +559,7 @@ static void ide_tape_callback(ide_drive_
if (pc->error)
uptodate = pc->error;
} else if (pc->c[0] == READ_POSITION && uptodate) {
- u8 *readpos = tape->pc->buf;
+ u8 *readpos = pc->buf;

debug_log(DBG_SENSE, "BOP - %s\n",
(readpos[0] & 0x80) ? "Yes" : "No");
@@ -659,9 +655,7 @@ static int ide_tape_io_buffers(ide_drive
*/
static ide_startstop_t idetape_pc_intr(ide_drive_t *drive)
{
- idetape_tape_t *tape = drive->driver_data;
-
- return ide_pc_intr(drive, tape->pc, idetape_pc_intr, WAIT_TAPE_CMD,
+ return ide_pc_intr(drive, idetape_pc_intr, WAIT_TAPE_CMD,
NULL, idetape_update_buffers, idetape_retry_pc,
ide_tape_io_buffers);
}
@@ -669,7 +663,7 @@ static ide_startstop_t idetape_pc_intr(i
/*
* Packet Command Interface
*
- * The current Packet Command is available in tape->pc, and will not change
+ * The current Packet Command is available in drive->pc, and will not change
* until we finish handling it. Each packet command is associated with a
* callback function that will be called when the command is finished.
*
@@ -704,10 +698,7 @@ static ide_startstop_t idetape_pc_intr(i
*/
static ide_startstop_t idetape_transfer_pc(ide_drive_t *drive)
{
- idetape_tape_t *tape = drive->driver_data;
-
- return ide_transfer_pc(drive, tape->pc, idetape_pc_intr,
- WAIT_TAPE_CMD, NULL);
+ return ide_transfer_pc(drive, idetape_pc_intr, WAIT_TAPE_CMD, NULL);
}

static ide_startstop_t idetape_issue_pc(ide_drive_t *drive,
@@ -715,7 +706,7 @@ static ide_startstop_t idetape_issue_pc(
{
idetape_tape_t *tape = drive->driver_data;

- if (tape->pc->c[0] == REQUEST_SENSE &&
+ if (drive->pc->c[0] == REQUEST_SENSE &&
pc->c[0] == REQUEST_SENSE) {
printk(KERN_ERR "ide-tape: possible ide-tape.c bug - "
"Two request sense in serial were issued\n");
@@ -723,8 +714,9 @@ static ide_startstop_t idetape_issue_pc(

if (tape->failed_pc == NULL && pc->c[0] != REQUEST_SENSE)
tape->failed_pc = pc;
+
/* Set the current packet command */
- tape->pc = pc;
+ drive->pc = pc;

if (pc->retries > IDETAPE_MAX_PC_RETRIES ||
(pc->flags & PC_FLAG_ABORT)) {
@@ -755,8 +747,7 @@ static ide_startstop_t idetape_issue_pc(

pc->retries++;

- return ide_issue_pc(drive, pc, idetape_transfer_pc,
- WAIT_TAPE_CMD, NULL);
+ return ide_issue_pc(drive, idetape_transfer_pc, WAIT_TAPE_CMD, NULL);
}

/* A mode sense command is used to "sense" tape parameters. */
@@ -790,7 +781,7 @@ static ide_startstop_t idetape_media_acc
{
ide_hwif_t *hwif = drive->hwif;
idetape_tape_t *tape = drive->driver_data;
- struct ide_atapi_pc *pc = tape->pc;
+ struct ide_atapi_pc *pc = drive->pc;
u8 stat;

stat = hwif->tp_ops->read_status(hwif);
@@ -866,7 +857,7 @@ static ide_startstop_t idetape_do_reques
}

/* Retry a failed packet command */
- if (tape->failed_pc && tape->pc->c[0] == REQUEST_SENSE) {
+ if (tape->failed_pc && drive->pc->c[0] == REQUEST_SENSE) {
pc = tape->failed_pc;
goto out;
}
Index: b/drivers/scsi/ide-scsi.c
===================================================================
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -82,7 +82,6 @@ typedef struct ide_scsi_obj {
struct gendisk *disk;
struct Scsi_Host *host;

- struct ide_atapi_pc *pc; /* Current packet command */
unsigned long transform; /* SCSI cmd translation layer */
unsigned long log; /* log flags */
} idescsi_scsi_t;
@@ -140,7 +139,7 @@ static int idescsi_end_request(ide_drive
static void ide_scsi_callback(ide_drive_t *drive, int dsc)
{
idescsi_scsi_t *scsi = drive_to_idescsi(drive);
- struct ide_atapi_pc *pc = scsi->pc;
+ struct ide_atapi_pc *pc = drive->pc;

if (pc->flags & PC_FLAG_TIMEDOUT)
debug_log("%s: got timed out packet %lu at %lu\n", __func__,
@@ -267,7 +266,7 @@ static int idescsi_end_request (ide_driv
spin_unlock_irqrestore(host->host_lock, flags);
kfree(pc);
blk_put_request(rq);
- scsi->pc = NULL;
+ drive->pc = NULL;
return 0;
}

@@ -278,8 +277,7 @@ static inline unsigned long get_timeout(

static int idescsi_expiry(ide_drive_t *drive)
{
- idescsi_scsi_t *scsi = drive_to_idescsi(drive);
- struct ide_atapi_pc *pc = scsi->pc;
+ struct ide_atapi_pc *pc = drive->pc;

debug_log("%s called for %lu at %lu\n", __func__,
pc->scsi_cmd->serial_number, jiffies);
@@ -294,19 +292,14 @@ static int idescsi_expiry(ide_drive_t *d
*/
static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive)
{
- idescsi_scsi_t *scsi = drive_to_idescsi(drive);
- struct ide_atapi_pc *pc = scsi->pc;
-
- return ide_pc_intr(drive, pc, idescsi_pc_intr, get_timeout(pc),
+ return ide_pc_intr(drive, idescsi_pc_intr, get_timeout(drive->pc),
idescsi_expiry, NULL, NULL, ide_io_buffers);
}

static ide_startstop_t idescsi_transfer_pc(ide_drive_t *drive)
{
- idescsi_scsi_t *scsi = drive_to_idescsi(drive);
-
- return ide_transfer_pc(drive, scsi->pc, idescsi_pc_intr,
- get_timeout(scsi->pc), idescsi_expiry);
+ return ide_transfer_pc(drive, idescsi_pc_intr,
+ get_timeout(drive->pc), idescsi_expiry);
}

static inline int idescsi_set_direction(struct ide_atapi_pc *pc)
@@ -351,12 +344,10 @@ static int idescsi_map_sg(ide_drive_t *d
static ide_startstop_t idescsi_issue_pc(ide_drive_t *drive,
struct ide_atapi_pc *pc)
{
- idescsi_scsi_t *scsi = drive_to_idescsi(drive);
-
/* Set the current packet command */
- scsi->pc = pc;
+ drive->pc = pc;

- return ide_issue_pc(drive, pc, idescsi_transfer_pc,
+ return ide_issue_pc(drive, idescsi_transfer_pc,
get_timeout(pc), idescsi_expiry);
}

@@ -621,6 +612,8 @@ static int idescsi_eh_abort (struct scsi
int busy;
int ret = FAILED;

+ struct ide_atapi_pc *pc;
+
/* In idescsi_eh_abort we try to gently pry our command from the ide subsystem */

if (test_bit(IDESCSI_LOG_CMD, &scsi->log))
@@ -641,26 +634,27 @@ static int idescsi_eh_abort (struct scsi
spin_lock_irq(&ide_lock);

/* If there is no pc running we're done (our interrupt took care of it) */
- if (!scsi->pc) {
+ pc = drive->pc;
+ if (pc == NULL) {
ret = SUCCESS;
goto ide_unlock;
}

/* It's somewhere in flight. Does ide subsystem agree? */
- if (scsi->pc->scsi_cmd->serial_number == cmd->serial_number && !busy &&
- elv_queue_empty(drive->queue) && HWGROUP(drive)->rq != scsi->pc->rq) {
+ if (pc->scsi_cmd->serial_number == cmd->serial_number && !busy &&
+ elv_queue_empty(drive->queue) && HWGROUP(drive)->rq != pc->rq) {
/*
* FIXME - not sure this condition can ever occur
*/
printk (KERN_ERR "ide-scsi: cmd aborted!\n");

- if (blk_sense_request(scsi->pc->rq))
- kfree(scsi->pc->buf);
+ if (blk_sense_request(pc->rq))
+ kfree(pc->buf);
/* we need to call blk_put_request twice. */
- blk_put_request(scsi->pc->rq);
- blk_put_request(scsi->pc->rq);
- kfree(scsi->pc);
- scsi->pc = NULL;
+ blk_put_request(pc->rq);
+ blk_put_request(pc->rq);
+ kfree(pc);
+ drive->pc = NULL;

ret = SUCCESS;
}
@@ -682,6 +676,8 @@ static int idescsi_eh_reset (struct scsi
int ready = 0;
int ret = SUCCESS;

+ struct ide_atapi_pc *pc;
+
/* In idescsi_eh_reset we forcefully remove the command from the ide subsystem and reset the device. */

if (test_bit(IDESCSI_LOG_CMD, &scsi->log))
@@ -696,7 +692,9 @@ static int idescsi_eh_reset (struct scsi
spin_lock_irq(cmd->device->host->host_lock);
spin_lock(&ide_lock);

- if (!scsi->pc || (req = scsi->pc->rq) != HWGROUP(drive)->rq || !HWGROUP(drive)->handler) {
+ pc = drive->pc;
+
+ if (pc == NULL || (req = pc->rq) != HWGROUP(drive)->rq || !HWGROUP(drive)->handler) {
printk (KERN_WARNING "ide-scsi: No active request in idescsi_eh_reset\n");
spin_unlock(&ide_lock);
spin_unlock_irq(cmd->device->host->host_lock);
@@ -707,9 +705,9 @@ static int idescsi_eh_reset (struct scsi
if (__blk_end_request(req, -EIO, 0))
BUG();
if (blk_sense_request(req))
- kfree(scsi->pc->buf);
- kfree(scsi->pc);
- scsi->pc = NULL;
+ kfree(pc->buf);
+ kfree(pc);
+ drive->pc = NULL;
blk_put_request(req);

/* now nuke the drive queue */
Index: b/include/linux/ide.h
===================================================================
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -321,6 +321,7 @@ typedef enum {
ide_started, /* a drive operation was started, handler was set */
} ide_startstop_t;

+struct ide_atapi_pc;
struct ide_devset;
struct ide_driver_s;

@@ -481,6 +482,9 @@ struct ide_drive_s {
struct device gendev;
struct completion gendev_rel_comp; /* to deal with device release() */

+ /* current packet command */
+ struct ide_atapi_pc *pc;
+
/* callback for packet commands */
void (*pc_callback)(struct ide_drive_s *, int);

@@ -1160,15 +1164,15 @@ int ide_do_test_unit_ready(ide_drive_t *
int ide_do_start_stop(ide_drive_t *, struct gendisk *, int);
int ide_set_media_lock(ide_drive_t *, struct gendisk *, int);

-ide_startstop_t ide_pc_intr(ide_drive_t *drive, struct ide_atapi_pc *pc,
+ide_startstop_t ide_pc_intr(ide_drive_t *drive,
ide_handler_t *handler, unsigned int timeout, ide_expiry_t *expiry,
void (*update_buffers)(ide_drive_t *, struct ide_atapi_pc *),
void (*retry_pc)(ide_drive_t *),
int (*io_buffers)(ide_drive_t *, struct ide_atapi_pc *, unsigned int,
int));
-ide_startstop_t ide_transfer_pc(ide_drive_t *, struct ide_atapi_pc *,
+ide_startstop_t ide_transfer_pc(ide_drive_t *,
ide_handler_t *, unsigned int, ide_expiry_t *);
-ide_startstop_t ide_issue_pc(ide_drive_t *, struct ide_atapi_pc *,
+ide_startstop_t ide_issue_pc(ide_drive_t *,
ide_handler_t *, unsigned int, ide_expiry_t *);

ide_startstop_t do_rw_taskfile(ide_drive_t *, ide_task_t *);

Subject: [PATCH 17/22] ide: drop 'timeout' and 'expiry' arguments from ide_pc_intr()

* Move idescsi_expiry() to ide-atapi.c.

* Move get_timeout() to <linux/ide.h>.

* Drop 'timeout' and 'expiry' arguments from ide_pc_intr().

While at it:

* idescsi_expiry() -> ide_scsi_expiry()

* get_timeout() -> ide_scsi_get_timeout()

There should be no functional changes caused by this patch.

Cc: Borislav Petkov <[email protected]>
Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
drivers/ide/ide-atapi.c | 34 +++++++++++++++++++++++++++-------
drivers/ide/ide-floppy.c | 3 +--
drivers/ide/ide-tape.c | 5 ++---
drivers/scsi/ide-scsi.c | 25 ++++---------------------
include/linux/ide.h | 10 ++++++++--
5 files changed, 42 insertions(+), 35 deletions(-)

Index: b/drivers/ide/ide-atapi.c
===================================================================
--- a/drivers/ide/ide-atapi.c
+++ b/drivers/ide/ide-atapi.c
@@ -203,9 +203,21 @@ int ide_set_media_lock(ide_drive_t *driv
}
EXPORT_SYMBOL_GPL(ide_set_media_lock);

+int ide_scsi_expiry(ide_drive_t *drive)
+{
+ struct ide_atapi_pc *pc = drive->pc;
+
+ debug_log("%s called for %lu at %lu\n", __func__,
+ pc->scsi_cmd->serial_number, jiffies);
+
+ pc->flags |= PC_FLAG_TIMEDOUT;
+
+ return 0; /* we do not want the IDE subsystem to retry */
+}
+EXPORT_SYMBOL_GPL(ide_scsi_expiry);
+
/* TODO: unify the code thus making some arguments go away */
-ide_startstop_t ide_pc_intr(ide_drive_t *drive,
- ide_handler_t *handler, unsigned int timeout, ide_expiry_t *expiry,
+ide_startstop_t ide_pc_intr(ide_drive_t *drive, ide_handler_t *handler,
void (*update_buffers)(ide_drive_t *, struct ide_atapi_pc *),
void (*retry_pc)(ide_drive_t *),
int (*io_buffers)(ide_drive_t *, struct ide_atapi_pc *, unsigned, int))
@@ -215,12 +227,22 @@ ide_startstop_t ide_pc_intr(ide_drive_t
struct request *rq = hwif->hwgroup->rq;
const struct ide_tp_ops *tp_ops = hwif->tp_ops;
xfer_func_t *xferfunc;
- unsigned int temp;
+ ide_expiry_t *expiry;
+ unsigned int timeout, temp;
u16 bcount;
u8 stat, ireason, scsi = drive->scsi, dsc = 0;

debug_log("Enter %s - interrupt handler\n", __func__);

+ if (scsi) {
+ timeout = ide_scsi_get_timeout(pc);
+ expiry = ide_scsi_expiry;
+ } else {
+ timeout = (drive->media == ide_floppy) ? WAIT_FLOPPY_CMD
+ : WAIT_TAPE_CMD;
+ expiry = NULL;
+ }
+
if (pc->flags & PC_FLAG_TIMEDOUT) {
drive->pc_callback(drive, 0);
return ide_stopped;
@@ -347,9 +369,7 @@ cmd_finished:
pc->xferred += temp;
pc->cur_pos += temp;
ide_pad_transfer(drive, 0, bcount - temp);
- ide_set_handler(drive, handler, timeout,
- expiry);
- return ide_started;
+ goto next_irq;
}
debug_log("The device wants to send us more data than "
"expected - allowing transfer\n");
@@ -376,7 +396,7 @@ cmd_finished:

debug_log("[cmd %x] transferred %d bytes on that intr.\n",
rq->cmd[0], bcount);
-
+next_irq:
/* And set the interrupt handler again */
ide_set_handler(drive, handler, timeout, expiry);
return ide_started;
Index: b/drivers/ide/ide-floppy.c
===================================================================
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -218,8 +218,7 @@ static void idefloppy_retry_pc(ide_drive
/* The usual interrupt handler called during a packet command. */
static ide_startstop_t idefloppy_pc_intr(ide_drive_t *drive)
{
- return ide_pc_intr(drive, idefloppy_pc_intr,
- WAIT_FLOPPY_CMD, NULL, idefloppy_update_buffers,
+ return ide_pc_intr(drive, idefloppy_pc_intr, idefloppy_update_buffers,
idefloppy_retry_pc, ide_io_buffers);
}

Index: b/drivers/ide/ide-tape.c
===================================================================
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -655,9 +655,8 @@ static int ide_tape_io_buffers(ide_drive
*/
static ide_startstop_t idetape_pc_intr(ide_drive_t *drive)
{
- return ide_pc_intr(drive, idetape_pc_intr, WAIT_TAPE_CMD,
- NULL, idetape_update_buffers, idetape_retry_pc,
- ide_tape_io_buffers);
+ return ide_pc_intr(drive, idetape_pc_intr, idetape_update_buffers,
+ idetape_retry_pc, ide_tape_io_buffers);
}

/*
Index: b/drivers/scsi/ide-scsi.c
===================================================================
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -270,36 +270,19 @@ static int idescsi_end_request (ide_driv
return 0;
}

-static inline unsigned long get_timeout(struct ide_atapi_pc *pc)
-{
- return max_t(unsigned long, WAIT_CMD, pc->timeout - jiffies);
-}
-
-static int idescsi_expiry(ide_drive_t *drive)
-{
- struct ide_atapi_pc *pc = drive->pc;
-
- debug_log("%s called for %lu at %lu\n", __func__,
- pc->scsi_cmd->serial_number, jiffies);
-
- pc->flags |= PC_FLAG_TIMEDOUT;
-
- return 0; /* we do not want the ide subsystem to retry */
-}
-
/*
* Our interrupt handler.
*/
static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive)
{
- return ide_pc_intr(drive, idescsi_pc_intr, get_timeout(drive->pc),
- idescsi_expiry, NULL, NULL, ide_io_buffers);
+ return ide_pc_intr(drive, idescsi_pc_intr, NULL, NULL, ide_io_buffers);
}

static ide_startstop_t idescsi_transfer_pc(ide_drive_t *drive)
{
return ide_transfer_pc(drive, idescsi_pc_intr,
- get_timeout(drive->pc), idescsi_expiry);
+ ide_scsi_get_timeout(drive->pc),
+ ide_scsi_expiry);
}

static inline int idescsi_set_direction(struct ide_atapi_pc *pc)
@@ -348,7 +331,7 @@ static ide_startstop_t idescsi_issue_pc(
drive->pc = pc;

return ide_issue_pc(drive, idescsi_transfer_pc,
- get_timeout(pc), idescsi_expiry);
+ ide_scsi_get_timeout(pc), ide_scsi_expiry);
}

/*
Index: b/include/linux/ide.h
===================================================================
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -1164,8 +1164,14 @@ int ide_do_test_unit_ready(ide_drive_t *
int ide_do_start_stop(ide_drive_t *, struct gendisk *, int);
int ide_set_media_lock(ide_drive_t *, struct gendisk *, int);

-ide_startstop_t ide_pc_intr(ide_drive_t *drive,
- ide_handler_t *handler, unsigned int timeout, ide_expiry_t *expiry,
+static inline unsigned long ide_scsi_get_timeout(struct ide_atapi_pc *pc)
+{
+ return max_t(unsigned long, WAIT_CMD, pc->timeout - jiffies);
+}
+
+int ide_scsi_expiry(ide_drive_t *);
+
+ide_startstop_t ide_pc_intr(ide_drive_t *drive, ide_handler_t *handler,
void (*update_buffers)(ide_drive_t *, struct ide_atapi_pc *),
void (*retry_pc)(ide_drive_t *),
int (*io_buffers)(ide_drive_t *, struct ide_atapi_pc *, unsigned int,

Subject: [PATCH 18/22] ide: add request_sense_{pc,rq} to ide_drive_t

Add 'struct ide_atapi_pc request_sense_pc' and 'request request_sense_rq' to
ide_drive_t and use them instead of fields in struct ide_{floppy,tape}_obj.

There should be no functional changes caused by this patch.

Cc: Borislav Petkov <[email protected]>
Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
drivers/ide/ide-floppy.c | 4 -
drivers/ide/ide-floppy.h | 3 -
drivers/ide/ide-tape.c | 7 --
include/linux/ide.h | 134 +++++++++++++++++++++++------------------------
4 files changed, 72 insertions(+), 76 deletions(-)

Index: b/drivers/ide/ide-floppy.c
===================================================================
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -207,8 +207,8 @@ void ide_floppy_create_request_sense_cmd
static void idefloppy_retry_pc(ide_drive_t *drive)
{
struct ide_floppy_obj *floppy = drive->driver_data;
- struct request *rq = &floppy->request_sense_rq;
- struct ide_atapi_pc *pc = &floppy->request_sense_pc;
+ struct request *rq = &drive->request_sense_rq;
+ struct ide_atapi_pc *pc = &drive->request_sense_pc;

(void)ide_read_error(drive);
ide_floppy_create_request_sense_cmd(pc);
Index: b/drivers/ide/ide-floppy.h
===================================================================
--- a/drivers/ide/ide-floppy.h
+++ b/drivers/ide/ide-floppy.h
@@ -18,9 +18,6 @@ typedef struct ide_floppy_obj {
/* used for blk_{fs,pc}_request() requests */
struct ide_atapi_pc queued_pc;

- struct ide_atapi_pc request_sense_pc;
- struct request request_sense_rq;
-
/* Last error information */
u8 sense_key, asc, ascq;
/* delay this long before sending packet command */
Index: b/drivers/ide/ide-tape.c
===================================================================
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -182,9 +182,6 @@ typedef struct ide_tape_obj {
/* used by REQ_IDETAPE_{READ,WRITE} requests */
struct ide_atapi_pc queued_pc;

- struct ide_atapi_pc request_sense_pc;
- struct request request_sense_rq;
-
/*
* DSC polling variables.
*
@@ -600,8 +597,8 @@ static void idetape_create_request_sense
static void idetape_retry_pc(ide_drive_t *drive)
{
struct ide_tape_obj *tape = drive->driver_data;
- struct request *rq = &tape->request_sense_rq;
- struct ide_atapi_pc *pc = &tape->request_sense_pc;
+ struct request *rq = &drive->request_sense_rq;
+ struct ide_atapi_pc *pc = &drive->request_sense_pc;

(void)ide_read_error(drive);
idetape_create_request_sense_cmd(pc);
Index: b/include/linux/ide.h
===================================================================
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -321,7 +321,71 @@ typedef enum {
ide_started, /* a drive operation was started, handler was set */
} ide_startstop_t;

-struct ide_atapi_pc;
+/* ATAPI packet command flags */
+enum {
+ /* set when an error is considered normal - no retry (ide-tape) */
+ PC_FLAG_ABORT = (1 << 0),
+ PC_FLAG_SUPPRESS_ERROR = (1 << 1),
+ PC_FLAG_WAIT_FOR_DSC = (1 << 2),
+ PC_FLAG_DMA_OK = (1 << 3),
+ PC_FLAG_DMA_IN_PROGRESS = (1 << 4),
+ PC_FLAG_DMA_ERROR = (1 << 5),
+ PC_FLAG_WRITING = (1 << 6),
+ /* command timed out */
+ PC_FLAG_TIMEDOUT = (1 << 7),
+};
+
+/*
+ * With each packet command, we allocate a buffer of IDE_PC_BUFFER_SIZE bytes.
+ * This is used for several packet commands (not for READ/WRITE commands).
+ */
+#define IDE_PC_BUFFER_SIZE 256
+
+struct ide_atapi_pc {
+ /* actual packet bytes */
+ u8 c[12];
+ /* incremented on each retry */
+ int retries;
+ int error;
+
+ /* bytes to transfer */
+ int req_xfer;
+ /* bytes actually transferred */
+ int xferred;
+
+ /* data buffer */
+ u8 *buf;
+ /* current buffer position */
+ u8 *cur_pos;
+ int buf_size;
+ /* missing/available data on the current buffer */
+ int b_count;
+
+ /* the corresponding request */
+ struct request *rq;
+
+ unsigned long flags;
+
+ /*
+ * those are more or less driver-specific and some of them are subject
+ * to change/removal later.
+ */
+ u8 pc_buf[IDE_PC_BUFFER_SIZE];
+
+ /* idetape only */
+ struct idetape_bh *bh;
+ char *b_data;
+
+ /* idescsi only for now */
+ struct scatterlist *sg;
+ unsigned int sg_cnt;
+
+ struct scsi_cmnd *scsi_cmd;
+ void (*done) (struct scsi_cmnd *);
+
+ unsigned long timeout;
+};
+
struct ide_devset;
struct ide_driver_s;

@@ -489,6 +553,9 @@ struct ide_drive_s {
void (*pc_callback)(struct ide_drive_s *, int);

unsigned long atapi_flags;
+
+ struct ide_atapi_pc request_sense_pc;
+ struct request request_sense_rq;
};

typedef struct ide_drive_s ide_drive_t;
@@ -732,71 +799,6 @@ int set_##name(ide_drive_t *drive, int a
return 0; \
}

-/* ATAPI packet command flags */
-enum {
- /* set when an error is considered normal - no retry (ide-tape) */
- PC_FLAG_ABORT = (1 << 0),
- PC_FLAG_SUPPRESS_ERROR = (1 << 1),
- PC_FLAG_WAIT_FOR_DSC = (1 << 2),
- PC_FLAG_DMA_OK = (1 << 3),
- PC_FLAG_DMA_IN_PROGRESS = (1 << 4),
- PC_FLAG_DMA_ERROR = (1 << 5),
- PC_FLAG_WRITING = (1 << 6),
- /* command timed out */
- PC_FLAG_TIMEDOUT = (1 << 7),
-};
-
-/*
- * With each packet command, we allocate a buffer of IDE_PC_BUFFER_SIZE bytes.
- * This is used for several packet commands (not for READ/WRITE commands).
- */
-#define IDE_PC_BUFFER_SIZE 256
-
-struct ide_atapi_pc {
- /* actual packet bytes */
- u8 c[12];
- /* incremented on each retry */
- int retries;
- int error;
-
- /* bytes to transfer */
- int req_xfer;
- /* bytes actually transferred */
- int xferred;
-
- /* data buffer */
- u8 *buf;
- /* current buffer position */
- u8 *cur_pos;
- int buf_size;
- /* missing/available data on the current buffer */
- int b_count;
-
- /* the corresponding request */
- struct request *rq;
-
- unsigned long flags;
-
- /*
- * those are more or less driver-specific and some of them are subject
- * to change/removal later.
- */
- u8 pc_buf[IDE_PC_BUFFER_SIZE];
-
- /* idetape only */
- struct idetape_bh *bh;
- char *b_data;
-
- /* idescsi only for now */
- struct scatterlist *sg;
- unsigned int sg_cnt;
-
- struct scsi_cmnd *scsi_cmd;
- void (*done) (struct scsi_cmnd *);
-
- unsigned long timeout;
-};
-
#ifdef CONFIG_IDE_PROC_FS
/*
* configurable drive settings

Subject: [PATCH 19/22] ide: add ide_retry_pc() helper

* Add ide_create_request_sense_cmd() and ide_retry_pc() helpers
and convert ide-{atapi,floppy,tape}.c to use them.

* Remove no longer used ide*_create_request_sense_cmd(),
ide*_retry_pc() and 'retry_pc' argument from ide_pc_intr().

* Make ide_queue_pc_head() static.

There should be no functional changes caused by this patch.

Cc: Borislav Petkov <[email protected]>
Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
drivers/ide/ide-atapi.c | 39 ++++++++++++++++++++++++++++++++++-----
drivers/ide/ide-floppy.c | 25 +------------------------
drivers/ide/ide-floppy.h | 1 -
drivers/ide/ide-floppy_ioctl.c | 2 +-
drivers/ide/ide-tape.c | 29 ++---------------------------
drivers/scsi/ide-scsi.c | 2 +-
include/linux/ide.h | 5 ++---
7 files changed, 41 insertions(+), 62 deletions(-)

Index: b/drivers/ide/ide-atapi.c
===================================================================
--- a/drivers/ide/ide-atapi.c
+++ b/drivers/ide/ide-atapi.c
@@ -124,8 +124,8 @@ EXPORT_SYMBOL_GPL(ide_init_pc);
* the current request, so that it will be processed immediately, on the next
* pass through the driver.
*/
-void ide_queue_pc_head(ide_drive_t *drive, struct gendisk *disk,
- struct ide_atapi_pc *pc, struct request *rq)
+static void ide_queue_pc_head(ide_drive_t *drive, struct gendisk *disk,
+ struct ide_atapi_pc *pc, struct request *rq)
{
blk_rq_init(NULL, rq);
rq->cmd_type = REQ_TYPE_SPECIAL;
@@ -137,7 +137,6 @@ void ide_queue_pc_head(ide_drive_t *driv
rq->cmd[13] = REQ_IDETAPE_PC1;
ide_do_drive_cmd(drive, rq);
}
-EXPORT_SYMBOL_GPL(ide_queue_pc_head);

/*
* Add a special packet command request to the tail of the request queue,
@@ -203,6 +202,37 @@ int ide_set_media_lock(ide_drive_t *driv
}
EXPORT_SYMBOL_GPL(ide_set_media_lock);

+void ide_create_request_sense_cmd(ide_drive_t *drive, struct ide_atapi_pc *pc)
+{
+ ide_init_pc(pc);
+ pc->c[0] = REQUEST_SENSE;
+ if (drive->media == ide_floppy) {
+ pc->c[4] = 255;
+ pc->req_xfer = 18;
+ } else {
+ pc->c[4] = 20;
+ pc->req_xfer = 20;
+ }
+}
+EXPORT_SYMBOL_GPL(ide_create_request_sense_cmd);
+
+/*
+ * Called when an error was detected during the last packet command.
+ * We queue a request sense packet command in the head of the request list.
+ */
+void ide_retry_pc(ide_drive_t *drive, struct gendisk *disk)
+{
+ struct request *rq = &drive->request_sense_rq;
+ struct ide_atapi_pc *pc = &drive->request_sense_pc;
+
+ (void)ide_read_error(drive);
+ ide_create_request_sense_cmd(drive, pc);
+ if (drive->media == ide_tape)
+ set_bit(IDE_AFLAG_IGNORE_DSC, &drive->atapi_flags);
+ ide_queue_pc_head(drive, disk, pc, rq);
+}
+EXPORT_SYMBOL_GPL(ide_retry_pc);
+
int ide_scsi_expiry(ide_drive_t *drive)
{
struct ide_atapi_pc *pc = drive->pc;
@@ -219,7 +249,6 @@ EXPORT_SYMBOL_GPL(ide_scsi_expiry);
/* TODO: unify the code thus making some arguments go away */
ide_startstop_t ide_pc_intr(ide_drive_t *drive, ide_handler_t *handler,
void (*update_buffers)(ide_drive_t *, struct ide_atapi_pc *),
- void (*retry_pc)(ide_drive_t *),
int (*io_buffers)(ide_drive_t *, struct ide_atapi_pc *, unsigned, int))
{
struct ide_atapi_pc *pc = drive->pc;
@@ -299,7 +328,7 @@ ide_startstop_t ide_pc_intr(ide_drive_t
debug_log("[cmd %x]: check condition\n", rq->cmd[0]);

/* Retry operation */
- retry_pc(drive);
+ ide_retry_pc(drive, rq->rq_disk);

/* queued, but not started */
return ide_stopped;
Index: b/drivers/ide/ide-floppy.c
===================================================================
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -192,34 +192,11 @@ static void ide_floppy_callback(ide_driv
idefloppy_end_request(drive, uptodate, 0);
}

-void ide_floppy_create_request_sense_cmd(struct ide_atapi_pc *pc)
-{
- ide_init_pc(pc);
- pc->c[0] = GPCMD_REQUEST_SENSE;
- pc->c[4] = 255;
- pc->req_xfer = 18;
-}
-
-/*
- * Called when an error was detected during the last packet command. We queue a
- * request sense packet command in the head of the request list.
- */
-static void idefloppy_retry_pc(ide_drive_t *drive)
-{
- struct ide_floppy_obj *floppy = drive->driver_data;
- struct request *rq = &drive->request_sense_rq;
- struct ide_atapi_pc *pc = &drive->request_sense_pc;
-
- (void)ide_read_error(drive);
- ide_floppy_create_request_sense_cmd(pc);
- ide_queue_pc_head(drive, floppy->disk, pc, rq);
-}
-
/* The usual interrupt handler called during a packet command. */
static ide_startstop_t idefloppy_pc_intr(ide_drive_t *drive)
{
return ide_pc_intr(drive, idefloppy_pc_intr, idefloppy_update_buffers,
- idefloppy_retry_pc, ide_io_buffers);
+ ide_io_buffers);
}

/*
Index: b/drivers/ide/ide-floppy.h
===================================================================
--- a/drivers/ide/ide-floppy.h
+++ b/drivers/ide/ide-floppy.h
@@ -49,7 +49,6 @@ typedef struct ide_floppy_obj {
/* ide-floppy.c */
void ide_floppy_create_mode_sense_cmd(struct ide_atapi_pc *, u8);
void ide_floppy_create_read_capacity_cmd(struct ide_atapi_pc *);
-void ide_floppy_create_request_sense_cmd(struct ide_atapi_pc *);

/* ide-floppy_ioctl.c */
int ide_floppy_format_ioctl(ide_drive_t *, struct file *, unsigned int,
Index: b/drivers/ide/ide-floppy_ioctl.c
===================================================================
--- a/drivers/ide/ide-floppy_ioctl.c
+++ b/drivers/ide/ide-floppy_ioctl.c
@@ -195,7 +195,7 @@ static int ide_floppy_get_format_progres
int progress_indication = 0x10000;

if (drive->atapi_flags & IDE_AFLAG_SRFP) {
- ide_floppy_create_request_sense_cmd(&pc);
+ ide_create_request_sense_cmd(drive, &pc);
if (ide_queue_pc_tail(drive, floppy->disk, &pc))
return -EIO;

Index: b/drivers/ide/ide-tape.c
===================================================================
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -581,31 +581,6 @@ static void ide_tape_callback(ide_drive_
idetape_end_request(drive, uptodate, 0);
}

-static void idetape_create_request_sense_cmd(struct ide_atapi_pc *pc)
-{
- ide_init_pc(pc);
- pc->c[0] = REQUEST_SENSE;
- pc->c[4] = 20;
- pc->req_xfer = 20;
-}
-
-/*
- * idetape_retry_pc is called when an error was detected during the
- * last packet command. We queue a request sense packet command in
- * the head of the request list.
- */
-static void idetape_retry_pc(ide_drive_t *drive)
-{
- struct ide_tape_obj *tape = drive->driver_data;
- struct request *rq = &drive->request_sense_rq;
- struct ide_atapi_pc *pc = &drive->request_sense_pc;
-
- (void)ide_read_error(drive);
- idetape_create_request_sense_cmd(pc);
- set_bit(IDE_AFLAG_IGNORE_DSC, &drive->atapi_flags);
- ide_queue_pc_head(drive, tape->disk, pc, rq);
-}
-
/*
* Postpone the current request so that ide.c will be able to service requests
* from another device on the same hwgroup while we are polling for DSC.
@@ -653,7 +628,7 @@ static int ide_tape_io_buffers(ide_drive
static ide_startstop_t idetape_pc_intr(ide_drive_t *drive)
{
return ide_pc_intr(drive, idetape_pc_intr, idetape_update_buffers,
- idetape_retry_pc, ide_tape_io_buffers);
+ ide_tape_io_buffers);
}

/*
@@ -789,7 +764,7 @@ static ide_startstop_t idetape_media_acc
printk(KERN_ERR "ide-tape: %s: I/O error, ",
tape->name);
/* Retry operation */
- idetape_retry_pc(drive);
+ ide_retry_pc(drive, tape->disk);
return ide_stopped;
}
pc->error = 0;
Index: b/drivers/scsi/ide-scsi.c
===================================================================
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -275,7 +275,7 @@ static int idescsi_end_request (ide_driv
*/
static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive)
{
- return ide_pc_intr(drive, idescsi_pc_intr, NULL, NULL, ide_io_buffers);
+ return ide_pc_intr(drive, idescsi_pc_intr, NULL, ide_io_buffers);
}

static ide_startstop_t idescsi_transfer_pc(ide_drive_t *drive)
Index: b/include/linux/ide.h
===================================================================
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -1158,13 +1158,13 @@ enum {
REQ_IDETAPE_WRITE = (1 << 3),
};

-void ide_queue_pc_head(ide_drive_t *, struct gendisk *, struct ide_atapi_pc *,
- struct request *);
int ide_queue_pc_tail(ide_drive_t *, struct gendisk *, struct ide_atapi_pc *);

int ide_do_test_unit_ready(ide_drive_t *, struct gendisk *);
int ide_do_start_stop(ide_drive_t *, struct gendisk *, int);
int ide_set_media_lock(ide_drive_t *, struct gendisk *, int);
+void ide_create_request_sense_cmd(ide_drive_t *, struct ide_atapi_pc *);
+void ide_retry_pc(ide_drive_t *, struct gendisk *);

static inline unsigned long ide_scsi_get_timeout(struct ide_atapi_pc *pc)
{
@@ -1175,7 +1175,6 @@ int ide_scsi_expiry(ide_drive_t *);

ide_startstop_t ide_pc_intr(ide_drive_t *drive, ide_handler_t *handler,
void (*update_buffers)(ide_drive_t *, struct ide_atapi_pc *),
- void (*retry_pc)(ide_drive_t *),
int (*io_buffers)(ide_drive_t *, struct ide_atapi_pc *, unsigned int,
int));
ide_startstop_t ide_transfer_pc(ide_drive_t *,

Subject: [PATCH 20/22] ide: add ->pc_{update,io}_buffers methods

Add ->pc_{update,io}_buffers methods to ide_drive_t and use
them instead of {update,io}_buffers ide_pc_intr() arguments.

There should be no functional changes caused by this patch.

Cc: Borislav Petkov <[email protected]>
Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
drivers/ide/ide-atapi.c | 14 ++++++--------
drivers/ide/ide-floppy.c | 7 ++++---
drivers/ide/ide-tape.c | 7 ++++---
drivers/scsi/ide-scsi.c | 6 ++++--
include/linux/ide.h | 9 +++++----
5 files changed, 23 insertions(+), 20 deletions(-)

Index: b/drivers/ide/ide-atapi.c
===================================================================
--- a/drivers/ide/ide-atapi.c
+++ b/drivers/ide/ide-atapi.c
@@ -246,10 +246,7 @@ int ide_scsi_expiry(ide_drive_t *drive)
}
EXPORT_SYMBOL_GPL(ide_scsi_expiry);

-/* TODO: unify the code thus making some arguments go away */
-ide_startstop_t ide_pc_intr(ide_drive_t *drive, ide_handler_t *handler,
- void (*update_buffers)(ide_drive_t *, struct ide_atapi_pc *),
- int (*io_buffers)(ide_drive_t *, struct ide_atapi_pc *, unsigned, int))
+ide_startstop_t ide_pc_intr(ide_drive_t *drive, ide_handler_t *handler)
{
struct ide_atapi_pc *pc = drive->pc;
ide_hwif_t *hwif = drive->hwif;
@@ -290,8 +287,8 @@ ide_startstop_t ide_pc_intr(ide_drive_t
pc->flags |= PC_FLAG_DMA_ERROR;
} else {
pc->xferred = pc->req_xfer;
- if (update_buffers)
- update_buffers(drive, pc);
+ if (drive->pc_update_buffers)
+ drive->pc_update_buffers(drive, pc);
}
debug_log("%s: DMA finished\n", drive->name);
}
@@ -386,7 +383,8 @@ cmd_finished:
temp = 0;
if (temp) {
if (pc->sg)
- io_buffers(drive, pc, temp, 0);
+ drive->pc_io_buffers(drive, pc,
+ temp, 0);
else
tp_ops->input_data(drive, NULL,
pc->cur_pos, temp);
@@ -410,7 +408,7 @@ cmd_finished:
if ((drive->media == ide_floppy && !scsi && !pc->buf) ||
(drive->media == ide_tape && !scsi && pc->bh) ||
(scsi && pc->sg)) {
- int done = io_buffers(drive, pc, bcount,
+ int done = drive->pc_io_buffers(drive, pc, bcount,
!!(pc->flags & PC_FLAG_WRITING));

/* FIXME: don't do partial completions */
Index: b/drivers/ide/ide-floppy.c
===================================================================
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -195,8 +195,7 @@ static void ide_floppy_callback(ide_driv
/* The usual interrupt handler called during a packet command. */
static ide_startstop_t idefloppy_pc_intr(ide_drive_t *drive)
{
- return ide_pc_intr(drive, idefloppy_pc_intr, idefloppy_update_buffers,
- ide_io_buffers);
+ return ide_pc_intr(drive, idefloppy_pc_intr);
}

/*
@@ -635,7 +634,9 @@ static void idefloppy_setup(ide_drive_t

*((u16 *)&gcw) = id[ATA_ID_CONFIG];

- drive->pc_callback = ide_floppy_callback;
+ drive->pc_callback = ide_floppy_callback;
+ drive->pc_update_buffers = idefloppy_update_buffers;
+ drive->pc_io_buffers = ide_io_buffers;

if (((gcw[0] & 0x60) >> 5) == 1)
drive->atapi_flags |= IDE_AFLAG_DRQ_INTERRUPT;
Index: b/drivers/ide/ide-tape.c
===================================================================
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -627,8 +627,7 @@ static int ide_tape_io_buffers(ide_drive
*/
static ide_startstop_t idetape_pc_intr(ide_drive_t *drive)
{
- return ide_pc_intr(drive, idetape_pc_intr, idetape_update_buffers,
- ide_tape_io_buffers);
+ return ide_pc_intr(drive, idetape_pc_intr);
}

/*
@@ -2210,7 +2209,9 @@ static void idetape_setup(ide_drive_t *d
u8 gcw[2];
u16 *ctl = (u16 *)&tape->caps[12];

- drive->pc_callback = ide_tape_callback;
+ drive->pc_callback = ide_tape_callback;
+ drive->pc_update_buffers = idetape_update_buffers;
+ drive->pc_io_buffers = ide_tape_io_buffers;

spin_lock_init(&tape->lock);
drive->dsc_overlap = 1;
Index: b/drivers/scsi/ide-scsi.c
===================================================================
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -275,7 +275,7 @@ static int idescsi_end_request (ide_driv
*/
static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive)
{
- return ide_pc_intr(drive, idescsi_pc_intr, NULL, ide_io_buffers);
+ return ide_pc_intr(drive, idescsi_pc_intr);
}

static ide_startstop_t idescsi_transfer_pc(ide_drive_t *drive)
@@ -407,7 +407,9 @@ static void idescsi_setup (ide_drive_t *
set_bit(IDESCSI_LOG_CMD, &scsi->log);
#endif /* IDESCSI_DEBUG_LOG */

- drive->pc_callback = ide_scsi_callback;
+ drive->pc_callback = ide_scsi_callback;
+ drive->pc_update_buffers = NULL;
+ drive->pc_io_buffers = ide_io_buffers;

ide_proc_register_driver(drive, scsi->driver);
}
Index: b/include/linux/ide.h
===================================================================
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -552,6 +552,10 @@ struct ide_drive_s {
/* callback for packet commands */
void (*pc_callback)(struct ide_drive_s *, int);

+ void (*pc_update_buffers)(struct ide_drive_s *, struct ide_atapi_pc *);
+ int (*pc_io_buffers)(struct ide_drive_s *, struct ide_atapi_pc *,
+ unsigned int, int);
+
unsigned long atapi_flags;

struct ide_atapi_pc request_sense_pc;
@@ -1173,10 +1177,7 @@ static inline unsigned long ide_scsi_get

int ide_scsi_expiry(ide_drive_t *);

-ide_startstop_t ide_pc_intr(ide_drive_t *drive, ide_handler_t *handler,
- void (*update_buffers)(ide_drive_t *, struct ide_atapi_pc *),
- int (*io_buffers)(ide_drive_t *, struct ide_atapi_pc *, unsigned int,
- int));
+ide_startstop_t ide_pc_intr(ide_drive_t *drive, ide_handler_t *handler);
ide_startstop_t ide_transfer_pc(ide_drive_t *,
ide_handler_t *, unsigned int, ide_expiry_t *);
ide_startstop_t ide_issue_pc(ide_drive_t *,

Subject: [PATCH 21/22] ide: make ide_pc_intr() static

* Always use ide_pc_intr as a handler in ide_pc_intr().

* Remove no longer used ide*_pc_intr() and 'handler'
argument from ide_{transfer_pc,pc_intr}().

* Make ide_pc_intr() static.

There should be no functional changes caused by this patch.

Cc: Borislav Petkov <[email protected]>
Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
drivers/ide/ide-atapi.c | 15 +++++++++------
drivers/ide/ide-floppy.c | 10 ++--------
drivers/ide/ide-tape.c | 18 +++---------------
drivers/scsi/ide-scsi.c | 11 +----------
include/linux/ide.h | 4 +---
5 files changed, 16 insertions(+), 42 deletions(-)

Index: b/drivers/ide/ide-atapi.c
===================================================================
--- a/drivers/ide/ide-atapi.c
+++ b/drivers/ide/ide-atapi.c
@@ -246,7 +246,12 @@ int ide_scsi_expiry(ide_drive_t *drive)
}
EXPORT_SYMBOL_GPL(ide_scsi_expiry);

-ide_startstop_t ide_pc_intr(ide_drive_t *drive, ide_handler_t *handler)
+/*
+ * This is the usual interrupt handler which will be called during a packet
+ * command. We will transfer some of the data (as requested by the drive)
+ * and will re-point interrupt handler to us.
+ */
+static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
{
struct ide_atapi_pc *pc = drive->pc;
ide_hwif_t *hwif = drive->hwif;
@@ -425,10 +430,9 @@ cmd_finished:
rq->cmd[0], bcount);
next_irq:
/* And set the interrupt handler again */
- ide_set_handler(drive, handler, timeout, expiry);
+ ide_set_handler(drive, ide_pc_intr, timeout, expiry);
return ide_started;
}
-EXPORT_SYMBOL_GPL(ide_pc_intr);

static u8 ide_read_ireason(ide_drive_t *drive)
{
@@ -464,8 +468,7 @@ static u8 ide_wait_ireason(ide_drive_t *
return ireason;
}

-ide_startstop_t ide_transfer_pc(ide_drive_t *drive,
- ide_handler_t *handler, unsigned int timeout,
+ide_startstop_t ide_transfer_pc(ide_drive_t *drive, unsigned int timeout,
ide_expiry_t *expiry)
{
struct ide_atapi_pc *pc = drive->pc;
@@ -491,7 +494,7 @@ ide_startstop_t ide_transfer_pc(ide_driv
}

/* Set the interrupt routine */
- ide_set_handler(drive, handler, timeout, expiry);
+ ide_set_handler(drive, ide_pc_intr, timeout, expiry);

/* Begin DMA, if necessary */
if (pc->flags & PC_FLAG_DMA_OK) {
Index: b/drivers/ide/ide-floppy.c
===================================================================
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -192,12 +192,6 @@ static void ide_floppy_callback(ide_driv
idefloppy_end_request(drive, uptodate, 0);
}

-/* The usual interrupt handler called during a packet command. */
-static ide_startstop_t idefloppy_pc_intr(ide_drive_t *drive)
-{
- return ide_pc_intr(drive, idefloppy_pc_intr);
-}
-
/*
* What we have here is a classic case of a top half / bottom half interrupt
* service routine. In interrupt mode, the device sends an interrupt to signal
@@ -229,7 +223,7 @@ static ide_startstop_t idefloppy_start_p
* where the Busy flag was apparently being deasserted before the
* unit was ready to receive data. This was happening on a
* 1200 MHz Athlon system. 10/26/01 25msec is too short,
- * 40 and 50msec work well. idefloppy_pc_intr will not be actually
+ * 40 and 50msec work well. ide_pc_intr will not be actually
* used until after the packet is moved in about 50 msec.
*/
if (drive->atapi_flags & IDE_AFLAG_ZIP_DRIVE) {
@@ -240,7 +234,7 @@ static ide_startstop_t idefloppy_start_p
expiry = NULL;
}

- return ide_transfer_pc(drive, idefloppy_pc_intr, timeout, expiry);
+ return ide_transfer_pc(drive, timeout, expiry);
}

static void ide_floppy_report_error(idefloppy_floppy_t *floppy,
Index: b/drivers/ide/ide-tape.c
===================================================================
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -619,18 +619,6 @@ static int ide_tape_io_buffers(ide_drive
}

/*
- * This is the usual interrupt handler which will be called during a packet
- * command. We will transfer some of the data (as requested by the drive) and
- * will re-point interrupt handler to us. When data transfer is finished, we
- * will act according to the algorithm described before
- * idetape_issue_pc.
- */
-static ide_startstop_t idetape_pc_intr(ide_drive_t *drive)
-{
- return ide_pc_intr(drive, idetape_pc_intr);
-}
-
-/*
* Packet Command Interface
*
* The current Packet Command is available in drive->pc, and will not change
@@ -640,9 +628,9 @@ static ide_startstop_t idetape_pc_intr(i
* The handling will be done in three stages:
*
* 1. idetape_issue_pc will send the packet command to the drive, and will set
- * the interrupt handler to idetape_pc_intr.
+ * the interrupt handler to ide_pc_intr.
*
- * 2. On each interrupt, idetape_pc_intr will be called. This step will be
+ * 2. On each interrupt, ide_pc_intr will be called. This step will be
* repeated until the device signals us that no more interrupts will be issued.
*
* 3. ATAPI Tape media access commands have immediate status with a delayed
@@ -668,7 +656,7 @@ static ide_startstop_t idetape_pc_intr(i
*/
static ide_startstop_t idetape_transfer_pc(ide_drive_t *drive)
{
- return ide_transfer_pc(drive, idetape_pc_intr, WAIT_TAPE_CMD, NULL);
+ return ide_transfer_pc(drive, WAIT_TAPE_CMD, NULL);
}

static ide_startstop_t idetape_issue_pc(ide_drive_t *drive,
Index: b/drivers/scsi/ide-scsi.c
===================================================================
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -270,18 +270,9 @@ static int idescsi_end_request (ide_driv
return 0;
}

-/*
- * Our interrupt handler.
- */
-static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive)
-{
- return ide_pc_intr(drive, idescsi_pc_intr);
-}
-
static ide_startstop_t idescsi_transfer_pc(ide_drive_t *drive)
{
- return ide_transfer_pc(drive, idescsi_pc_intr,
- ide_scsi_get_timeout(drive->pc),
+ return ide_transfer_pc(drive, ide_scsi_get_timeout(drive->pc),
ide_scsi_expiry);
}

Index: b/include/linux/ide.h
===================================================================
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -1177,9 +1177,7 @@ static inline unsigned long ide_scsi_get

int ide_scsi_expiry(ide_drive_t *);

-ide_startstop_t ide_pc_intr(ide_drive_t *drive, ide_handler_t *handler);
-ide_startstop_t ide_transfer_pc(ide_drive_t *,
- ide_handler_t *, unsigned int, ide_expiry_t *);
+ide_startstop_t ide_transfer_pc(ide_drive_t *, unsigned int, ide_expiry_t *);
ide_startstop_t ide_issue_pc(ide_drive_t *,
ide_handler_t *, unsigned int, ide_expiry_t *);

Subject: [PATCH 22/22] ide: make ide_transfer_pc() static

* Move ->ticks field from struct ide_floppy_obj to ide_drive_t.

* Move idefloppy_transfer_pc() to ide-atapi.c and make
ide_transfer_pc() use it.

* Always use ide_transfer_pc as a handler in ide_issue_pc().

* Remove no longer used idefloppy_start_pc_transfer(),
ide*_transfer_pc() and 'handler' argument from ide_issue_pc().

* Make ide_transfer_pc() static.

While at it:

* idefloppy_transfer_pc() -> ide_delayed_transfer_pc()

* IDEFLOPPY_TICKS_DELAY -> IDEFLOPPY_PC_DELAY

* ->ticks -> ->pc_delay

There should be no functional changes caused by this patch.

Cc: Borislav Petkov <[email protected]>
Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
drivers/ide/ide-atapi.c | 41 ++++++++++++++++++++++----
drivers/ide/ide-floppy.c | 72 +++++------------------------------------------
drivers/ide/ide-floppy.h | 3 -
drivers/ide/ide-tape.c | 6 ---
drivers/scsi/ide-scsi.c | 9 -----
include/linux/ide.h | 7 ++--
6 files changed, 49 insertions(+), 89 deletions(-)

Index: b/drivers/ide/ide-atapi.c
===================================================================
--- a/drivers/ide/ide-atapi.c
+++ b/drivers/ide/ide-atapi.c
@@ -468,12 +468,22 @@ static u8 ide_wait_ireason(ide_drive_t *
return ireason;
}

-ide_startstop_t ide_transfer_pc(ide_drive_t *drive, unsigned int timeout,
- ide_expiry_t *expiry)
+static int ide_delayed_transfer_pc(ide_drive_t *drive)
+{
+ /* Send the actual packet */
+ drive->hwif->tp_ops->output_data(drive, NULL, drive->pc->c, 12);
+
+ /* Timeout for the packet command */
+ return WAIT_FLOPPY_CMD;
+}
+
+static ide_startstop_t ide_transfer_pc(ide_drive_t *drive)
{
struct ide_atapi_pc *pc = drive->pc;
ide_hwif_t *hwif = drive->hwif;
struct request *rq = hwif->hwgroup->rq;
+ ide_expiry_t *expiry;
+ unsigned int timeout;
ide_startstop_t startstop;
u8 ireason;

@@ -493,6 +503,25 @@ ide_startstop_t ide_transfer_pc(ide_driv
return ide_do_reset(drive);
}

+ /*
+ * If necessary schedule the packet transfer to occur 'timeout'
+ * miliseconds later in ide_delayed_transfer_pc() after the device
+ * says it's ready for a packet.
+ */
+ if (drive->atapi_flags & IDE_AFLAG_ZIP_DRIVE) {
+ timeout = drive->pc_delay;
+ expiry = &ide_delayed_transfer_pc;
+ } else {
+ if (drive->scsi) {
+ timeout = ide_scsi_get_timeout(pc);
+ expiry = ide_scsi_expiry;
+ } else {
+ timeout = (drive->media == ide_floppy) ? WAIT_FLOPPY_CMD
+ : WAIT_TAPE_CMD;
+ expiry = NULL;
+ }
+ }
+
/* Set the interrupt routine */
ide_set_handler(drive, ide_pc_intr, timeout, expiry);

@@ -508,10 +537,8 @@ ide_startstop_t ide_transfer_pc(ide_driv

return ide_started;
}
-EXPORT_SYMBOL_GPL(ide_transfer_pc);

-ide_startstop_t ide_issue_pc(ide_drive_t *drive,
- ide_handler_t *handler, unsigned int timeout,
+ide_startstop_t ide_issue_pc(ide_drive_t *drive, unsigned int timeout,
ide_expiry_t *expiry)
{
struct ide_atapi_pc *pc = drive->pc;
@@ -550,12 +577,12 @@ ide_startstop_t ide_issue_pc(ide_drive_t

/* Issue the packet command */
if (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT) {
- ide_execute_command(drive, ATA_CMD_PACKET, handler,
+ ide_execute_command(drive, ATA_CMD_PACKET, ide_transfer_pc,
timeout, NULL);
return ide_started;
} else {
ide_execute_pkt_cmd(drive);
- return (*handler)(drive);
+ return ide_transfer_pc(drive);
}
}
EXPORT_SYMBOL_GPL(ide_issue_pc);
Index: b/drivers/ide/ide-floppy.c
===================================================================
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -72,7 +72,11 @@
#define CAPACITY_CURRENT 0x02
#define CAPACITY_NO_CARTRIDGE 0x03

-#define IDEFLOPPY_TICKS_DELAY HZ/20 /* default delay for ZIP 100 (50ms) */
+/*
+ * The following delay solves a problem with ATAPI Zip 100 drive where BSY bit
+ * was apparently being deasserted before the unit was ready to receive data.
+ */
+#define IDEFLOPPY_PC_DELAY (HZ/20) /* default delay for ZIP 100 (50ms) */

/* Error code returned in rq->errors to the higher part of the driver. */
#define IDEFLOPPY_ERROR_GENERAL 101
@@ -192,51 +196,6 @@ static void ide_floppy_callback(ide_driv
idefloppy_end_request(drive, uptodate, 0);
}

-/*
- * What we have here is a classic case of a top half / bottom half interrupt
- * service routine. In interrupt mode, the device sends an interrupt to signal
- * that it is ready to receive a packet. However, we need to delay about 2-3
- * ticks before issuing the packet or we gets in trouble.
- */
-static int idefloppy_transfer_pc(ide_drive_t *drive)
-{
- /* Send the actual packet */
- drive->hwif->tp_ops->output_data(drive, NULL, drive->pc->c, 12);
-
- /* Timeout for the packet command */
- return WAIT_FLOPPY_CMD;
-}
-
-/*
- * Called as an interrupt (or directly). When the device says it's ready for a
- * packet, we schedule the packet transfer to occur about 2-3 ticks later in
- * transfer_pc.
- */
-static ide_startstop_t idefloppy_start_pc_transfer(ide_drive_t *drive)
-{
- idefloppy_floppy_t *floppy = drive->driver_data;
- ide_expiry_t *expiry;
- unsigned int timeout;
-
- /*
- * The following delay solves a problem with ATAPI Zip 100 drives
- * where the Busy flag was apparently being deasserted before the
- * unit was ready to receive data. This was happening on a
- * 1200 MHz Athlon system. 10/26/01 25msec is too short,
- * 40 and 50msec work well. ide_pc_intr will not be actually
- * used until after the packet is moved in about 50 msec.
- */
- if (drive->atapi_flags & IDE_AFLAG_ZIP_DRIVE) {
- timeout = floppy->ticks;
- expiry = &idefloppy_transfer_pc;
- } else {
- timeout = WAIT_FLOPPY_CMD;
- expiry = NULL;
- }
-
- return ide_transfer_pc(drive, timeout, expiry);
-}
-
static void ide_floppy_report_error(idefloppy_floppy_t *floppy,
struct ide_atapi_pc *pc)
{
@@ -280,8 +239,7 @@ static ide_startstop_t idefloppy_issue_p

pc->retries++;

- return ide_issue_pc(drive, idefloppy_start_pc_transfer,
- WAIT_FLOPPY_CMD, NULL);
+ return ide_issue_pc(drive, WAIT_FLOPPY_CMD, NULL);
}

void ide_floppy_create_read_capacity_cmd(struct ide_atapi_pc *pc)
@@ -596,21 +554,7 @@ static sector_t idefloppy_capacity(ide_d
ide_devset_rw(bios_cyl, 0, 1023, bios_cyl);
ide_devset_rw(bios_head, 0, 255, bios_head);
ide_devset_rw(bios_sect, 0, 63, bios_sect);
-
-static int get_ticks(ide_drive_t *drive)
-{
- idefloppy_floppy_t *floppy = drive->driver_data;
- return floppy->ticks;
-}
-
-static int set_ticks(ide_drive_t *drive, int arg)
-{
- idefloppy_floppy_t *floppy = drive->driver_data;
- floppy->ticks = arg;
- return 0;
-}
-
-IDE_DEVSET(ticks, S_RW, 0, 255, get_ticks, set_ticks);
+ide_devset_rw(ticks, 0, 255, pc_delay);

static const struct ide_devset *idefloppy_settings[] = {
&ide_devset_bios_cyl,
@@ -646,7 +590,7 @@ static void idefloppy_setup(ide_drive_t
if (!strncmp((char *)&id[ATA_ID_PROD], "IOMEGA ZIP 100 ATAPI", 20)) {
drive->atapi_flags |= IDE_AFLAG_ZIP_DRIVE;
/* This value will be visible in the /proc/ide/hdx/settings */
- floppy->ticks = IDEFLOPPY_TICKS_DELAY;
+ drive->pc_delay = IDEFLOPPY_PC_DELAY;
blk_queue_max_sectors(drive->queue, 64);
}

Index: b/drivers/ide/ide-floppy.h
===================================================================
--- a/drivers/ide/ide-floppy.h
+++ b/drivers/ide/ide-floppy.h
@@ -20,8 +20,7 @@ typedef struct ide_floppy_obj {

/* Last error information */
u8 sense_key, asc, ascq;
- /* delay this long before sending packet command */
- u8 ticks;
+
int progress_indication;

/* Device information */
Index: b/drivers/ide/ide-tape.c
===================================================================
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -654,10 +654,6 @@ static int ide_tape_io_buffers(ide_drive
* again, the callback function will be called and then we will handle the next
* request.
*/
-static ide_startstop_t idetape_transfer_pc(ide_drive_t *drive)
-{
- return ide_transfer_pc(drive, WAIT_TAPE_CMD, NULL);
-}

static ide_startstop_t idetape_issue_pc(ide_drive_t *drive,
struct ide_atapi_pc *pc)
@@ -705,7 +701,7 @@ static ide_startstop_t idetape_issue_pc(

pc->retries++;

- return ide_issue_pc(drive, idetape_transfer_pc, WAIT_TAPE_CMD, NULL);
+ return ide_issue_pc(drive, WAIT_TAPE_CMD, NULL);
}

/* A mode sense command is used to "sense" tape parameters. */
Index: b/drivers/scsi/ide-scsi.c
===================================================================
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -270,12 +270,6 @@ static int idescsi_end_request (ide_driv
return 0;
}

-static ide_startstop_t idescsi_transfer_pc(ide_drive_t *drive)
-{
- return ide_transfer_pc(drive, ide_scsi_get_timeout(drive->pc),
- ide_scsi_expiry);
-}
-
static inline int idescsi_set_direction(struct ide_atapi_pc *pc)
{
switch (pc->c[0]) {
@@ -321,8 +315,7 @@ static ide_startstop_t idescsi_issue_pc(
/* Set the current packet command */
drive->pc = pc;

- return ide_issue_pc(drive, idescsi_transfer_pc,
- ide_scsi_get_timeout(pc), ide_scsi_expiry);
+ return ide_issue_pc(drive, ide_scsi_get_timeout(pc), ide_scsi_expiry);
}

/*
Index: b/include/linux/ide.h
===================================================================
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -528,6 +528,9 @@ struct ide_drive_s {
u8 bios_head; /* BIOS/fdisk/LILO number of heads */
u8 bios_sect; /* BIOS/fdisk/LILO sectors per track */

+ /* delay this long before sending packet command */
+ u8 pc_delay;
+
unsigned int bios_cyl; /* BIOS/fdisk/LILO number of cyls */
unsigned int cyl; /* "real" number of cyls */
unsigned int drive_data; /* used by set_pio_mode/selectproc */
@@ -1177,9 +1180,7 @@ static inline unsigned long ide_scsi_get

int ide_scsi_expiry(ide_drive_t *);

-ide_startstop_t ide_transfer_pc(ide_drive_t *, unsigned int, ide_expiry_t *);
-ide_startstop_t ide_issue_pc(ide_drive_t *,
- ide_handler_t *, unsigned int, ide_expiry_t *);
+ide_startstop_t ide_issue_pc(ide_drive_t *, unsigned int, ide_expiry_t *);

ide_startstop_t do_rw_taskfile(ide_drive_t *, ide_task_t *);

2008-08-11 06:02:50

by Borislav Petkov

[permalink] [raw]
Subject: Re: [PATCH 11/22] ide: add ide_set_media_lock() helper

Hi,

On Sun, Aug 10, 2008 at 05:36:45PM +0200, Bartlomiej Zolnierkiewicz wrote:
> * Set IDE_AFLAG_NO_DOORLOCK in idetape_get_mode_sense_result(), check it
> in ide_tape_set_media_lock() and cleanup idetape_create_prevent_cmd().
>
> * Set IDE_AFLAG_NO_DOORLOCK in ide_floppy_create_read_capacity_cmd() and
> check it instead of IDE_AFLAG_CLIK_DRIVE in ide_floppy_set_media_lock().
>
> * Add ide_set_media_lock() helper and convert ide-{floppy,tape}.c to use it.
>
> * Remove no longer used ide*_create_prevent_cmd()/ide*_set_media_lock().
>
> * Update comment in <linux/ide.h> accordingly.
>
> Cc: Borislav Petkov <[email protected]>
> Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
> ---
> drivers/ide/ide-atapi.c | 15 +++++++++++++++
> drivers/ide/ide-floppy.c | 32 +++++++-------------------------
> drivers/ide/ide-tape.c | 41 ++++++++++-------------------------------
> include/linux/ide.h | 6 ++++--
> 4 files changed, 36 insertions(+), 58 deletions(-)
>
> Index: b/drivers/ide/ide-atapi.c
> ===================================================================
> --- a/drivers/ide/ide-atapi.c
> +++ b/drivers/ide/ide-atapi.c
> @@ -162,6 +162,21 @@ int ide_queue_pc_tail(ide_drive_t *drive
> }
> EXPORT_SYMBOL_GPL(ide_queue_pc_tail);
>
> +int ide_set_media_lock(ide_drive_t *drive, struct gendisk *disk, int on)
> +{
> + struct ide_atapi_pc pc;
> +
> + if (drive->atapi_flags & IDE_AFLAG_NO_DOORLOCK)
> + return 0;
> +
> + ide_init_pc(&pc);
> + pc.c[0] = ALLOW_MEDIUM_REMOVAL;

Are we switching to SCSI opcodes? What about the generic packet commands in
<include/linux/cdrom.h>?

> + pc.c[4] = on;
> +
> + return ide_queue_pc_tail(drive, disk, &pc);
> +}
> +EXPORT_SYMBOL_GPL(ide_set_media_lock);
> +
> /* TODO: unify the code thus making some arguments go away */
> ide_startstop_t ide_pc_intr(ide_drive_t *drive, struct ide_atapi_pc *pc,
> ide_handler_t *handler, unsigned int timeout, ide_expiry_t *expiry,
> Index: b/drivers/ide/ide-floppy.c
> ===================================================================
> --- a/drivers/ide/ide-floppy.c
> +++ b/drivers/ide/ide-floppy.c
> @@ -324,15 +324,6 @@ static ide_startstop_t idefloppy_issue_p
> IDEFLOPPY_WAIT_CMD, NULL);
> }
>
> -static void idefloppy_create_prevent_cmd(struct ide_atapi_pc *pc, int prevent)
> -{
> - debug_log("creating prevent removal command, prevent = %d\n", prevent);
> -
> - ide_init_pc(pc);
> - pc->c[0] = GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL;
> - pc->c[4] = prevent;
> -}
> -
> void ide_floppy_create_read_capacity_cmd(struct ide_atapi_pc *pc)
> {
> ide_init_pc(pc);
> @@ -711,6 +702,8 @@ static void idefloppy_setup(ide_drive_t
> if (strncmp((char *)&id[ATA_ID_PROD], "IOMEGA Clik!", 11) == 0) {
> blk_queue_max_sectors(drive->queue, 64);
> drive->atapi_flags |= IDE_AFLAG_CLIK_DRIVE;
> + /* IOMEGA Clik! drives do not support lock/unlock commands */
> + drive->atapi_flags |= IDE_AFLAG_NO_DOORLOCK;
> }
>
> (void) ide_floppy_get_capacity(drive);
> @@ -781,18 +774,6 @@ static ide_driver_t idefloppy_driver = {
> #endif
> };
>
> -static void ide_floppy_set_media_lock(ide_drive_t *drive, int on)
> -{
> - struct ide_floppy_obj *floppy = drive->driver_data;
> - struct ide_atapi_pc pc;
> -
> - /* IOMEGA Clik! drives do not support lock/unlock commands */
> - if ((drive->atapi_flags & IDE_AFLAG_CLIK_DRIVE) == 0) {
> - idefloppy_create_prevent_cmd(&pc, on);
> - (void)ide_queue_pc_tail(drive, floppy->disk, &pc);
> - }
> -}
> -
> static int idefloppy_open(struct inode *inode, struct file *filp)
> {
> struct gendisk *disk = inode->i_bdev->bd_disk;
> @@ -841,7 +822,7 @@ static int idefloppy_open(struct inode *
> }
>
> drive->atapi_flags |= IDE_AFLAG_MEDIA_CHANGED;
> - ide_floppy_set_media_lock(drive, 1);
> + ide_set_media_lock(drive, disk, 1);
> check_disk_change(inode->i_bdev);
> } else if (drive->atapi_flags & IDE_AFLAG_FORMAT_IN_PROGRESS) {
> ret = -EBUSY;
> @@ -864,7 +845,7 @@ static int idefloppy_release(struct inod
> debug_log("Reached %s\n", __func__);
>
> if (floppy->openers == 1) {
> - ide_floppy_set_media_lock(drive, 0);
> + ide_set_media_lock(drive, disk, 0);
> drive->atapi_flags &= ~IDE_AFLAG_FORMAT_IN_PROGRESS;
> }
>
> @@ -890,16 +871,17 @@ static int ide_floppy_lockdoor(ide_drive
> unsigned long arg, unsigned int cmd)
> {
> idefloppy_floppy_t *floppy = drive->driver_data;
> + struct gendisk *disk = floppy->disk;
> int prevent = (arg && cmd != CDROMEJECT) ? 1 : 0;
>
> if (floppy->openers > 1)
> return -EBUSY;
>
> - ide_floppy_set_media_lock(drive, prevent);
> + ide_set_media_lock(drive, disk, prevent);
>
> if (cmd == CDROMEJECT) {
> idefloppy_create_start_stop_cmd(pc, 2);
> - (void)ide_queue_pc_tail(drive, floppy->disk, pc);
> + (void)ide_queue_pc_tail(drive, disk, pc);
> }
>
> return 0;
> Index: b/drivers/ide/ide-tape.c
> ===================================================================
> --- a/drivers/ide/ide-tape.c
> +++ b/drivers/ide/ide-tape.c
> @@ -1213,32 +1213,6 @@ static void idetape_create_locate_cmd(id
> pc->flags |= PC_FLAG_WAIT_FOR_DSC;
> }
>
> -static int idetape_create_prevent_cmd(ide_drive_t *drive,
> - struct ide_atapi_pc *pc, int prevent)
> -{
> - idetape_tape_t *tape = drive->driver_data;
> -
> - /* device supports locking according to capabilities page */
> - if (!(tape->caps[6] & 0x01))
> - return 0;
> -
> - ide_init_pc(pc);
> - pc->c[0] = ALLOW_MEDIUM_REMOVAL;
> - pc->c[4] = prevent;
> - return 1;
> -}
> -
> -static int ide_tape_set_media_lock(ide_drive_t *drive, int on)
> -{
> - struct ide_tape_obj *tape = drive->driver_data;
> - struct ide_atapi_pc pc;
> -
> - if (!idetape_create_prevent_cmd(drive, &pc, on))
> - return 0;
> -
> - return ide_queue_pc_tail(drive, tape->disk, &pc);
> -}
> -
> static void __ide_tape_discard_merge_buffer(ide_drive_t *drive)
> {
> idetape_tape_t *tape = drive->driver_data;
> @@ -1871,7 +1845,7 @@ static int idetape_mtioctop(ide_drive_t
> * attempting to eject.
> */
> if (tape->door_locked) {
> - if (!ide_tape_set_media_lock(drive, 0))
> + if (!ide_set_media_lock(drive, disk, 0))
> tape->door_locked = DOOR_UNLOCKED;
> }
> ide_tape_discard_merge_buffer(drive, 0);
> @@ -1916,13 +1890,13 @@ static int idetape_mtioctop(ide_drive_t
> case MTFSR:
> case MTBSR:
> case MTLOCK:
> - retval = ide_tape_set_media_lock(drive, 1);
> + retval = ide_set_media_lock(drive, disk, 1);
> if (retval)
> return retval;
> tape->door_locked = DOOR_EXPLICITLY_LOCKED;
> return 0;
> case MTUNLOCK:
> - retval = ide_tape_set_media_lock(drive, 0);
> + retval = ide_set_media_lock(drive, disk, 0);
> if (retval)
> return retval;
> tape->door_locked = DOOR_UNLOCKED;
> @@ -2086,7 +2060,7 @@ static int idetape_chrdev_open(struct in
>
> /* Lock the tape drive door so user can't eject. */
> if (tape->chrdev_dir == IDETAPE_DIR_NONE) {
> - if (!ide_tape_set_media_lock(drive, 1)) {
> + if (!ide_set_media_lock(drive, tape->disk, 1)) {
> if (tape->door_locked != DOOR_EXPLICITLY_LOCKED)
> tape->door_locked = DOOR_LOCKED;
> }
> @@ -2139,7 +2113,7 @@ static int idetape_chrdev_release(struct
> (void) idetape_rewind_tape(drive);
> if (tape->chrdev_dir == IDETAPE_DIR_NONE) {
> if (tape->door_locked == DOOR_LOCKED) {
> - if (!ide_tape_set_media_lock(drive, 0))
> + if (!ide_set_media_lock(drive, tape->disk, 0))
> tape->door_locked = DOOR_UNLOCKED;
> }
> }
> @@ -2217,6 +2191,11 @@ static void idetape_get_mode_sense_resul
> }
>
> memcpy(&tape->caps, caps, 20);
> +
> + /* device lacks locking support according to capabilities page */
> + if ((caps[6] & 1) == 0)
> + drive->atapi_flags |= IDE_AFLAG_NO_DOORLOCK;
> +
> if (caps[7] & 0x02)
> tape->blk_size = 512;
> else if (caps[7] & 0x04)
> Index: b/include/linux/ide.h
> ===================================================================
> --- a/include/linux/ide.h
> +++ b/include/linux/ide.h
> @@ -317,10 +317,10 @@ struct ide_acpi_hwif_link;
> enum {
> IDE_AFLAG_DRQ_INTERRUPT = (1 << 0),
> IDE_AFLAG_MEDIA_CHANGED = (1 << 1),
> -
> - /* ide-cd */
> /* Drive cannot lock the door. */
> IDE_AFLAG_NO_DOORLOCK = (1 << 2),
> +
> + /* ide-cd */
> /* Drive cannot eject the disc. */
> IDE_AFLAG_NO_EJECT = (1 << 3),
> /* Drive is a pre ATAPI 1.2 drive. */
> @@ -1140,6 +1140,8 @@ void ide_queue_pc_head(ide_drive_t *, st
> struct request *);
> int ide_queue_pc_tail(ide_drive_t *, struct gendisk *, struct ide_atapi_pc *);
>
> +int ide_set_media_lock(ide_drive_t *, struct gendisk *, int);
> +
> ide_startstop_t ide_pc_intr(ide_drive_t *drive, struct ide_atapi_pc *pc,
> ide_handler_t *handler, unsigned int timeout, ide_expiry_t *expiry,
> void (*update_buffers)(ide_drive_t *, struct ide_atapi_pc *),

--
Regards/Gruss,
Boris.

2008-08-11 06:37:17

by Borislav Petkov

[permalink] [raw]
Subject: Re: [PATCH 00/22] ide: more work on generic ATAPI support

On Sun, Aug 10, 2008 at 05:35:27PM +0200, Bartlomiej Zolnierkiewicz wrote:
>
> Just some more work on generic ATAPI layer...
>
> - code unifications here and there
>
> - move IDEFLOPPY_IOCTL_FORMAT_* support to a separate file
>
> - ide_pc_intr() no longer requires zillion of arguments
>
> Applies on top of current pata tree, tested with ide-scsi.
>
> diffstat:
> drivers/ide/Makefile | 3
> drivers/ide/ide-atapi.c | 323 +++++++++++++++--
> drivers/ide/ide-floppy.c | 739 ++++++-----------------------------------
> drivers/ide/ide-floppy.h | 72 +++
> drivers/ide/ide-floppy_ioctl.c | 245 +++++++++++++
> drivers/ide/ide-tape.c | 396 ++++++---------------
> drivers/scsi/ide-scsi.c | 178 ++-------
> include/linux/ide.h | 266 +++++++++-----
> 8 files changed, 1035 insertions(+), 1187 deletions(-)

ACK 1-14, looks good so far. Will review the rest of them later and do some
testing.

--
Regards/Gruss,
Boris.

Subject: Re: [PATCH 11/22] ide: add ide_set_media_lock() helper

On Monday 11 August 2008, Borislav Petkov wrote:
> Hi,
>
> On Sun, Aug 10, 2008 at 05:36:45PM +0200, Bartlomiej Zolnierkiewicz wrote:
> > * Set IDE_AFLAG_NO_DOORLOCK in idetape_get_mode_sense_result(), check it
> > in ide_tape_set_media_lock() and cleanup idetape_create_prevent_cmd().
> >
> > * Set IDE_AFLAG_NO_DOORLOCK in ide_floppy_create_read_capacity_cmd() and
> > check it instead of IDE_AFLAG_CLIK_DRIVE in ide_floppy_set_media_lock().
> >
> > * Add ide_set_media_lock() helper and convert ide-{floppy,tape}.c to use it.
> >
> > * Remove no longer used ide*_create_prevent_cmd()/ide*_set_media_lock().
> >
> > * Update comment in <linux/ide.h> accordingly.
> >
> > Cc: Borislav Petkov <[email protected]>
> > Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
> > ---
> > drivers/ide/ide-atapi.c | 15 +++++++++++++++
> > drivers/ide/ide-floppy.c | 32 +++++++-------------------------
> > drivers/ide/ide-tape.c | 41 ++++++++++-------------------------------
> > include/linux/ide.h | 6 ++++--
> > 4 files changed, 36 insertions(+), 58 deletions(-)
> >
> > Index: b/drivers/ide/ide-atapi.c
> > ===================================================================
> > --- a/drivers/ide/ide-atapi.c
> > +++ b/drivers/ide/ide-atapi.c
> > @@ -162,6 +162,21 @@ int ide_queue_pc_tail(ide_drive_t *drive
> > }
> > EXPORT_SYMBOL_GPL(ide_queue_pc_tail);
> >
> > +int ide_set_media_lock(ide_drive_t *drive, struct gendisk *disk, int on)
> > +{
> > + struct ide_atapi_pc pc;
> > +
> > + if (drive->atapi_flags & IDE_AFLAG_NO_DOORLOCK)
> > + return 0;
> > +
> > + ide_init_pc(&pc);
> > + pc.c[0] = ALLOW_MEDIUM_REMOVAL;
>
> Are we switching to SCSI opcodes? What about the generic packet commands in
> <include/linux/cdrom.h>?

I prefer to use them when possible but there is no strict policy.

[ SCSI defines are shorter, one of the drivers was using them already
and it also makes easier for comparing code with SCSI. ]

2008-08-12 13:37:49

by Borislav Petkov

[permalink] [raw]
Subject: Re: [PATCH 11/22] ide: add ide_set_media_lock() helper

>> Are we switching to SCSI opcodes? What about the generic packet commands in
>> <include/linux/cdrom.h>?
>
> I prefer to use them when possible but there is no strict policy.
>
> [ SCSI defines are shorter, one of the drivers was using them already
> and it also makes easier for comparing code with SCSI. ]

I still think we should stick to one format or the other. All
the drivers' functions, for example, comply with a naming scheme
(ide_cd/ide_floppy/...) so opcodes shouldn't be an exception, imho...

--
Regards/Gruss,
Boris

Subject: Re: [PATCH 11/22] ide: add ide_set_media_lock() helper

On Tuesday 12 August 2008, Boris Petkov wrote:
> >> Are we switching to SCSI opcodes? What about the generic packet commands in
> >> <include/linux/cdrom.h>?
> >
> > I prefer to use them when possible but there is no strict policy.
> >
> > [ SCSI defines are shorter, one of the drivers was using them already
> > and it also makes easier for comparing code with SCSI. ]
>
> I still think we should stick to one format or the other. All
> the drivers' functions, for example, comply with a naming scheme
> (ide_cd/ide_floppy/...) so opcodes shouldn't be an exception, imho...

Some opcodes are only in <linux/cdrom.h> while the other ones only
in <scsi/scsi.h> so it is not that simple without additional effort.

I don't have a time for it at the moment (+ I consider it a low-prio
task). However if you would like to look into it, please go ahead.

Thanks,
Bart

2008-08-23 11:49:43

by Sergei Shtylyov

[permalink] [raw]
Subject: Re: [PATCH 04/22] ide-floppy: add ide_floppy_set_media_lock() helper

Hello.

Bartlomiej Zolnierkiewicz wrote:

> Add ide_floppy_set_media_lock() helper and convert idefloppy_open(),
> idefloppy_release() and ide_floppy_lockdoor() to use it.
>
> There should be no functional changes caused by this patch.
>
> Cc: Borislav Petkov <[email protected]>
> Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>

Acked-by: Sergei Shtylyov <[email protected]>

MBR, Sergei

2008-08-23 21:31:20

by Sergei Shtylyov

[permalink] [raw]
Subject: Re: [PATCH 13/22] ide: add ide_do_test_unit_ready() helper

Bartlomiej Zolnierkiewicz wrote:

> * Add ide_do_test_unit_ready() helper and convert ide-{floppy,tape}.c
> to use it.
>
> * Remove no longer used idetape_create_test_unit_ready_cmd().
>
> There should be no functional changes caused by this patch.
>
> Cc: Borislav Petkov <[email protected]>
> Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>

Acked-by: Sergei Shtylyov <[email protected]>

MBR, Sergei

2008-08-23 21:57:32

by Sergei Shtylyov

[permalink] [raw]
Subject: Re: [PATCH 07/22] ide: add ide_queue_pc_head() helper

Bartlomiej Zolnierkiewicz wrote:

> * Move REQ_IDETAPE_* enums to <linux/ide.h>.
>
> * Add ide_queue_pc_head() and convert ide-{floppy,tape}.c to use it
> instead of ide*_queue_pc_head().
>
> * Remove no longer used ide*_queue_pc_head().
>
> There should be no functional changes caused by this patch.
>
> Cc: Borislav Petkov <[email protected]>
> Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
>

Acked-by: Sergei Shtylyov <[email protected]>

MBR, Sergei

2008-08-23 21:58:43

by Sergei Shtylyov

[permalink] [raw]
Subject: Re: [PATCH 08/22] ide: add ide_queue_pc_tail() helper

Bartlomiej Zolnierkiewicz wrote:

> * Add ide_queue_pc_tail() and convert ide-{floppy,tape}.c to use it
> instead of ide*_queue_pc_tail().
>
> * Remove no longer used ide*_queue_pc_tail().
>
> There should be no functional changes caused by this patch.
>
> Cc: Borislav Petkov <[email protected]>
> Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>

Acked-by: Sergei Shtylyov <[email protected]>

MBR, Sergei