Commit c7c39840 authored by Martin Dalecki's avatar Martin Dalecki Committed by Linus Torvalds

[PATCH] 2.5.16 IDE 68

 - Make the different ATAPI device type drivers use a unified packet command
   structure. We have to start to push them together.

This patch is rather trivial in itself, but the plentora of code duplication it
is trying to fight against is making it unfortunately rather big...
parent 14cfb6a6
...@@ -130,6 +130,13 @@ if [ "$CONFIG_BLK_DEV_IDE" != "n" ]; then ...@@ -130,6 +130,13 @@ if [ "$CONFIG_BLK_DEV_IDE" != "n" ]; then
"$CONFIG_BLK_DEV_IDEDMA_ICS" = "y" ]; then "$CONFIG_BLK_DEV_IDEDMA_ICS" = "y" ]; then
bool ' IGNORE word93 Validation BITS' CONFIG_IDEDMA_IVB bool ' IGNORE word93 Validation BITS' CONFIG_IDEDMA_IVB
fi fi
if [ "$CONFIG_BLK_DEV_IDECD" != "n" -o \
"$CONFIG_BLK_DEV_IDETAPE" != "n" -o \
"$CONFIG_BLK_DEV_IDEFLOPPY" != "n" -o \
"$CONFIG_BLK_DEV_IDESCSI" != "n" ]; then
define_bool CONFIG_ATAPI y
fi
else else
bool 'Old hard disk (MFM/RLL/IDE) driver' CONFIG_BLK_DEV_HD_ONLY bool 'Old hard disk (MFM/RLL/IDE) driver' CONFIG_BLK_DEV_HD_ONLY
define_bool CONFIG_BLK_DEV_HD $CONFIG_BLK_DEV_HD_ONLY define_bool CONFIG_BLK_DEV_HD $CONFIG_BLK_DEV_HD_ONLY
......
...@@ -10,7 +10,8 @@ ...@@ -10,7 +10,8 @@
O_TARGET := idedriver.o O_TARGET := idedriver.o
export-objs := ide-taskfile.o ide.o ide-features.o ide-probe.o quirks.o pcidma.o tcq.o ataraid.o export-objs := ide-taskfile.o ide.o ide-features.o ide-probe.o quirks.o pcidma.o tcq.o \
atapi.o ataraid.o
obj-y := obj-y :=
obj-m := obj-m :=
...@@ -20,6 +21,7 @@ obj-$(CONFIG_BLK_DEV_HD) += hd.o ...@@ -20,6 +21,7 @@ obj-$(CONFIG_BLK_DEV_HD) += hd.o
obj-$(CONFIG_BLK_DEV_IDE) += ide-mod.o obj-$(CONFIG_BLK_DEV_IDE) += ide-mod.o
obj-$(CONFIG_BLK_DEV_IDECS) += ide-cs.o obj-$(CONFIG_BLK_DEV_IDECS) += ide-cs.o
obj-$(CONFIG_BLK_DEV_IDEDISK) += ide-disk.o obj-$(CONFIG_BLK_DEV_IDEDISK) += ide-disk.o
obj-$(CONFIG_ATAPI) += atapi.o
obj-$(CONFIG_BLK_DEV_IDECD) += ide-cd.o obj-$(CONFIG_BLK_DEV_IDECD) += ide-cd.o
obj-$(CONFIG_BLK_DEV_IDETAPE) += ide-tape.o obj-$(CONFIG_BLK_DEV_IDETAPE) += ide-tape.o
obj-$(CONFIG_BLK_DEV_IDEFLOPPY) += ide-floppy.o obj-$(CONFIG_BLK_DEV_IDEFLOPPY) += ide-floppy.o
......
/**** vi:set ts=8 sts=8 sw=8:************************************************
*
* Copyright (C) 2002 Marcin Dalecki <martin@dalecki.de>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*/
/*
* Code common among all the ATAPI device drivers.
*
* Ideally this should evolve in to a unified driver.
*/
#include <linux/module.h>
#include <linux/types.h>
#include <linux/string.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/ioport.h>
#include <linux/blkdev.h>
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/cdrom.h>
#include <linux/hdreg.h>
#include <linux/ide.h>
#include <linux/atapi.h>
#include <asm/byteorder.h>
#include <asm/io.h>
#include <asm/bitops.h>
#include <asm/uaccess.h>
/*
* Too bad. The drive wants to send us data which we are not ready to accept.
* Just throw it away.
*/
void atapi_discard_data(struct ata_device *drive, unsigned int bcount)
{
while (bcount--)
IN_BYTE(IDE_DATA_REG);
}
void atapi_write_zeros(struct ata_device *drive, unsigned int bcount)
{
while (bcount--)
OUT_BYTE(0, IDE_DATA_REG);
}
/*
* Initializes a packet command. Used by tape and floppy driver.
*/
void atapi_init_pc(struct atapi_packet_command *pc)
{
memset(pc->c, 0, 12);
pc->retries = 0;
pc->flags = 0;
pc->request_transfer = 0;
pc->buffer = pc->pc_buffer;
pc->buffer_size = IDEFLOPPY_PC_BUFFER_SIZE;
pc->b_data = NULL;
pc->bio = NULL;
}
EXPORT_SYMBOL(atapi_discard_data);
EXPORT_SYMBOL(atapi_write_zeros);
EXPORT_SYMBOL(atapi_init_pc);
MODULE_LICENSE("GPL");
...@@ -97,6 +97,7 @@ ...@@ -97,6 +97,7 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/cdrom.h> #include <linux/cdrom.h>
#include <linux/ide.h> #include <linux/ide.h>
#include <linux/atapi.h>
#include <asm/byteorder.h> #include <asm/byteorder.h>
#include <asm/irq.h> #include <asm/irq.h>
...@@ -127,12 +128,6 @@ ...@@ -127,12 +128,6 @@
*/ */
#define IDEFLOPPY_MAX_PC_RETRIES 3 #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
/* /*
* In various places in the driver, we need to allocate storage * In various places in the driver, we need to allocate storage
* for packet commands and requests, which will remain valid while * for packet commands and requests, which will remain valid while
...@@ -140,25 +135,6 @@ ...@@ -140,25 +135,6 @@
*/ */
#define IDEFLOPPY_PC_STACK (10 + IDEFLOPPY_MAX_PC_RETRIES) #define IDEFLOPPY_PC_STACK (10 + IDEFLOPPY_MAX_PC_RETRIES)
/*
* Our view of a packet command.
*/
typedef struct idefloppy_packet_command_s {
u8 c[12]; /* Actual packet bytes */
int retries; /* On each retry, we increment retries */
int error; /* Error code */
int request_transfer; /* Bytes to transfer */
int actually_transferred; /* Bytes actually transferred */
int buffer_size; /* Size of our data buffer */
char *b_data; /* Pointer which runs on the buffers */
int b_count; /* Missing/Available data on the current buffer */
byte *buffer; /* Data buffer */
byte *current_position; /* Pointer into the above buffer */
void (*callback) (struct ata_device *, struct request *); /* Called when this packet command is completed */
byte pc_buffer[IDEFLOPPY_PC_BUFFER_SIZE]; /* Temporary buffer */
unsigned long flags; /* Status/Action bit flags: long for set_bit */
} idefloppy_pc_t;
/* /*
* Packet command flag bits. * Packet command flag bits.
*/ */
...@@ -269,11 +245,11 @@ typedef struct { ...@@ -269,11 +245,11 @@ typedef struct {
* of type idefloppy_floppy_t, defined below. * of type idefloppy_floppy_t, defined below.
*/ */
typedef struct { typedef struct {
ide_drive_t *drive; struct ata_device *drive;
idefloppy_pc_t *pc; /* Current packet command */ struct atapi_packet_command *pc; /* Current packet command */
idefloppy_pc_t *failed_pc; /* Last failed packet command */ struct atapi_packet_command *failed_pc; /* Last failed packet command */
idefloppy_pc_t pc_stack[IDEFLOPPY_PC_STACK];/* Packet command stack */ struct atapi_packet_command pc_stack[IDEFLOPPY_PC_STACK]; /* Packet command stack */
int pc_stack_index; /* Next free packet command storage space */ int pc_stack_index; /* Next free packet command storage space */
struct request rq_stack[IDEFLOPPY_PC_STACK]; struct request rq_stack[IDEFLOPPY_PC_STACK];
int rq_stack_index; /* We implement a circular array */ int rq_stack_index; /* We implement a circular array */
...@@ -644,24 +620,6 @@ typedef struct { ...@@ -644,24 +620,6 @@ typedef struct {
#define IDEFLOPPY_MIN(a,b) ((a)<(b) ? (a):(b)) #define IDEFLOPPY_MIN(a,b) ((a)<(b) ? (a):(b))
#define IDEFLOPPY_MAX(a,b) ((a)>(b) ? (a):(b)) #define IDEFLOPPY_MAX(a,b) ((a)>(b) ? (a):(b))
/*
* Too bad. The drive wants to send us data which we are not ready to accept.
* Just throw it away.
*/
static void idefloppy_discard_data (ide_drive_t *drive, unsigned int bcount)
{
while (bcount--)
IN_BYTE (IDE_DATA_REG);
}
#if IDEFLOPPY_DEBUG_BUGS
static void idefloppy_write_zeros (ide_drive_t *drive, unsigned int bcount)
{
while (bcount--)
OUT_BYTE (0, IDE_DATA_REG);
}
#endif /* IDEFLOPPY_DEBUG_BUGS */
/* /*
* idefloppy_end_request is used to finish servicing a request. * idefloppy_end_request is used to finish servicing a request.
* *
...@@ -698,7 +656,7 @@ static int idefloppy_end_request(struct ata_device *drive, struct request *rq, i ...@@ -698,7 +656,7 @@ static int idefloppy_end_request(struct ata_device *drive, struct request *rq, i
} }
static void idefloppy_input_buffers(struct ata_device *drive, struct request *rq, static void idefloppy_input_buffers(struct ata_device *drive, struct request *rq,
idefloppy_pc_t *pc, unsigned int bcount) struct atapi_packet_command *pc, unsigned int bcount)
{ {
struct bio *bio = rq->bio; struct bio *bio = rq->bio;
int count; int count;
...@@ -713,17 +671,17 @@ static void idefloppy_input_buffers(struct ata_device *drive, struct request *rq ...@@ -713,17 +671,17 @@ static void idefloppy_input_buffers(struct ata_device *drive, struct request *rq
} }
if (bio == NULL) { if (bio == NULL) {
printk (KERN_ERR "%s: bio == NULL in %s, bcount == %d\n", drive->name, __FUNCTION__, bcount); printk (KERN_ERR "%s: bio == NULL in %s, bcount == %d\n", drive->name, __FUNCTION__, bcount);
idefloppy_discard_data (drive, bcount); atapi_discard_data(drive, bcount);
return; return;
} }
count = IDEFLOPPY_MIN (bio->bi_size - pc->b_count, bcount); count = IDEFLOPPY_MIN(bio->bi_size - pc->b_count, bcount);
atapi_read(drive, bio_data(bio) + pc->b_count, count); atapi_read(drive, bio_data(bio) + pc->b_count, count);
bcount -= count; pc->b_count += count; bcount -= count; pc->b_count += count;
} }
} }
static void idefloppy_output_buffers(struct ata_device *drive, struct request *rq, static void idefloppy_output_buffers(struct ata_device *drive, struct request *rq,
idefloppy_pc_t *pc, unsigned int bcount) struct atapi_packet_command *pc, unsigned int bcount)
{ {
struct bio *bio = rq->bio; struct bio *bio = rq->bio;
int count; int count;
...@@ -740,40 +698,41 @@ static void idefloppy_output_buffers(struct ata_device *drive, struct request *r ...@@ -740,40 +698,41 @@ static void idefloppy_output_buffers(struct ata_device *drive, struct request *r
} }
if (bio == NULL) { if (bio == NULL) {
printk (KERN_ERR "%s: bio == NULL in idefloppy_output_buffers, bcount == %d\n", drive->name, bcount); printk (KERN_ERR "%s: bio == NULL in idefloppy_output_buffers, bcount == %d\n", drive->name, bcount);
idefloppy_write_zeros (drive, bcount); atapi_write_zeros (drive, bcount);
return; return;
} }
count = IDEFLOPPY_MIN (pc->b_count, bcount); count = IDEFLOPPY_MIN(pc->b_count, bcount);
atapi_write(drive, pc->b_data, count); atapi_write(drive, pc->b_data, count);
bcount -= count; pc->b_data += count; pc->b_count -= count; bcount -= count; pc->b_data += count; pc->b_count -= count;
} }
} }
#ifdef CONFIG_BLK_DEV_IDEDMA #ifdef CONFIG_BLK_DEV_IDEDMA
static void idefloppy_update_buffers (struct ata_device *drive, struct request *rq, static void idefloppy_update_buffers(struct ata_device *drive, struct request *rq)
idefloppy_pc_t *pc)
{ {
struct bio *bio = rq->bio; struct bio *bio = rq->bio;
while ((bio = rq->bio) != NULL) while ((bio = rq->bio) != NULL)
idefloppy_end_request(drive, rq, 1); idefloppy_end_request(drive, rq, 1);
} }
#endif /* CONFIG_BLK_DEV_IDEDMA */ #endif
/* /*
* idefloppy_queue_pc_head generates a new packet command request in front * idefloppy_queue_pc_head generates a new packet command request in front
* of the request queue, before the current request, so that it will be * of the request queue, before the current request, so that it will be
* processed immediately, on the next pass through the driver. * processed immediately, on the next pass through the driver.
*/ */
static void idefloppy_queue_pc_head (ide_drive_t *drive,idefloppy_pc_t *pc,struct request *rq) static void idefloppy_queue_pc_head(struct ata_device *drive,
struct atapi_packet_command *pc, struct request *rq)
{ {
ide_init_drive_cmd (rq); ide_init_drive_cmd (rq);
/* FIXME: --mdcki */
rq->buffer = (char *) pc; rq->buffer = (char *) pc;
rq->flags = IDEFLOPPY_RQ; rq->flags = IDEFLOPPY_RQ;
(void) ide_do_drive_cmd (drive, rq, ide_preempt); (void) ide_do_drive_cmd (drive, rq, ide_preempt);
} }
static idefloppy_pc_t *idefloppy_next_pc_storage (ide_drive_t *drive) static struct atapi_packet_command *idefloppy_next_pc_storage(struct ata_device *drive)
{ {
idefloppy_floppy_t *floppy = drive->driver_data; idefloppy_floppy_t *floppy = drive->driver_data;
...@@ -782,7 +741,7 @@ static idefloppy_pc_t *idefloppy_next_pc_storage (ide_drive_t *drive) ...@@ -782,7 +741,7 @@ static idefloppy_pc_t *idefloppy_next_pc_storage (ide_drive_t *drive)
return (&floppy->pc_stack[floppy->pc_stack_index++]); return (&floppy->pc_stack[floppy->pc_stack_index++]);
} }
static struct request *idefloppy_next_rq_storage (ide_drive_t *drive) static struct request *idefloppy_next_rq_storage(struct ata_device *drive)
{ {
idefloppy_floppy_t *floppy = drive->driver_data; idefloppy_floppy_t *floppy = drive->driver_data;
...@@ -795,7 +754,7 @@ static struct request *idefloppy_next_rq_storage (ide_drive_t *drive) ...@@ -795,7 +754,7 @@ static struct request *idefloppy_next_rq_storage (ide_drive_t *drive)
* idefloppy_analyze_error is called on each failed packet command retry * idefloppy_analyze_error is called on each failed packet command retry
* to analyze the request sense. * to analyze the request sense.
*/ */
static void idefloppy_analyze_error (ide_drive_t *drive,idefloppy_request_sense_result_t *result) static void idefloppy_analyze_error(struct ata_device *drive, idefloppy_request_sense_result_t *result)
{ {
idefloppy_floppy_t *floppy = drive->driver_data; idefloppy_floppy_t *floppy = drive->driver_data;
...@@ -807,7 +766,7 @@ static void idefloppy_analyze_error (ide_drive_t *drive,idefloppy_request_sense_ ...@@ -807,7 +766,7 @@ static void idefloppy_analyze_error (ide_drive_t *drive,idefloppy_request_sense_
printk (KERN_INFO "ide-floppy: pc = %x, sense key = %x, asc = %x, ascq = %x\n",floppy->failed_pc->c[0],result->sense_key,result->asc,result->ascq); printk (KERN_INFO "ide-floppy: pc = %x, sense key = %x, asc = %x, ascq = %x\n",floppy->failed_pc->c[0],result->sense_key,result->asc,result->ascq);
else else
printk (KERN_INFO "ide-floppy: sense key = %x, asc = %x, ascq = %x\n",result->sense_key,result->asc,result->ascq); printk (KERN_INFO "ide-floppy: sense key = %x, asc = %x, ascq = %x\n",result->sense_key,result->asc,result->ascq);
#endif /* IDEFLOPPY_DEBUG_LOG */ #endif
} }
static void idefloppy_request_sense_callback(struct ata_device *drive, struct request *rq) static void idefloppy_request_sense_callback(struct ata_device *drive, struct request *rq)
...@@ -816,9 +775,9 @@ static void idefloppy_request_sense_callback(struct ata_device *drive, struct re ...@@ -816,9 +775,9 @@ static void idefloppy_request_sense_callback(struct ata_device *drive, struct re
#if IDEFLOPPY_DEBUG_LOG #if IDEFLOPPY_DEBUG_LOG
printk (KERN_INFO "ide-floppy: Reached idefloppy_request_sense_callback\n"); printk (KERN_INFO "ide-floppy: Reached idefloppy_request_sense_callback\n");
#endif /* IDEFLOPPY_DEBUG_LOG */ #endif
if (!floppy->pc->error) { if (!floppy->pc->error) {
idefloppy_analyze_error (drive,(idefloppy_request_sense_result_t *) floppy->pc->buffer); idefloppy_analyze_error(drive,(idefloppy_request_sense_result_t *) floppy->pc->buffer);
idefloppy_end_request(drive, rq, 1); idefloppy_end_request(drive, rq, 1);
} else { } else {
printk (KERN_ERR "Error in REQUEST SENSE itself - Aborting request!\n"); printk (KERN_ERR "Error in REQUEST SENSE itself - Aborting request!\n");
...@@ -835,29 +794,14 @@ static void idefloppy_pc_callback(struct ata_device *drive, struct request *rq) ...@@ -835,29 +794,14 @@ static void idefloppy_pc_callback(struct ata_device *drive, struct request *rq)
#if IDEFLOPPY_DEBUG_LOG #if IDEFLOPPY_DEBUG_LOG
printk (KERN_INFO "ide-floppy: Reached idefloppy_pc_callback\n"); printk (KERN_INFO "ide-floppy: Reached idefloppy_pc_callback\n");
#endif /* IDEFLOPPY_DEBUG_LOG */ #endif
idefloppy_end_request(drive, rq, floppy->pc->error ? 0:1); idefloppy_end_request(drive, rq, floppy->pc->error ? 0:1);
} }
/* static void idefloppy_create_request_sense_cmd(struct atapi_packet_command *pc)
* idefloppy_init_pc initializes a packet command.
*/
static void idefloppy_init_pc (idefloppy_pc_t *pc)
{
memset (pc->c, 0, 12);
pc->retries = 0;
pc->flags = 0;
pc->request_transfer = 0;
pc->buffer = pc->pc_buffer;
pc->buffer_size = IDEFLOPPY_PC_BUFFER_SIZE;
pc->b_data = NULL;
pc->callback = idefloppy_pc_callback;
}
static void idefloppy_create_request_sense_cmd (idefloppy_pc_t *pc)
{ {
idefloppy_init_pc (pc); atapi_init_pc(pc);
pc->c[0] = IDEFLOPPY_REQUEST_SENSE_CMD; pc->c[0] = IDEFLOPPY_REQUEST_SENSE_CMD;
pc->c[4] = 255; pc->c[4] = 255;
pc->request_transfer = 18; pc->request_transfer = 18;
...@@ -869,16 +813,16 @@ static void idefloppy_create_request_sense_cmd (idefloppy_pc_t *pc) ...@@ -869,16 +813,16 @@ static void idefloppy_create_request_sense_cmd (idefloppy_pc_t *pc)
* last packet command. We queue a request sense packet command in * last packet command. We queue a request sense packet command in
* the head of the request list. * the head of the request list.
*/ */
static void idefloppy_retry_pc (ide_drive_t *drive) static void idefloppy_retry_pc(struct ata_device *drive)
{ {
idefloppy_pc_t *pc; struct atapi_packet_command *pc;
struct request *rq; struct request *rq;
idefloppy_error_reg_t error; idefloppy_error_reg_t error;
error.all = IN_BYTE (IDE_ERROR_REG); error.all = IN_BYTE(IDE_ERROR_REG);
pc = idefloppy_next_pc_storage (drive); pc = idefloppy_next_pc_storage(drive);
rq = idefloppy_next_rq_storage (drive); rq = idefloppy_next_rq_storage(drive);
idefloppy_create_request_sense_cmd (pc); idefloppy_create_request_sense_cmd(pc);
idefloppy_queue_pc_head(drive, pc, rq); idefloppy_queue_pc_head(drive, pc, rq);
} }
...@@ -892,7 +836,7 @@ static ide_startstop_t idefloppy_pc_intr(struct ata_device *drive, struct reques ...@@ -892,7 +836,7 @@ static ide_startstop_t idefloppy_pc_intr(struct ata_device *drive, struct reques
idefloppy_status_reg_t status; idefloppy_status_reg_t status;
idefloppy_bcount_reg_t bcount; idefloppy_bcount_reg_t bcount;
idefloppy_ireason_reg_t ireason; idefloppy_ireason_reg_t ireason;
idefloppy_pc_t *pc=floppy->pc; struct atapi_packet_command *pc = floppy->pc;
unsigned int temp; unsigned int temp;
#if IDEFLOPPY_DEBUG_LOG #if IDEFLOPPY_DEBUG_LOG
...@@ -905,7 +849,7 @@ static ide_startstop_t idefloppy_pc_intr(struct ata_device *drive, struct reques ...@@ -905,7 +849,7 @@ static ide_startstop_t idefloppy_pc_intr(struct ata_device *drive, struct reques
set_bit (PC_DMA_ERROR, &pc->flags); set_bit (PC_DMA_ERROR, &pc->flags);
} else { } else {
pc->actually_transferred=pc->request_transfer; pc->actually_transferred=pc->request_transfer;
idefloppy_update_buffers(drive, rq, pc); idefloppy_update_buffers(drive, rq);
} }
# if IDEFLOPPY_DEBUG_LOG # if IDEFLOPPY_DEBUG_LOG
printk (KERN_INFO "ide-floppy: DMA finished\n"); printk (KERN_INFO "ide-floppy: DMA finished\n");
...@@ -923,10 +867,10 @@ static ide_startstop_t idefloppy_pc_intr(struct ata_device *drive, struct reques ...@@ -923,10 +867,10 @@ static ide_startstop_t idefloppy_pc_intr(struct ata_device *drive, struct reques
ide__sti(); /* local CPU only */ ide__sti(); /* local CPU only */
if (status.b.check || test_bit (PC_DMA_ERROR, &pc->flags)) { /* Error detected */ if (status.b.check || test_bit(PC_DMA_ERROR, &pc->flags)) { /* Error detected */
#if IDEFLOPPY_DEBUG_LOG #if IDEFLOPPY_DEBUG_LOG
printk (KERN_INFO "ide-floppy: %s: I/O error\n",drive->name); printk (KERN_INFO "ide-floppy: %s: I/O error\n",drive->name);
#endif /* IDEFLOPPY_DEBUG_LOG */ #endif
rq->errors++; rq->errors++;
if (pc->c[0] == IDEFLOPPY_REQUEST_SENSE_CMD) { if (pc->c[0] == IDEFLOPPY_REQUEST_SENSE_CMD) {
printk (KERN_ERR "ide-floppy: I/O error in request sense command\n"); printk (KERN_ERR "ide-floppy: I/O error in request sense command\n");
...@@ -942,7 +886,7 @@ static ide_startstop_t idefloppy_pc_intr(struct ata_device *drive, struct reques ...@@ -942,7 +886,7 @@ static ide_startstop_t idefloppy_pc_intr(struct ata_device *drive, struct reques
return ide_stopped; return ide_stopped;
} }
#ifdef CONFIG_BLK_DEV_IDEDMA #ifdef CONFIG_BLK_DEV_IDEDMA
if (test_and_clear_bit (PC_DMA_IN_PROGRESS, &pc->flags)) { if (test_and_clear_bit(PC_DMA_IN_PROGRESS, &pc->flags)) {
printk (KERN_ERR "ide-floppy: The floppy wants to issue more interrupts in DMA mode\n"); printk (KERN_ERR "ide-floppy: The floppy wants to issue more interrupts in DMA mode\n");
udma_enable(drive, 0, 1); udma_enable(drive, 0, 1);
...@@ -957,23 +901,23 @@ static ide_startstop_t idefloppy_pc_intr(struct ata_device *drive, struct reques ...@@ -957,23 +901,23 @@ static ide_startstop_t idefloppy_pc_intr(struct ata_device *drive, struct reques
printk (KERN_ERR "ide-floppy: CoD != 0 in idefloppy_pc_intr\n"); printk (KERN_ERR "ide-floppy: CoD != 0 in idefloppy_pc_intr\n");
return ide_stopped; return ide_stopped;
} }
if (ireason.b.io == test_bit (PC_WRITING, &pc->flags)) { /* Hopefully, we will never get here */ if (ireason.b.io == test_bit(PC_WRITING, &pc->flags)) { /* Hopefully, we will never get here */
printk (KERN_ERR "ide-floppy: We wanted to %s, ", ireason.b.io ? "Write":"Read"); printk (KERN_ERR "ide-floppy: We wanted to %s, ", ireason.b.io ? "Write":"Read");
printk (KERN_ERR "but the floppy wants us to %s !\n",ireason.b.io ? "Read":"Write"); printk (KERN_ERR "but the floppy wants us to %s !\n",ireason.b.io ? "Read":"Write");
return ide_stopped; return ide_stopped;
} }
if (!test_bit (PC_WRITING, &pc->flags)) { /* Reading - Check that we have enough space */ if (!test_bit(PC_WRITING, &pc->flags)) { /* Reading - Check that we have enough space */
temp = pc->actually_transferred + bcount.all; temp = pc->actually_transferred + bcount.all;
if ( temp > pc->request_transfer) { if ( temp > pc->request_transfer) {
if (temp > pc->buffer_size) { if (temp > pc->buffer_size) {
printk (KERN_ERR "ide-floppy: The floppy wants to send us more data than expected - discarding data\n"); printk (KERN_ERR "ide-floppy: The floppy wants to send us more data than expected - discarding data\n");
idefloppy_discard_data (drive,bcount.all); atapi_discard_data (drive,bcount.all);
ide_set_handler(drive, idefloppy_pc_intr,IDEFLOPPY_WAIT_CMD, NULL); ide_set_handler(drive, idefloppy_pc_intr,IDEFLOPPY_WAIT_CMD, NULL);
return ide_started; return ide_started;
} }
#if IDEFLOPPY_DEBUG_LOG #if IDEFLOPPY_DEBUG_LOG
printk (KERN_NOTICE "ide-floppy: The floppy wants to send us more data than expected - allowing transfer\n"); printk (KERN_NOTICE "ide-floppy: The floppy wants to send us more data than expected - allowing transfer\n");
#endif /* IDEFLOPPY_DEBUG_LOG */ #endif
} }
} }
if (test_bit (PC_WRITING, &pc->flags)) { if (test_bit (PC_WRITING, &pc->flags)) {
...@@ -1076,7 +1020,8 @@ static ide_startstop_t idefloppy_transfer_pc1(struct ata_device *drive, struct r ...@@ -1076,7 +1020,8 @@ static ide_startstop_t idefloppy_transfer_pc1(struct ata_device *drive, struct r
/* /*
* Issue a packet command * Issue a packet command
*/ */
static ide_startstop_t idefloppy_issue_pc(struct ata_device *drive, struct request *rq, idefloppy_pc_t *pc) static ide_startstop_t idefloppy_issue_pc(struct ata_device *drive, struct request *rq,
struct atapi_packet_command *pc)
{ {
idefloppy_floppy_t *floppy = drive->driver_data; idefloppy_floppy_t *floppy = drive->driver_data;
idefloppy_bcount_reg_t bcount; idefloppy_bcount_reg_t bcount;
...@@ -1085,28 +1030,28 @@ static ide_startstop_t idefloppy_issue_pc(struct ata_device *drive, struct reque ...@@ -1085,28 +1030,28 @@ static ide_startstop_t idefloppy_issue_pc(struct ata_device *drive, struct reque
#if IDEFLOPPY_DEBUG_BUGS #if IDEFLOPPY_DEBUG_BUGS
if (floppy->pc->c[0] == IDEFLOPPY_REQUEST_SENSE_CMD && pc->c[0] == IDEFLOPPY_REQUEST_SENSE_CMD) { if (floppy->pc->c[0] == IDEFLOPPY_REQUEST_SENSE_CMD && pc->c[0] == IDEFLOPPY_REQUEST_SENSE_CMD) {
printk (KERN_ERR "ide-floppy: possible ide-floppy.c bug - Two request sense in serial were issued\n"); printk(KERN_ERR "ide-floppy: possible ide-floppy.c bug - Two request sense in serial were issued\n");
} }
#endif /* IDEFLOPPY_DEBUG_BUGS */ #endif
if (floppy->failed_pc == NULL && pc->c[0] != IDEFLOPPY_REQUEST_SENSE_CMD) if (floppy->failed_pc == NULL && pc->c[0] != IDEFLOPPY_REQUEST_SENSE_CMD)
floppy->failed_pc=pc; floppy->failed_pc=pc;
floppy->pc=pc; /* Set the current packet command */ floppy->pc=pc; /* Set the current packet command */
if (pc->retries > IDEFLOPPY_MAX_PC_RETRIES || test_bit (PC_ABORT, &pc->flags)) { if (pc->retries > IDEFLOPPY_MAX_PC_RETRIES || test_bit(PC_ABORT, &pc->flags)) {
/* /*
* We will "abort" retrying a packet command in case * We will "abort" retrying a packet command in case
* a legitimate error code was received. * a legitimate error code was received.
*/ */
if (!test_bit (PC_ABORT, &pc->flags)) { if (!test_bit(PC_ABORT, &pc->flags)) {
if (!test_bit (PC_SUPPRESS_ERROR, &pc->flags)) { if (!test_bit(PC_SUPPRESS_ERROR, &pc->flags)) {
; ;
printk( KERN_ERR "ide-floppy: %s: I/O error, pc = %2x, key = %2x, asc = %2x, ascq = %2x\n", printk( KERN_ERR "ide-floppy: %s: I/O error, pc = %2x, key = %2x, asc = %2x, ascq = %2x\n",
drive->name, pc->c[0], floppy->sense_key, floppy->asc, floppy->ascq); drive->name, pc->c[0], floppy->sense_key, floppy->asc, floppy->ascq);
} }
pc->error = IDEFLOPPY_ERROR_GENERAL; /* Giving up */ pc->error = IDEFLOPPY_ERROR_GENERAL; /* Giving up */
} }
floppy->failed_pc=NULL; floppy->failed_pc = NULL;
pc->callback(drive, rq); pc->callback(drive, rq);
return ide_stopped; return ide_stopped;
} }
...@@ -1129,7 +1074,7 @@ static ide_startstop_t idefloppy_issue_pc(struct ata_device *drive, struct reque ...@@ -1129,7 +1074,7 @@ static ide_startstop_t idefloppy_issue_pc(struct ata_device *drive, struct reque
else else
dma_ok = !udma_read(drive, rq); dma_ok = !udma_read(drive, rq);
} }
#endif /* CONFIG_BLK_DEV_IDEDMA */ #endif
if (IDE_CONTROL_REG) if (IDE_CONTROL_REG)
OUT_BYTE (drive->ctl,IDE_CONTROL_REG); OUT_BYTE (drive->ctl,IDE_CONTROL_REG);
...@@ -1140,10 +1085,10 @@ static ide_startstop_t idefloppy_issue_pc(struct ata_device *drive, struct reque ...@@ -1140,10 +1085,10 @@ static ide_startstop_t idefloppy_issue_pc(struct ata_device *drive, struct reque
#ifdef CONFIG_BLK_DEV_IDEDMA #ifdef CONFIG_BLK_DEV_IDEDMA
if (dma_ok) { /* Begin DMA, if necessary */ if (dma_ok) { /* Begin DMA, if necessary */
set_bit (PC_DMA_IN_PROGRESS, &pc->flags); set_bit(PC_DMA_IN_PROGRESS, &pc->flags);
udma_start(drive, rq); udma_start(drive, rq);
} }
#endif /* CONFIG_BLK_DEV_IDEDMA */ #endif
/* Can we transfer the packet when we get the interrupt or wait? */ /* Can we transfer the packet when we get the interrupt or wait? */
if (test_bit (IDEFLOPPY_ZIP_DRIVE, &floppy->flags)) { if (test_bit (IDEFLOPPY_ZIP_DRIVE, &floppy->flags)) {
...@@ -1172,30 +1117,32 @@ static void idefloppy_rw_callback(struct ata_device *drive, struct request *rq) ...@@ -1172,30 +1117,32 @@ static void idefloppy_rw_callback(struct ata_device *drive, struct request *rq)
return; return;
} }
static void idefloppy_create_prevent_cmd (idefloppy_pc_t *pc, int prevent) static void idefloppy_create_prevent_cmd(struct atapi_packet_command *pc, int prevent)
{ {
#if IDEFLOPPY_DEBUG_LOG #if IDEFLOPPY_DEBUG_LOG
printk (KERN_INFO "ide-floppy: creating prevent removal command, prevent = %d\n", prevent); printk (KERN_INFO "ide-floppy: creating prevent removal command, prevent = %d\n", prevent);
#endif /* IDEFLOPPY_DEBUG_LOG */ #endif
idefloppy_init_pc (pc); atapi_init_pc (pc);
pc->c[0] = IDEFLOPPY_PREVENT_REMOVAL_CMD; pc->c[0] = IDEFLOPPY_PREVENT_REMOVAL_CMD;
pc->c[4] = prevent; pc->c[4] = prevent;
pc->callback = idefloppy_pc_callback;
} }
static void idefloppy_create_read_capacity_cmd (idefloppy_pc_t *pc) static void idefloppy_create_read_capacity_cmd(struct atapi_packet_command *pc)
{ {
idefloppy_init_pc (pc); atapi_init_pc(pc);
pc->c[0] = IDEFLOPPY_READ_CAPACITY_CMD; pc->c[0] = IDEFLOPPY_READ_CAPACITY_CMD;
pc->c[7] = 255; pc->c[7] = 255;
pc->c[8] = 255; pc->c[8] = 255;
pc->request_transfer = 255; pc->request_transfer = 255;
pc->callback = idefloppy_pc_callback;
} }
static void idefloppy_create_format_unit_cmd (idefloppy_pc_t *pc, int b, int l, static void idefloppy_create_format_unit_cmd(struct atapi_packet_command *pc,
int flags) int b, int l, int flags)
{ {
idefloppy_init_pc (pc); atapi_init_pc (pc);
pc->c[0] = IDEFLOPPY_FORMAT_UNIT_CMD; pc->c[0] = IDEFLOPPY_FORMAT_UNIT_CMD;
pc->c[1] = 0x17; pc->c[1] = 0x17;
...@@ -1209,18 +1156,19 @@ static void idefloppy_create_format_unit_cmd (idefloppy_pc_t *pc, int b, int l, ...@@ -1209,18 +1156,19 @@ static void idefloppy_create_format_unit_cmd (idefloppy_pc_t *pc, int b, int l,
put_unaligned(htonl(b), (unsigned int *)(&pc->buffer[4])); put_unaligned(htonl(b), (unsigned int *)(&pc->buffer[4]));
put_unaligned(htonl(l), (unsigned int *)(&pc->buffer[8])); put_unaligned(htonl(l), (unsigned int *)(&pc->buffer[8]));
pc->buffer_size=12; pc->buffer_size = 12;
set_bit(PC_WRITING, &pc->flags); set_bit(PC_WRITING, &pc->flags);
pc->callback = idefloppy_pc_callback;
} }
/* /*
* A mode sense command is used to "sense" floppy parameters. * A mode sense command is used to "sense" floppy parameters.
*/ */
static void idefloppy_create_mode_sense_cmd (idefloppy_pc_t *pc, byte page_code, byte type) static void idefloppy_create_mode_sense_cmd(struct atapi_packet_command *pc, u8 page_code, u8 type)
{ {
unsigned short length = sizeof (idefloppy_mode_parameter_header_t); unsigned short length = sizeof(idefloppy_mode_parameter_header_t);
idefloppy_init_pc (pc); atapi_init_pc(pc);
pc->c[0] = IDEFLOPPY_MODE_SENSE_CMD; pc->c[0] = IDEFLOPPY_MODE_SENSE_CMD;
pc->c[1] = 0; pc->c[1] = 0;
pc->c[2] = page_code + (type << 6); pc->c[2] = page_code + (type << 6);
...@@ -1235,24 +1183,28 @@ static void idefloppy_create_mode_sense_cmd (idefloppy_pc_t *pc, byte page_code, ...@@ -1235,24 +1183,28 @@ static void idefloppy_create_mode_sense_cmd (idefloppy_pc_t *pc, byte page_code,
default: default:
printk (KERN_ERR "ide-floppy: unsupported page code in create_mode_sense_cmd\n"); printk (KERN_ERR "ide-floppy: unsupported page code in create_mode_sense_cmd\n");
} }
put_unaligned (htons (length), (unsigned short *) &pc->c[7]); put_unaligned(htons(length), (unsigned short *) &pc->c[7]);
pc->request_transfer = length; pc->request_transfer = length;
pc->callback = idefloppy_pc_callback;
} }
static void idefloppy_create_start_stop_cmd (idefloppy_pc_t *pc, int start) static void idefloppy_create_start_stop_cmd(struct atapi_packet_command *pc, int start)
{ {
idefloppy_init_pc (pc); atapi_init_pc(pc);
pc->c[0] = IDEFLOPPY_START_STOP_CMD; pc->c[0] = IDEFLOPPY_START_STOP_CMD;
pc->c[4] = start; pc->c[4] = start;
pc->callback = idefloppy_pc_callback;
} }
static void idefloppy_create_test_unit_ready_cmd(idefloppy_pc_t *pc) static void idefloppy_create_test_unit_ready_cmd(struct atapi_packet_command *pc)
{ {
idefloppy_init_pc(pc); atapi_init_pc(pc);
pc->c[0] = IDEFLOPPY_TEST_UNIT_READY_CMD; pc->c[0] = IDEFLOPPY_TEST_UNIT_READY_CMD;
pc->callback = idefloppy_pc_callback;
} }
static void idefloppy_create_rw_cmd(idefloppy_floppy_t *floppy, idefloppy_pc_t *pc, struct request *rq, sector_t sector) static void idefloppy_create_rw_cmd(idefloppy_floppy_t *floppy,
struct atapi_packet_command *pc, struct request *rq, sector_t sector)
{ {
int block = sector / floppy->bs_factor; int block = sector / floppy->bs_factor;
int blocks = rq->nr_sectors / floppy->bs_factor; int blocks = rq->nr_sectors / floppy->bs_factor;
...@@ -1261,25 +1213,25 @@ static void idefloppy_create_rw_cmd(idefloppy_floppy_t *floppy, idefloppy_pc_t * ...@@ -1261,25 +1213,25 @@ static void idefloppy_create_rw_cmd(idefloppy_floppy_t *floppy, idefloppy_pc_t *
#if IDEFLOPPY_DEBUG_LOG #if IDEFLOPPY_DEBUG_LOG
printk ("create_rw1%d_cmd: block == %d, blocks == %d\n", printk ("create_rw1%d_cmd: block == %d, blocks == %d\n",
2 * test_bit (IDEFLOPPY_USE_READ12, &floppy->flags), block, blocks); 2 * test_bit (IDEFLOPPY_USE_READ12, &floppy->flags), block, blocks);
#endif /* IDEFLOPPY_DEBUG_LOG */ #endif
idefloppy_init_pc(pc); atapi_init_pc(pc);
if (test_bit (IDEFLOPPY_USE_READ12, &floppy->flags)) { if (test_bit (IDEFLOPPY_USE_READ12, &floppy->flags)) {
pc->c[0] = cmd == READ ? IDEFLOPPY_READ12_CMD : IDEFLOPPY_WRITE12_CMD; pc->c[0] = cmd == READ ? IDEFLOPPY_READ12_CMD : IDEFLOPPY_WRITE12_CMD;
put_unaligned (htonl (blocks), (unsigned int *) &pc->c[6]); put_unaligned(htonl (blocks), (unsigned int *) &pc->c[6]);
} else { } else {
pc->c[0] = cmd == READ ? IDEFLOPPY_READ10_CMD : IDEFLOPPY_WRITE10_CMD; pc->c[0] = cmd == READ ? IDEFLOPPY_READ10_CMD : IDEFLOPPY_WRITE10_CMD;
put_unaligned (htons (blocks), (unsigned short *) &pc->c[7]); put_unaligned(htons (blocks), (unsigned short *) &pc->c[7]);
} }
put_unaligned (htonl (block), (unsigned int *) &pc->c[2]); put_unaligned(htonl(block), (unsigned int *) &pc->c[2]);
pc->callback = idefloppy_rw_callback; pc->callback = idefloppy_rw_callback;
pc->b_data = rq->buffer; pc->b_data = rq->buffer;
pc->b_count = cmd == READ ? 0 : rq->bio->bi_size; pc->b_count = cmd == READ ? 0 : rq->bio->bi_size;
if (rq->flags & REQ_RW) if (rq->flags & REQ_RW)
set_bit (PC_WRITING, &pc->flags); set_bit(PC_WRITING, &pc->flags);
pc->buffer = NULL; pc->buffer = NULL;
pc->request_transfer = pc->buffer_size = blocks * floppy->block_size; pc->request_transfer = pc->buffer_size = blocks * floppy->block_size;
set_bit (PC_DMA_RECOMMENDED, &pc->flags); set_bit(PC_DMA_RECOMMENDED, &pc->flags);
} }
/* /*
...@@ -1288,7 +1240,7 @@ static void idefloppy_create_rw_cmd(idefloppy_floppy_t *floppy, idefloppy_pc_t * ...@@ -1288,7 +1240,7 @@ static void idefloppy_create_rw_cmd(idefloppy_floppy_t *floppy, idefloppy_pc_t *
static ide_startstop_t idefloppy_do_request(struct ata_device *drive, struct request *rq, sector_t block) static ide_startstop_t idefloppy_do_request(struct ata_device *drive, struct request *rq, sector_t block)
{ {
idefloppy_floppy_t *floppy = drive->driver_data; idefloppy_floppy_t *floppy = drive->driver_data;
idefloppy_pc_t *pc; struct atapi_packet_command *pc;
#if IDEFLOPPY_DEBUG_LOG #if IDEFLOPPY_DEBUG_LOG
printk (KERN_INFO "rq_status: %d, rq_dev: %u, flags: %lx, errors: %d\n",rq->rq_status,(unsigned int) rq->rq_dev,rq->flags,rq->errors); printk (KERN_INFO "rq_status: %d, rq_dev: %u, flags: %lx, errors: %d\n",rq->rq_status,(unsigned int) rq->rq_dev,rq->flags,rq->errors);
...@@ -1313,7 +1265,8 @@ static ide_startstop_t idefloppy_do_request(struct ata_device *drive, struct req ...@@ -1313,7 +1265,8 @@ static ide_startstop_t idefloppy_do_request(struct ata_device *drive, struct req
pc = idefloppy_next_pc_storage(drive); pc = idefloppy_next_pc_storage(drive);
idefloppy_create_rw_cmd (floppy, pc, rq, block); idefloppy_create_rw_cmd (floppy, pc, rq, block);
} else if (rq->flags & IDEFLOPPY_RQ) { } else if (rq->flags & IDEFLOPPY_RQ) {
pc = (idefloppy_pc_t *) rq->buffer; /* FIXME: --mdcki */
pc = (struct atapi_packet_command *) rq->buffer;
} else { } else {
blk_dump_rq_flags(rq, "ide-floppy: unsupported command in queue"); blk_dump_rq_flags(rq, "ide-floppy: unsupported command in queue");
idefloppy_end_request(drive, rq, 0); idefloppy_end_request(drive, rq, 0);
...@@ -1327,11 +1280,12 @@ static ide_startstop_t idefloppy_do_request(struct ata_device *drive, struct req ...@@ -1327,11 +1280,12 @@ static ide_startstop_t idefloppy_do_request(struct ata_device *drive, struct req
* idefloppy_queue_pc_tail adds a special packet command request to the * idefloppy_queue_pc_tail adds a special packet command request to the
* tail of the request queue, and waits for it to be serviced. * tail of the request queue, and waits for it to be serviced.
*/ */
static int idefloppy_queue_pc_tail (ide_drive_t *drive,idefloppy_pc_t *pc) static int idefloppy_queue_pc_tail(struct ata_device *drive, struct atapi_packet_command *pc)
{ {
struct request rq; struct request rq;
ide_init_drive_cmd (&rq); ide_init_drive_cmd (&rq);
/* FIXME: --mdcki */
rq.buffer = (char *) pc; rq.buffer = (char *) pc;
rq.flags = IDEFLOPPY_RQ; rq.flags = IDEFLOPPY_RQ;
return ide_do_drive_cmd (drive, &rq, ide_wait); return ide_do_drive_cmd (drive, &rq, ide_wait);
...@@ -1341,10 +1295,10 @@ static int idefloppy_queue_pc_tail (ide_drive_t *drive,idefloppy_pc_t *pc) ...@@ -1341,10 +1295,10 @@ static int idefloppy_queue_pc_tail (ide_drive_t *drive,idefloppy_pc_t *pc)
* Look at the flexible disk page parameters. We will ignore the CHS * Look at the flexible disk page parameters. We will ignore the CHS
* capacity parameters and use the LBA parameters instead. * capacity parameters and use the LBA parameters instead.
*/ */
static int idefloppy_get_flexible_disk_page (ide_drive_t *drive) static int idefloppy_get_flexible_disk_page(struct ata_device *drive)
{ {
idefloppy_floppy_t *floppy = drive->driver_data; idefloppy_floppy_t *floppy = drive->driver_data;
idefloppy_pc_t pc; struct atapi_packet_command pc;
idefloppy_mode_parameter_header_t *header; idefloppy_mode_parameter_header_t *header;
idefloppy_flexible_disk_page_t *page; idefloppy_flexible_disk_page_t *page;
int capacity, lba_capacity; int capacity, lba_capacity;
...@@ -1382,15 +1336,15 @@ static int idefloppy_get_flexible_disk_page (ide_drive_t *drive) ...@@ -1382,15 +1336,15 @@ static int idefloppy_get_flexible_disk_page (ide_drive_t *drive)
return 0; return 0;
} }
static int idefloppy_get_capability_page(ide_drive_t *drive) static int idefloppy_get_capability_page(struct ata_device *drive)
{ {
idefloppy_floppy_t *floppy = drive->driver_data; idefloppy_floppy_t *floppy = drive->driver_data;
idefloppy_pc_t pc; struct atapi_packet_command pc;
idefloppy_mode_parameter_header_t *header; idefloppy_mode_parameter_header_t *header;
idefloppy_capabilities_page_t *page; idefloppy_capabilities_page_t *page;
floppy->srfp=0; floppy->srfp=0;
idefloppy_create_mode_sense_cmd (&pc, IDEFLOPPY_CAPABILITIES_PAGE, idefloppy_create_mode_sense_cmd(&pc, IDEFLOPPY_CAPABILITIES_PAGE,
MODE_SENSE_CURRENT); MODE_SENSE_CURRENT);
set_bit(PC_SUPPRESS_ERROR, &pc.flags); set_bit(PC_SUPPRESS_ERROR, &pc.flags);
...@@ -1408,10 +1362,10 @@ static int idefloppy_get_capability_page(ide_drive_t *drive) ...@@ -1408,10 +1362,10 @@ static int idefloppy_get_capability_page(ide_drive_t *drive)
* Determine if a media is present in the floppy drive, and if so, * Determine if a media is present in the floppy drive, and if so,
* its LBA capacity. * its LBA capacity.
*/ */
static int idefloppy_get_capacity (ide_drive_t *drive) static int idefloppy_get_capacity(struct ata_device *drive)
{ {
idefloppy_floppy_t *floppy = drive->driver_data; idefloppy_floppy_t *floppy = drive->driver_data;
idefloppy_pc_t pc; struct atapi_packet_command pc;
idefloppy_capacity_header_t *header; idefloppy_capacity_header_t *header;
idefloppy_capacity_descriptor_t *descriptor; idefloppy_capacity_descriptor_t *descriptor;
int i, descriptors, rc = 1, blocks, length; int i, descriptors, rc = 1, blocks, length;
...@@ -1500,12 +1454,12 @@ static int idefloppy_get_capacity (ide_drive_t *drive) ...@@ -1500,12 +1454,12 @@ static int idefloppy_get_capacity (ide_drive_t *drive)
** **
*/ */
static int idefloppy_get_format_capacities (ide_drive_t *drive, static int idefloppy_get_format_capacities(struct ata_device *drive,
struct inode *inode, struct inode *inode,
struct file *file, struct file *file,
int *arg) /* Cheater */ int *arg) /* Cheater */
{ {
idefloppy_pc_t pc; struct atapi_packet_command pc;
idefloppy_capacity_header_t *header; idefloppy_capacity_header_t *header;
idefloppy_capacity_descriptor_t *descriptor; idefloppy_capacity_descriptor_t *descriptor;
int i, descriptors, blocks, length; int i, descriptors, blocks, length;
...@@ -1519,8 +1473,8 @@ static int idefloppy_get_format_capacities (ide_drive_t *drive, ...@@ -1519,8 +1473,8 @@ static int idefloppy_get_format_capacities (ide_drive_t *drive,
if (u_array_size <= 0) if (u_array_size <= 0)
return (-EINVAL); return (-EINVAL);
idefloppy_create_read_capacity_cmd (&pc); idefloppy_create_read_capacity_cmd(&pc);
if (idefloppy_queue_pc_tail (drive, &pc)) { if (idefloppy_queue_pc_tail(drive, &pc)) {
printk (KERN_ERR "ide-floppy: Can't get floppy parameters\n"); printk (KERN_ERR "ide-floppy: Can't get floppy parameters\n");
return (-EIO); return (-EIO);
} }
...@@ -1580,7 +1534,7 @@ static int idefloppy_get_format_capacities (ide_drive_t *drive, ...@@ -1580,7 +1534,7 @@ static int idefloppy_get_format_capacities (ide_drive_t *drive,
** 0x01 - verify media after format. ** 0x01 - verify media after format.
*/ */
static int idefloppy_begin_format(ide_drive_t *drive, static int idefloppy_begin_format(struct ata_device *drive,
struct inode *inode, struct inode *inode,
struct file *file, struct file *file,
int *arg) int *arg)
...@@ -1588,7 +1542,7 @@ static int idefloppy_begin_format(ide_drive_t *drive, ...@@ -1588,7 +1542,7 @@ static int idefloppy_begin_format(ide_drive_t *drive,
int blocks; int blocks;
int length; int length;
int flags; int flags;
idefloppy_pc_t pc; struct atapi_packet_command pc;
if (get_user(blocks, arg) if (get_user(blocks, arg)
|| get_user(length, arg+1) || get_user(length, arg+1)
...@@ -1599,10 +1553,9 @@ static int idefloppy_begin_format(ide_drive_t *drive, ...@@ -1599,10 +1553,9 @@ static int idefloppy_begin_format(ide_drive_t *drive,
(void) idefloppy_get_capability_page (drive); /* Get the SFRP bit */ (void) idefloppy_get_capability_page (drive); /* Get the SFRP bit */
idefloppy_create_format_unit_cmd(&pc, blocks, length, flags); idefloppy_create_format_unit_cmd(&pc, blocks, length, flags);
if (idefloppy_queue_pc_tail (drive, &pc)) if (idefloppy_queue_pc_tail(drive, &pc))
{ return -EIO;
return (-EIO);
}
return (0); return (0);
} }
...@@ -1616,13 +1569,13 @@ static int idefloppy_begin_format(ide_drive_t *drive, ...@@ -1616,13 +1569,13 @@ static int idefloppy_begin_format(ide_drive_t *drive,
** the dsc bit, and return either 0 or 65536. ** the dsc bit, and return either 0 or 65536.
*/ */
static int idefloppy_get_format_progress(ide_drive_t *drive, static int idefloppy_get_format_progress(struct ata_device *drive,
struct inode *inode, struct inode *inode,
struct file *file, struct file *file,
int *arg) int *arg)
{ {
idefloppy_floppy_t *floppy = drive->driver_data; idefloppy_floppy_t *floppy = drive->driver_data;
idefloppy_pc_t pc; struct atapi_packet_command pc;
int progress_indication=0x10000; int progress_indication=0x10000;
if (floppy->srfp) if (floppy->srfp)
...@@ -1664,10 +1617,10 @@ static int idefloppy_get_format_progress(ide_drive_t *drive, ...@@ -1664,10 +1617,10 @@ static int idefloppy_get_format_progress(ide_drive_t *drive,
* *
* Currently there aren't any ioctl's. * Currently there aren't any ioctl's.
*/ */
static int idefloppy_ioctl (ide_drive_t *drive, struct inode *inode, struct file *file, static int idefloppy_ioctl(struct ata_device *drive, struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg) unsigned int cmd, unsigned long arg)
{ {
idefloppy_pc_t pc; struct atapi_packet_command pc;
idefloppy_floppy_t *floppy = drive->driver_data; idefloppy_floppy_t *floppy = drive->driver_data;
int prevent = (arg) ? 1 : 0; int prevent = (arg) ? 1 : 0;
...@@ -1681,8 +1634,8 @@ static int idefloppy_ioctl (ide_drive_t *drive, struct inode *inode, struct file ...@@ -1681,8 +1634,8 @@ static int idefloppy_ioctl (ide_drive_t *drive, struct inode *inode, struct file
/* The IOMEGA Clik! Drive doesn't support this command - no room for an eject mechanism */ /* The IOMEGA Clik! Drive doesn't support this command - no room for an eject mechanism */
if (!test_bit(IDEFLOPPY_CLIK_DRIVE, &floppy->flags)) { if (!test_bit(IDEFLOPPY_CLIK_DRIVE, &floppy->flags)) {
idefloppy_create_prevent_cmd (&pc, prevent); idefloppy_create_prevent_cmd(&pc, prevent);
(void) idefloppy_queue_pc_tail (drive, &pc); (void) idefloppy_queue_pc_tail(drive, &pc);
} }
if (cmd == CDROMEJECT) { if (cmd == CDROMEJECT) {
idefloppy_create_start_stop_cmd (&pc, 2); idefloppy_create_start_stop_cmd (&pc, 2);
...@@ -1744,14 +1697,14 @@ static int idefloppy_ioctl (ide_drive_t *drive, struct inode *inode, struct file ...@@ -1744,14 +1697,14 @@ static int idefloppy_ioctl (ide_drive_t *drive, struct inode *inode, struct file
/* /*
* Our open/release functions * Our open/release functions
*/ */
static int idefloppy_open (struct inode *inode, struct file *filp, ide_drive_t *drive) static int idefloppy_open(struct inode *inode, struct file *filp, struct ata_device *drive)
{ {
idefloppy_floppy_t *floppy = drive->driver_data; idefloppy_floppy_t *floppy = drive->driver_data;
idefloppy_pc_t pc; struct atapi_packet_command pc;
#if IDEFLOPPY_DEBUG_LOG #if IDEFLOPPY_DEBUG_LOG
printk (KERN_INFO "Reached idefloppy_open\n"); printk (KERN_INFO "Reached idefloppy_open\n");
#endif /* IDEFLOPPY_DEBUG_LOG */ #endif
MOD_INC_USE_COUNT; MOD_INC_USE_COUNT;
if (drive->usage == 1) { if (drive->usage == 1) {
...@@ -1799,13 +1752,13 @@ static int idefloppy_open (struct inode *inode, struct file *filp, ide_drive_t * ...@@ -1799,13 +1752,13 @@ static int idefloppy_open (struct inode *inode, struct file *filp, ide_drive_t *
return 0; return 0;
} }
static void idefloppy_release (struct inode *inode, struct file *filp, ide_drive_t *drive) static void idefloppy_release(struct inode *inode, struct file *filp, struct ata_device *drive)
{ {
idefloppy_pc_t pc; struct atapi_packet_command pc;
#if IDEFLOPPY_DEBUG_LOG #if IDEFLOPPY_DEBUG_LOG
printk (KERN_INFO "Reached idefloppy_release\n"); printk (KERN_INFO "Reached idefloppy_release\n");
#endif /* IDEFLOPPY_DEBUG_LOG */ #endif
if (!drive->usage) { if (!drive->usage) {
idefloppy_floppy_t *floppy = drive->driver_data; idefloppy_floppy_t *floppy = drive->driver_data;
...@@ -1826,17 +1779,17 @@ static void idefloppy_release (struct inode *inode, struct file *filp, ide_drive ...@@ -1826,17 +1779,17 @@ static void idefloppy_release (struct inode *inode, struct file *filp, ide_drive
/* /*
* Check media change. Use a simple algorithm for now. * Check media change. Use a simple algorithm for now.
*/ */
static int idefloppy_check_media_change (ide_drive_t *drive) static int idefloppy_check_media_change(struct ata_device *drive)
{ {
idefloppy_floppy_t *floppy = drive->driver_data; idefloppy_floppy_t *floppy = drive->driver_data;
return test_and_clear_bit (IDEFLOPPY_MEDIA_CHANGED, &floppy->flags); return test_and_clear_bit(IDEFLOPPY_MEDIA_CHANGED, &floppy->flags);
} }
/* /*
* Return the current floppy capacity to ide.c. * Return the current floppy capacity to ide.c.
*/ */
static unsigned long idefloppy_capacity (ide_drive_t *drive) static unsigned long idefloppy_capacity(struct ata_device *drive)
{ {
idefloppy_floppy_t *floppy = drive->driver_data; idefloppy_floppy_t *floppy = drive->driver_data;
unsigned long capacity = floppy->blocks * floppy->bs_factor; unsigned long capacity = floppy->blocks * floppy->bs_factor;
...@@ -1848,7 +1801,7 @@ static unsigned long idefloppy_capacity (ide_drive_t *drive) ...@@ -1848,7 +1801,7 @@ static unsigned long idefloppy_capacity (ide_drive_t *drive)
* idefloppy_identify_device checks if we can support a drive, * idefloppy_identify_device checks if we can support a drive,
* based on the ATAPI IDENTIFY command results. * based on the ATAPI IDENTIFY command results.
*/ */
static int idefloppy_identify_device (ide_drive_t *drive,struct hd_driveid *id) static int idefloppy_identify_device(struct ata_device *drive,struct hd_driveid *id)
{ {
struct idefloppy_id_gcw gcw; struct idefloppy_id_gcw gcw;
#if IDEFLOPPY_DEBUG_INFO #if IDEFLOPPY_DEBUG_INFO
...@@ -1963,7 +1916,7 @@ static int idefloppy_identify_device (ide_drive_t *drive,struct hd_driveid *id) ...@@ -1963,7 +1916,7 @@ static int idefloppy_identify_device (ide_drive_t *drive,struct hd_driveid *id)
/* /*
* Driver initialization. * Driver initialization.
*/ */
static void idefloppy_setup (ide_drive_t *drive, idefloppy_floppy_t *floppy) static void idefloppy_setup(struct ata_device *drive, idefloppy_floppy_t *floppy)
{ {
struct idefloppy_id_gcw gcw; struct idefloppy_id_gcw gcw;
int i; int i;
...@@ -2013,7 +1966,7 @@ static void idefloppy_setup (ide_drive_t *drive, idefloppy_floppy_t *floppy) ...@@ -2013,7 +1966,7 @@ static void idefloppy_setup (ide_drive_t *drive, idefloppy_floppy_t *floppy)
} }
} }
static int idefloppy_cleanup (ide_drive_t *drive) static int idefloppy_cleanup(struct ata_device *drive)
{ {
idefloppy_floppy_t *floppy = drive->driver_data; idefloppy_floppy_t *floppy = drive->driver_data;
...@@ -2043,13 +1996,13 @@ static struct ata_operations idefloppy_driver = { ...@@ -2043,13 +1996,13 @@ static struct ata_operations idefloppy_driver = {
MODULE_DESCRIPTION("ATAPI FLOPPY Driver"); MODULE_DESCRIPTION("ATAPI FLOPPY Driver");
static void __exit idefloppy_exit (void) static void __exit idefloppy_exit(void)
{ {
ide_drive_t *drive; struct ata_device *drive;
int failed = 0; int failed = 0;
while ((drive = ide_scan_devices(ATA_FLOPPY, "ide-floppy", &idefloppy_driver, failed)) != NULL) { while ((drive = ide_scan_devices(ATA_FLOPPY, "ide-floppy", &idefloppy_driver, failed)) != NULL) {
if (idefloppy_cleanup (drive)) { if (idefloppy_cleanup(drive)) {
printk ("%s: cleanup_module() called while still busy\n", drive->name); printk ("%s: cleanup_module() called while still busy\n", drive->name);
failed++; failed++;
} }
...@@ -2059,9 +2012,9 @@ static void __exit idefloppy_exit (void) ...@@ -2059,9 +2012,9 @@ static void __exit idefloppy_exit (void)
/* /*
* idefloppy_init will register the driver for each floppy. * idefloppy_init will register the driver for each floppy.
*/ */
int idefloppy_init (void) int idefloppy_init(void)
{ {
ide_drive_t *drive; struct ata_device *drive;
idefloppy_floppy_t *floppy; idefloppy_floppy_t *floppy;
int failed = 0; int failed = 0;
......
...@@ -417,9 +417,10 @@ ...@@ -417,9 +417,10 @@
#include <linux/genhd.h> #include <linux/genhd.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/ide.h>
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
#include <linux/completion.h> #include <linux/completion.h>
#include <linux/ide.h>
#include <linux/atapi.h>
#include <asm/byteorder.h> #include <asm/byteorder.h>
#include <asm/irq.h> #include <asm/irq.h>
...@@ -614,13 +615,6 @@ typedef struct { ...@@ -614,13 +615,6 @@ typedef struct {
*/ */
#define IDETAPE_MAX_PC_RETRIES 3 #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
/* /*
* In various places in the driver, we need to allocate storage * In various places in the driver, we need to allocate storage
* for packet commands and requests, which will remain valid while * for packet commands and requests, which will remain valid while
...@@ -711,27 +705,6 @@ typedef enum { ...@@ -711,27 +705,6 @@ typedef enum {
idetape_direction_write idetape_direction_write
} idetape_chrdev_direction_t; } idetape_chrdev_direction_t;
/*
* Our view of a packet command.
*/
typedef struct idetape_packet_command_s {
u8 c[12]; /* Actual packet bytes */
int retries; /* On each retry, we increment retries */
int error; /* Error code */
int request_transfer; /* Bytes to transfer */
int actually_transferred; /* Bytes actually transferred */
int buffer_size; /* Size of our data buffer */
struct bio *bio;
char *b_data;
int b_count;
byte *buffer; /* Data buffer */
byte *current_position; /* Pointer into the above buffer */
/* Called when this packet command is completed */
ide_startstop_t (*callback) (struct ata_device *, struct request *);
byte pc_buffer[IDETAPE_PC_BUFFER_SIZE]; /* Temporary buffer */
unsigned long flags; /* Status/Action bit flags: long for set_bit */
} idetape_pc_t;
/* /*
* Packet command flag bits. * Packet command flag bits.
*/ */
...@@ -747,10 +720,10 @@ typedef struct idetape_packet_command_s { ...@@ -747,10 +720,10 @@ typedef struct idetape_packet_command_s {
*/ */
typedef struct { typedef struct {
unsigned page_code :6; /* Page code - Should be 0x2a */ unsigned page_code :6; /* Page code - Should be 0x2a */
__u8 reserved0_6 :1; u8 reserved0_6 :1;
__u8 ps :1; /* parameters saveable */ u8 ps :1; /* parameters saveable */
__u8 page_length; /* Page Length - Should be 0x12 */ u8 page_length; /* Page Length - Should be 0x12 */
__u8 reserved2, reserved3; u8 reserved2, reserved3;
unsigned ro :1; /* Read Only Mode */ unsigned ro :1; /* Read Only Mode */
unsigned reserved4_1234 :4; unsigned reserved4_1234 :4;
unsigned sprev :1; /* Supports SPACE in the reverse direction */ unsigned sprev :1; /* Supports SPACE in the reverse direction */
...@@ -764,8 +737,8 @@ typedef struct { ...@@ -764,8 +737,8 @@ typedef struct {
unsigned locked :1; /* The volume is locked */ unsigned locked :1; /* The volume is locked */
unsigned prevent :1; /* The device defaults in the prevent state after power up */ unsigned prevent :1; /* The device defaults in the prevent state after power up */
unsigned eject :1; /* The device can eject the volume */ unsigned eject :1; /* The device can eject the volume */
__u8 disconnect :1; /* The device can break request > ctl */ u8 disconnect :1; /* The device can break request > ctl */
__u8 reserved6_5 :1; u8 reserved6_5 :1;
unsigned ecc :1; /* Supports error correction */ unsigned ecc :1; /* Supports error correction */
unsigned cmprs :1; /* Supports data compression */ unsigned cmprs :1; /* Supports data compression */
unsigned reserved7_0 :1; unsigned reserved7_0 :1;
...@@ -775,12 +748,12 @@ typedef struct { ...@@ -775,12 +748,12 @@ typedef struct {
unsigned blk32768 :1; /* slowb - the device restricts the byte count for PIO */ unsigned blk32768 :1; /* slowb - the device restricts the byte count for PIO */
/* transfers for slow buffer memory ??? */ /* transfers for slow buffer memory ??? */
/* Also 32768 block size in some cases */ /* Also 32768 block size in some cases */
__u16 max_speed; /* Maximum speed supported in KBps */ u16 max_speed; /* Maximum speed supported in KBps */
__u8 reserved10, reserved11; u8 reserved10, reserved11;
__u16 ctl; /* Continuous Transfer Limit in blocks */ u16 ctl; /* Continuous Transfer Limit in blocks */
__u16 speed; /* Current Speed, in KBps */ u16 speed; /* Current Speed, in KBps */
__u16 buffer_size; /* Buffer Size, in 512 bytes */ u16 buffer_size; /* Buffer Size, in 512 bytes */
__u8 reserved18, reserved19; u8 reserved18, reserved19;
} idetape_capabilities_page_t; } idetape_capabilities_page_t;
/* /*
...@@ -790,8 +763,8 @@ typedef struct { ...@@ -790,8 +763,8 @@ typedef struct {
unsigned page_code :6; /* Page code - Should be 0x30 */ unsigned page_code :6; /* Page code - Should be 0x30 */
unsigned reserved1_6 :1; unsigned reserved1_6 :1;
unsigned ps :1; unsigned ps :1;
__u8 page_length; /* Page Length - Should be 2 */ u8 page_length; /* Page Length - Should be 2 */
__u8 reserved2; u8 reserved2;
unsigned play32 :1; unsigned play32 :1;
unsigned play32_5 :1; unsigned play32_5 :1;
unsigned reserved2_23 :2; unsigned reserved2_23 :2;
...@@ -861,9 +834,9 @@ typedef struct { ...@@ -861,9 +834,9 @@ typedef struct {
* required since an additional packet command is needed before the * required since an additional packet command is needed before the
* retry, to get detailed information on what went wrong. * retry, to get detailed information on what went wrong.
*/ */
idetape_pc_t *pc; /* Current packet command */ struct atapi_packet_command *pc; /* Current packet command */
idetape_pc_t *failed_pc; /* Last failed packet command */ struct atapi_packet_command *failed_pc; /* Last failed packet command */
idetape_pc_t pc_stack[IDETAPE_PC_STACK];/* Packet command stack */ struct atapi_packet_command pc_stack[IDETAPE_PC_STACK];/* Packet command stack */
int pc_stack_index; /* Next free packet command storage space */ int pc_stack_index; /* Next free packet command storage space */
struct request rq_stack[IDETAPE_PC_STACK]; struct request rq_stack[IDETAPE_PC_STACK];
int rq_stack_index; /* We implement a circular array */ int rq_stack_index; /* We implement a circular array */
...@@ -1482,17 +1455,9 @@ static void idetape_onstream_mode_sense_tape_parameter_page(struct ata_device *d ...@@ -1482,17 +1455,9 @@ static void idetape_onstream_mode_sense_tape_parameter_page(struct ata_device *d
static int idetape_chrdev_release (struct inode *inode, struct file *filp); static int idetape_chrdev_release (struct inode *inode, struct file *filp);
static void idetape_write_release (struct inode *inode); static void idetape_write_release (struct inode *inode);
/* static void idetape_input_buffers(struct ata_device *drive,
* Too bad. The drive wants to send us data which we are not ready to accept. struct atapi_packet_command *pc,
* Just throw it away. unsigned int bcount)
*/
static void idetape_discard_data(struct ata_device *drive, unsigned int bcount)
{
while (bcount--)
IN_BYTE (IDE_DATA_REG);
}
static void idetape_input_buffers(struct ata_device *drive, idetape_pc_t *pc, unsigned int bcount)
{ {
struct bio *bio = pc->bio; struct bio *bio = pc->bio;
int count; int count;
...@@ -1501,7 +1466,7 @@ static void idetape_input_buffers(struct ata_device *drive, idetape_pc_t *pc, un ...@@ -1501,7 +1466,7 @@ static void idetape_input_buffers(struct ata_device *drive, idetape_pc_t *pc, un
#if IDETAPE_DEBUG_BUGS #if IDETAPE_DEBUG_BUGS
if (bio == NULL) { if (bio == NULL) {
printk (KERN_ERR "ide-tape: bio == NULL in idetape_input_buffers\n"); printk (KERN_ERR "ide-tape: bio == NULL in idetape_input_buffers\n");
idetape_discard_data (drive, bcount); atapi_discard_data(drive, bcount);
return; return;
} }
#endif #endif
...@@ -1518,7 +1483,9 @@ static void idetape_input_buffers(struct ata_device *drive, idetape_pc_t *pc, un ...@@ -1518,7 +1483,9 @@ static void idetape_input_buffers(struct ata_device *drive, idetape_pc_t *pc, un
pc->bio = bio; pc->bio = bio;
} }
static void idetape_output_buffers(struct ata_device *drive, idetape_pc_t *pc, unsigned int bcount) static void idetape_output_buffers(struct ata_device *drive,
struct atapi_packet_command *pc,
unsigned int bcount)
{ {
struct bio *bio = pc->bio; struct bio *bio = pc->bio;
int count; int count;
...@@ -1529,7 +1496,7 @@ static void idetape_output_buffers(struct ata_device *drive, idetape_pc_t *pc, u ...@@ -1529,7 +1496,7 @@ static void idetape_output_buffers(struct ata_device *drive, idetape_pc_t *pc, u
printk (KERN_ERR "ide-tape: bio == NULL in idetape_output_buffers\n"); printk (KERN_ERR "ide-tape: bio == NULL in idetape_output_buffers\n");
return; return;
} }
#endif /* IDETAPE_DEBUG_BUGS */ #endif
count = min(pc->b_count, bcount); count = min(pc->b_count, bcount);
atapi_write(drive, bio_data(bio), count); atapi_write(drive, bio_data(bio), count);
bcount -= count; bcount -= count;
...@@ -1546,20 +1513,21 @@ static void idetape_output_buffers(struct ata_device *drive, idetape_pc_t *pc, u ...@@ -1546,20 +1513,21 @@ static void idetape_output_buffers(struct ata_device *drive, idetape_pc_t *pc, u
} }
#ifdef CONFIG_BLK_DEV_IDEDMA #ifdef CONFIG_BLK_DEV_IDEDMA
static void idetape_update_buffers (idetape_pc_t *pc) static void idetape_update_buffers(struct atapi_packet_command *pc)
{ {
struct bio *bio = pc->bio; struct bio *bio = pc->bio;
int count, bcount = pc->actually_transferred; int count;
unsigned int bcount = pc->actually_transferred;
if (test_bit (PC_WRITING, &pc->flags)) if (test_bit(PC_WRITING, &pc->flags))
return; return;
while (bcount) { while (bcount) {
#if IDETAPE_DEBUG_BUGS # if IDETAPE_DEBUG_BUGS
if (bio == NULL) { if (bio == NULL) {
printk (KERN_ERR "ide-tape: bio == NULL in idetape_update_buffers\n"); printk (KERN_ERR "ide-tape: bio == NULL in idetape_update_buffers\n");
return; return;
} }
#endif /* IDETAPE_DEBUG_BUGS */ # endif
count = min(bio->bi_size, bcount); count = min(bio->bi_size, bcount);
pc->b_count = count; pc->b_count = count;
if (pc->b_count == bio->bi_size) if (pc->b_count == bio->bi_size)
...@@ -1568,7 +1536,7 @@ static void idetape_update_buffers (idetape_pc_t *pc) ...@@ -1568,7 +1536,7 @@ static void idetape_update_buffers (idetape_pc_t *pc)
} }
pc->bio = bio; pc->bio = bio;
} }
#endif /* CONFIG_BLK_DEV_IDEDMA */ #endif
/* /*
* idetape_next_pc_storage returns a pointer to a place in which we can * idetape_next_pc_storage returns a pointer to a place in which we can
...@@ -1576,7 +1544,7 @@ static void idetape_update_buffers (idetape_pc_t *pc) ...@@ -1576,7 +1544,7 @@ static void idetape_update_buffers (idetape_pc_t *pc)
* driver. A storage space for a maximum of IDETAPE_PC_STACK packet * driver. A storage space for a maximum of IDETAPE_PC_STACK packet
* commands is allocated at initialization time. * commands is allocated at initialization time.
*/ */
static idetape_pc_t *idetape_next_pc_storage(struct ata_device *drive) static struct atapi_packet_command *idetape_next_pc_storage(struct ata_device *drive)
{ {
idetape_tape_t *tape = drive->driver_data; idetape_tape_t *tape = drive->driver_data;
...@@ -1609,27 +1577,12 @@ static struct request *idetape_next_rq_storage(struct ata_device *drive) ...@@ -1609,27 +1577,12 @@ static struct request *idetape_next_rq_storage(struct ata_device *drive)
#if IDETAPE_DEBUG_LOG #if IDETAPE_DEBUG_LOG
if (tape->debug_level >= 5) if (tape->debug_level >= 5)
printk (KERN_INFO "ide-tape: rq_stack_index=%d\n",tape->rq_stack_index); printk (KERN_INFO "ide-tape: rq_stack_index=%d\n",tape->rq_stack_index);
#endif /* IDETAPE_DEBUG_LOG */ #endif
if (tape->rq_stack_index==IDETAPE_PC_STACK) if (tape->rq_stack_index==IDETAPE_PC_STACK)
tape->rq_stack_index=0; tape->rq_stack_index=0;
return (&tape->rq_stack[tape->rq_stack_index++]); return (&tape->rq_stack[tape->rq_stack_index++]);
} }
/*
* idetape_init_pc initializes a packet command.
*/
static void idetape_init_pc (idetape_pc_t *pc)
{
memset (pc->c, 0, 12);
pc->retries = 0;
pc->flags = 0;
pc->request_transfer = 0;
pc->buffer = pc->pc_buffer;
pc->buffer_size = IDETAPE_PC_BUFFER_SIZE;
pc->bio = NULL;
pc->b_data = NULL;
}
/* /*
* idetape_analyze_error is called on each failed packet command retry * idetape_analyze_error is called on each failed packet command retry
* to analyze the request sense. We currently do not utilize this * to analyze the request sense. We currently do not utilize this
...@@ -1638,7 +1591,7 @@ static void idetape_init_pc (idetape_pc_t *pc) ...@@ -1638,7 +1591,7 @@ static void idetape_init_pc (idetape_pc_t *pc)
static void idetape_analyze_error(struct ata_device *drive, idetape_request_sense_result_t *result) static void idetape_analyze_error(struct ata_device *drive, idetape_request_sense_result_t *result)
{ {
idetape_tape_t *tape = drive->driver_data; idetape_tape_t *tape = drive->driver_data;
idetape_pc_t *pc = tape->failed_pc; struct atapi_packet_command *pc = tape->failed_pc;
tape->sense = *result; tape->sense = *result;
tape->sense_key = result->sense_key; tape->sense_key = result->sense_key;
...@@ -1652,15 +1605,15 @@ static void idetape_analyze_error(struct ata_device *drive, idetape_request_sens ...@@ -1652,15 +1605,15 @@ static void idetape_analyze_error(struct ata_device *drive, idetape_request_sens
if (tape->debug_level >= 1) if (tape->debug_level >= 1)
printk (KERN_INFO "ide-tape: pc = %x, sense key = %x, asc = %x, ascq = %x\n", printk (KERN_INFO "ide-tape: pc = %x, sense key = %x, asc = %x, ascq = %x\n",
pc->c[0], result->sense_key, result->asc, result->ascq); pc->c[0], result->sense_key, result->asc, result->ascq);
#if IDETAPE_DEBUG_LOG_VERBOSE # if IDETAPE_DEBUG_LOG_VERBOSE
if (tape->debug_level >= 1) if (tape->debug_level >= 1)
printk (KERN_INFO "ide-tape: pc = %s, sense key = %x, asc = %x, ascq = %x\n", printk (KERN_INFO "ide-tape: pc = %s, sense key = %x, asc = %x, ascq = %x\n",
idetape_command_key_verbose((byte) pc->c[0]), idetape_command_key_verbose((byte) pc->c[0]),
result->sense_key, result->sense_key,
result->asc, result->asc,
result->ascq); result->ascq);
#endif /* IDETAPE_DEBUG_LOG_VERBOSE */ # endif
#endif /* IDETAPE_DEBUG_LOG */ #endif
if (tape->onstream && result->sense_key == 2 && result->asc == 0x53 && result->ascq == 2) { if (tape->onstream && result->sense_key == 2 && result->asc == 0x53 && result->ascq == 2) {
clear_bit(PC_DMA_ERROR, &pc->flags); clear_bit(PC_DMA_ERROR, &pc->flags);
...@@ -1674,23 +1627,23 @@ static void idetape_analyze_error(struct ata_device *drive, idetape_request_sens ...@@ -1674,23 +1627,23 @@ static void idetape_analyze_error(struct ata_device *drive, idetape_request_sens
*/ */
if (test_bit (PC_DMA_ERROR, &pc->flags)) { if (test_bit (PC_DMA_ERROR, &pc->flags)) {
pc->actually_transferred = pc->request_transfer - tape->tape_block_size * ntohl (get_unaligned (&result->information)); pc->actually_transferred = pc->request_transfer - tape->tape_block_size * ntohl (get_unaligned (&result->information));
idetape_update_buffers (pc); idetape_update_buffers(pc);
} }
#endif /* CONFIG_BLK_DEV_IDEDMA */ #endif
if (pc->c[0] == IDETAPE_READ_CMD && result->filemark) { if (pc->c[0] == IDETAPE_READ_CMD && result->filemark) {
pc->error = IDETAPE_ERROR_FILEMARK; pc->error = IDETAPE_ERROR_FILEMARK;
set_bit (PC_ABORT, &pc->flags); set_bit(PC_ABORT, &pc->flags);
} }
if (pc->c[0] == IDETAPE_WRITE_CMD) { if (pc->c[0] == IDETAPE_WRITE_CMD) {
if (result->eom || (result->sense_key == 0xd && result->asc == 0x0 && result->ascq == 0x2)) { if (result->eom || (result->sense_key == 0xd && result->asc == 0x0 && result->ascq == 0x2)) {
pc->error = IDETAPE_ERROR_EOD; pc->error = IDETAPE_ERROR_EOD;
set_bit (PC_ABORT, &pc->flags); set_bit(PC_ABORT, &pc->flags);
} }
} }
if (pc->c[0] == IDETAPE_READ_CMD || pc->c[0] == IDETAPE_WRITE_CMD) { if (pc->c[0] == IDETAPE_READ_CMD || pc->c[0] == IDETAPE_WRITE_CMD) {
if (result->sense_key == 8) { if (result->sense_key == 8) {
pc->error = IDETAPE_ERROR_EOD; pc->error = IDETAPE_ERROR_EOD;
set_bit (PC_ABORT, &pc->flags); set_bit(PC_ABORT, &pc->flags);
} }
if (!test_bit (PC_ABORT, &pc->flags) && (tape->onstream || pc->actually_transferred)) if (!test_bit (PC_ABORT, &pc->flags) && (tape->onstream || pc->actually_transferred))
pc->retries = IDETAPE_MAX_PC_RETRIES + 1; pc->retries = IDETAPE_MAX_PC_RETRIES + 1;
...@@ -1727,13 +1680,13 @@ static void idetape_active_next_stage(struct ata_device *drive) ...@@ -1727,13 +1680,13 @@ static void idetape_active_next_stage(struct ata_device *drive)
#if IDETAPE_DEBUG_LOG #if IDETAPE_DEBUG_LOG
if (tape->debug_level >= 4) if (tape->debug_level >= 4)
printk (KERN_INFO "ide-tape: Reached idetape_active_next_stage\n"); printk (KERN_INFO "ide-tape: Reached idetape_active_next_stage\n");
#endif /* IDETAPE_DEBUG_LOG */ #endif
#if IDETAPE_DEBUG_BUGS #if IDETAPE_DEBUG_BUGS
if (stage == NULL) { if (stage == NULL) {
printk (KERN_ERR "ide-tape: bug: Trying to activate a non existing stage\n"); printk (KERN_ERR "ide-tape: bug: Trying to activate a non existing stage\n");
return; return;
} }
#endif /* IDETAPE_DEBUG_BUGS */ #endif
rq->buffer = NULL; rq->buffer = NULL;
rq->bio = stage->bio; rq->bio = stage->bio;
...@@ -1816,7 +1769,7 @@ static void idetape_remove_stage_head(struct ata_device *drive) ...@@ -1816,7 +1769,7 @@ static void idetape_remove_stage_head(struct ata_device *drive)
printk (KERN_ERR "ide-tape: bug: Trying to free our active pipeline stage\n"); printk (KERN_ERR "ide-tape: bug: Trying to free our active pipeline stage\n");
return; return;
} }
#endif /* IDETAPE_DEBUG_BUGS */ #endif
stage = tape->first_stage; stage = tape->first_stage;
tape->first_stage = stage->next; tape->first_stage = stage->next;
idetape_kfree_stage (tape, stage); idetape_kfree_stage (tape, stage);
...@@ -1828,7 +1781,7 @@ static void idetape_remove_stage_head(struct ata_device *drive) ...@@ -1828,7 +1781,7 @@ static void idetape_remove_stage_head(struct ata_device *drive)
printk (KERN_ERR "ide-tape: bug: tape->next_stage != NULL\n"); printk (KERN_ERR "ide-tape: bug: tape->next_stage != NULL\n");
if (tape->nr_stages) if (tape->nr_stages)
printk (KERN_ERR "ide-tape: bug: nr_stages should be 0 now\n"); printk (KERN_ERR "ide-tape: bug: nr_stages should be 0 now\n");
#endif /* IDETAPE_DEBUG_BUGS */ #endif
} }
} }
...@@ -1935,14 +1888,14 @@ static int idetape_end_request(struct ata_device *drive, struct request *rq, int ...@@ -1935,14 +1888,14 @@ static int idetape_end_request(struct ata_device *drive, struct request *rq, int
return 0; return 0;
} }
static ide_startstop_t idetape_request_sense_callback(struct ata_device *drive, struct request *rq) static void idetape_request_sense_callback(struct ata_device *drive, struct request *rq)
{ {
idetape_tape_t *tape = drive->driver_data; idetape_tape_t *tape = drive->driver_data;
#if IDETAPE_DEBUG_LOG #if IDETAPE_DEBUG_LOG
if (tape->debug_level >= 4) if (tape->debug_level >= 4)
printk (KERN_INFO "ide-tape: Reached idetape_request_sense_callback\n"); printk (KERN_INFO "ide-tape: Reached idetape_request_sense_callback\n");
#endif /* IDETAPE_DEBUG_LOG */ #endif
if (!tape->pc->error) { if (!tape->pc->error) {
idetape_analyze_error (drive, (idetape_request_sense_result_t *) tape->pc->buffer); idetape_analyze_error (drive, (idetape_request_sense_result_t *) tape->pc->buffer);
idetape_end_request(drive, rq, 1); idetape_end_request(drive, rq, 1);
...@@ -1950,12 +1903,11 @@ static ide_startstop_t idetape_request_sense_callback(struct ata_device *drive, ...@@ -1950,12 +1903,11 @@ static ide_startstop_t idetape_request_sense_callback(struct ata_device *drive,
printk (KERN_ERR "ide-tape: Error in REQUEST SENSE itself - Aborting request!\n"); printk (KERN_ERR "ide-tape: Error in REQUEST SENSE itself - Aborting request!\n");
idetape_end_request(drive, rq, 0); idetape_end_request(drive, rq, 0);
} }
return ide_stopped;
} }
static void idetape_create_request_sense_cmd (idetape_pc_t *pc) static void idetape_create_request_sense_cmd(struct atapi_packet_command *pc)
{ {
idetape_init_pc (pc); atapi_init_pc(pc);
pc->c[0] = IDETAPE_REQUEST_SENSE_CMD; pc->c[0] = IDETAPE_REQUEST_SENSE_CMD;
pc->c[4] = 20; pc->c[4] = 20;
pc->request_transfer = 18; pc->request_transfer = 18;
...@@ -1981,7 +1933,7 @@ static void idetape_create_request_sense_cmd (idetape_pc_t *pc) ...@@ -1981,7 +1933,7 @@ static void idetape_create_request_sense_cmd (idetape_pc_t *pc)
* and wait for their completion using idetape_queue_pc_tail or * and wait for their completion using idetape_queue_pc_tail or
* idetape_queue_rw_tail. * idetape_queue_rw_tail.
*/ */
static void idetape_queue_pc_head(struct ata_device *drive, idetape_pc_t *pc, struct request *rq) static void idetape_queue_pc_head(struct ata_device *drive, struct atapi_packet_command *pc, struct request *rq)
{ {
ide_init_drive_cmd (rq); ide_init_drive_cmd (rq);
rq->buffer = (char *) pc; rq->buffer = (char *) pc;
...@@ -1994,10 +1946,10 @@ static void idetape_queue_pc_head(struct ata_device *drive, idetape_pc_t *pc, st ...@@ -1994,10 +1946,10 @@ static void idetape_queue_pc_head(struct ata_device *drive, idetape_pc_t *pc, st
* last packet command. We queue a request sense packet command in * last packet command. We queue a request sense packet command in
* the head of the request list. * the head of the request list.
*/ */
static ide_startstop_t idetape_retry_pc(struct ata_device *drive) static void idetape_retry_pc(struct ata_device *drive)
{ {
idetape_tape_t *tape = drive->driver_data; idetape_tape_t *tape = drive->driver_data;
idetape_pc_t *pc; struct atapi_packet_command *pc;
struct request *rq; struct request *rq;
idetape_error_reg_t error; idetape_error_reg_t error;
...@@ -2007,7 +1959,6 @@ static ide_startstop_t idetape_retry_pc(struct ata_device *drive) ...@@ -2007,7 +1959,6 @@ static ide_startstop_t idetape_retry_pc(struct ata_device *drive)
idetape_create_request_sense_cmd (pc); idetape_create_request_sense_cmd (pc);
set_bit (IDETAPE_IGNORE_DSC, &tape->flags); set_bit (IDETAPE_IGNORE_DSC, &tape->flags);
idetape_queue_pc_head (drive, pc, rq); idetape_queue_pc_head (drive, pc, rq);
return ide_stopped;
} }
/* /*
...@@ -2041,7 +1992,7 @@ static ide_startstop_t idetape_pc_intr(struct ata_device *drive, struct request ...@@ -2041,7 +1992,7 @@ static ide_startstop_t idetape_pc_intr(struct ata_device *drive, struct request
idetape_status_reg_t status; idetape_status_reg_t status;
idetape_bcount_reg_t bcount; idetape_bcount_reg_t bcount;
idetape_ireason_reg_t ireason; idetape_ireason_reg_t ireason;
idetape_pc_t *pc = tape->pc; struct atapi_packet_command *pc = tape->pc;
unsigned int temp; unsigned int temp;
unsigned long cmd_time; unsigned long cmd_time;
...@@ -2052,7 +2003,7 @@ static ide_startstop_t idetape_pc_intr(struct ata_device *drive, struct request ...@@ -2052,7 +2003,7 @@ static ide_startstop_t idetape_pc_intr(struct ata_device *drive, struct request
#if IDETAPE_DEBUG_LOG #if IDETAPE_DEBUG_LOG
if (tape->debug_level >= 4) if (tape->debug_level >= 4)
printk (KERN_INFO "ide-tape: Reached idetape_pc_intr interrupt handler\n"); printk (KERN_INFO "ide-tape: Reached idetape_pc_intr interrupt handler\n");
#endif /* IDETAPE_DEBUG_LOG */ #endif
status.all = GET_STAT(); /* Clear the interrupt */ status.all = GET_STAT(); /* Clear the interrupt */
...@@ -2078,9 +2029,9 @@ static ide_startstop_t idetape_pc_intr(struct ata_device *drive, struct request ...@@ -2078,9 +2029,9 @@ static ide_startstop_t idetape_pc_intr(struct ata_device *drive, struct request
#if IDETAPE_DEBUG_LOG #if IDETAPE_DEBUG_LOG
if (tape->debug_level >= 4) if (tape->debug_level >= 4)
printk (KERN_INFO "ide-tape: DMA finished\n"); printk (KERN_INFO "ide-tape: DMA finished\n");
#endif /* IDETAPE_DEBUG_LOG */ #endif
} }
#endif /* CONFIG_BLK_DEV_IDEDMA */ #endif
if (!status.b.drq) { /* No more interrupts */ if (!status.b.drq) { /* No more interrupts */
cmd_time = (jiffies - tape->cmd_start_time) * 1000 / HZ; cmd_time = (jiffies - tape->cmd_start_time) * 1000 / HZ;
...@@ -2088,7 +2039,7 @@ static ide_startstop_t idetape_pc_intr(struct ata_device *drive, struct request ...@@ -2088,7 +2039,7 @@ static ide_startstop_t idetape_pc_intr(struct ata_device *drive, struct request
#if IDETAPE_DEBUG_LOG #if IDETAPE_DEBUG_LOG
if (tape->debug_level >= 2) if (tape->debug_level >= 2)
printk (KERN_INFO "ide-tape: Packet command completed, %d bytes transferred\n", pc->actually_transferred); printk (KERN_INFO "ide-tape: Packet command completed, %d bytes transferred\n", pc->actually_transferred);
#endif /* IDETAPE_DEBUG_LOG */ #endif
clear_bit (PC_DMA_IN_PROGRESS, &pc->flags); clear_bit (PC_DMA_IN_PROGRESS, &pc->flags);
ide__sti(); /* local CPU only */ ide__sti(); /* local CPU only */
...@@ -2105,7 +2056,7 @@ static ide_startstop_t idetape_pc_intr(struct ata_device *drive, struct request ...@@ -2105,7 +2056,7 @@ static ide_startstop_t idetape_pc_intr(struct ata_device *drive, struct request
#if IDETAPE_DEBUG_LOG #if IDETAPE_DEBUG_LOG
if (tape->debug_level >= 1) if (tape->debug_level >= 1)
printk (KERN_INFO "ide-tape: %s: I/O error, ",tape->name); printk (KERN_INFO "ide-tape: %s: I/O error, ",tape->name);
#endif /* IDETAPE_DEBUG_LOG */ #endif
if (pc->c[0] == IDETAPE_REQUEST_SENSE_CMD) { if (pc->c[0] == IDETAPE_REQUEST_SENSE_CMD) {
printk (KERN_ERR "ide-tape: I/O error in request sense command\n"); printk (KERN_ERR "ide-tape: I/O error in request sense command\n");
return ide_stopped; return ide_stopped;
...@@ -2114,7 +2065,8 @@ static ide_startstop_t idetape_pc_intr(struct ata_device *drive, struct request ...@@ -2114,7 +2065,8 @@ static ide_startstop_t idetape_pc_intr(struct ata_device *drive, struct request
if (tape->debug_level >= 1) if (tape->debug_level >= 1)
printk(KERN_INFO "ide-tape: [cmd %x]: check condition\n", pc->c[0]); printk(KERN_INFO "ide-tape: [cmd %x]: check condition\n", pc->c[0]);
#endif #endif
return idetape_retry_pc (drive); /* Retry operation */ idetape_retry_pc(drive); /* Retry operation */
return ide_stopped;
} }
pc->error = 0; pc->error = 0;
if (!tape->onstream && test_bit (PC_WAIT_FOR_DSC, &pc->flags) && !status.b.dsc) { /* Media access command */ if (!tape->onstream && test_bit (PC_WAIT_FOR_DSC, &pc->flags) && !status.b.dsc) { /* Media access command */
...@@ -2126,7 +2078,8 @@ static ide_startstop_t idetape_pc_intr(struct ata_device *drive, struct request ...@@ -2126,7 +2078,8 @@ static ide_startstop_t idetape_pc_intr(struct ata_device *drive, struct request
} }
if (tape->failed_pc == pc) if (tape->failed_pc == pc)
tape->failed_pc = NULL; tape->failed_pc = NULL;
return pc->callback(drive, rq); /* Command finished - Call the callback function */ pc->callback(drive, rq); /* Command finished - Call the callback function */
return ide_stopped;
} }
#ifdef CONFIG_BLK_DEV_IDEDMA #ifdef CONFIG_BLK_DEV_IDEDMA
if (test_and_clear_bit (PC_DMA_IN_PROGRESS, &pc->flags)) { if (test_and_clear_bit (PC_DMA_IN_PROGRESS, &pc->flags)) {
...@@ -2136,7 +2089,7 @@ static ide_startstop_t idetape_pc_intr(struct ata_device *drive, struct request ...@@ -2136,7 +2089,7 @@ static ide_startstop_t idetape_pc_intr(struct ata_device *drive, struct request
return ide_stopped; return ide_stopped;
} }
#endif /* CONFIG_BLK_DEV_IDEDMA */ #endif
bcount.b.high = IN_BYTE (IDE_BCOUNTH_REG); /* Get the number of bytes to transfer */ bcount.b.high = IN_BYTE (IDE_BCOUNTH_REG); /* Get the number of bytes to transfer */
bcount.b.low = IN_BYTE (IDE_BCOUNTL_REG); /* on this interrupt */ bcount.b.low = IN_BYTE (IDE_BCOUNTL_REG); /* on this interrupt */
ireason.all = IN_BYTE (IDE_IREASON_REG); ireason.all = IN_BYTE (IDE_IREASON_REG);
...@@ -2155,14 +2108,14 @@ static ide_startstop_t idetape_pc_intr(struct ata_device *drive, struct request ...@@ -2155,14 +2108,14 @@ static ide_startstop_t idetape_pc_intr(struct ata_device *drive, struct request
if ( temp > pc->request_transfer) { if ( temp > pc->request_transfer) {
if (temp > pc->buffer_size) { if (temp > pc->buffer_size) {
printk (KERN_ERR "ide-tape: The tape wants to send us more data than expected - discarding data\n"); printk (KERN_ERR "ide-tape: The tape wants to send us more data than expected - discarding data\n");
idetape_discard_data (drive, bcount.all); atapi_discard_data (drive, bcount.all);
ide_set_handler(drive, idetape_pc_intr, IDETAPE_WAIT_CMD, NULL); ide_set_handler(drive, idetape_pc_intr, IDETAPE_WAIT_CMD, NULL);
return ide_started; return ide_started;
} }
#if IDETAPE_DEBUG_LOG #if IDETAPE_DEBUG_LOG
if (tape->debug_level >= 2) if (tape->debug_level >= 2)
printk (KERN_NOTICE "ide-tape: The tape wants to send us more data than expected - allowing transfer\n"); printk (KERN_NOTICE "ide-tape: The tape wants to send us more data than expected - allowing transfer\n");
#endif /* IDETAPE_DEBUG_LOG */ #endif
} }
} }
if (test_bit (PC_WRITING, &pc->flags)) { if (test_bit (PC_WRITING, &pc->flags)) {
...@@ -2231,7 +2184,7 @@ static ide_startstop_t idetape_pc_intr(struct ata_device *drive, struct request ...@@ -2231,7 +2184,7 @@ static ide_startstop_t idetape_pc_intr(struct ata_device *drive, struct request
static ide_startstop_t idetape_transfer_pc(struct ata_device *drive, struct request *rq) static ide_startstop_t idetape_transfer_pc(struct ata_device *drive, struct request *rq)
{ {
idetape_tape_t *tape = drive->driver_data; idetape_tape_t *tape = drive->driver_data;
idetape_pc_t *pc = tape->pc; struct atapi_packet_command *pc = tape->pc;
idetape_ireason_reg_t ireason; idetape_ireason_reg_t ireason;
int retries = 100; int retries = 100;
ide_startstop_t startstop; ide_startstop_t startstop;
...@@ -2258,10 +2211,12 @@ static ide_startstop_t idetape_transfer_pc(struct ata_device *drive, struct requ ...@@ -2258,10 +2211,12 @@ static ide_startstop_t idetape_transfer_pc(struct ata_device *drive, struct requ
tape->cmd_start_time = jiffies; tape->cmd_start_time = jiffies;
ide_set_handler(drive, idetape_pc_intr, IDETAPE_WAIT_CMD, NULL); /* Set the interrupt routine */ ide_set_handler(drive, idetape_pc_intr, IDETAPE_WAIT_CMD, NULL); /* Set the interrupt routine */
atapi_write(drive,pc->c,12); /* Send the actual packet */ atapi_write(drive,pc->c,12); /* Send the actual packet */
return ide_started; return ide_started;
} }
static ide_startstop_t idetape_issue_packet_command(struct ata_device *drive, struct request *rq, idetape_pc_t *pc) static ide_startstop_t idetape_issue_packet_command(struct ata_device *drive,
struct request *rq, struct atapi_packet_command *pc)
{ {
idetape_tape_t *tape = drive->driver_data; idetape_tape_t *tape = drive->driver_data;
idetape_bcount_reg_t bcount; idetape_bcount_reg_t bcount;
...@@ -2277,7 +2232,7 @@ static ide_startstop_t idetape_issue_packet_command(struct ata_device *drive, st ...@@ -2277,7 +2232,7 @@ static ide_startstop_t idetape_issue_packet_command(struct ata_device *drive, st
tape->failed_pc = pc; tape->failed_pc = pc;
tape->pc = pc; /* Set the current packet command */ tape->pc = pc; /* Set the current packet command */
if (pc->retries > IDETAPE_MAX_PC_RETRIES || test_bit (PC_ABORT, &pc->flags)) { if (pc->retries > IDETAPE_MAX_PC_RETRIES || test_bit(PC_ABORT, &pc->flags)) {
/* /*
* We will "abort" retrying a packet command in case * We will "abort" retrying a packet command in case
* a legitimate error code was received (crossing a * a legitimate error code was received (crossing a
...@@ -2295,12 +2250,13 @@ static ide_startstop_t idetape_issue_packet_command(struct ata_device *drive, st ...@@ -2295,12 +2250,13 @@ static ide_startstop_t idetape_issue_packet_command(struct ata_device *drive, st
pc->error = IDETAPE_ERROR_GENERAL; /* Giving up */ pc->error = IDETAPE_ERROR_GENERAL; /* Giving up */
} }
tape->failed_pc = NULL; tape->failed_pc = NULL;
return pc->callback(drive, rq); pc->callback(drive, rq);
return ide_stopped;
} }
#if IDETAPE_DEBUG_LOG #if IDETAPE_DEBUG_LOG
if (tape->debug_level >= 2) if (tape->debug_level >= 2)
printk (KERN_INFO "ide-tape: Retry number - %d\n", pc->retries); printk (KERN_INFO "ide-tape: Retry number - %d\n", pc->retries);
#endif /* IDETAPE_DEBUG_LOG */ #endif
pc->retries++; pc->retries++;
pc->actually_transferred = 0; /* We haven't transferred any data yet */ pc->actually_transferred = 0; /* We haven't transferred any data yet */
...@@ -2328,10 +2284,10 @@ static ide_startstop_t idetape_issue_packet_command(struct ata_device *drive, st ...@@ -2328,10 +2284,10 @@ static ide_startstop_t idetape_issue_packet_command(struct ata_device *drive, st
OUT_BYTE (drive->select.all, IDE_SELECT_REG); OUT_BYTE (drive->select.all, IDE_SELECT_REG);
#ifdef CONFIG_BLK_DEV_IDEDMA #ifdef CONFIG_BLK_DEV_IDEDMA
if (dma_ok) { /* Begin DMA, if necessary */ if (dma_ok) { /* Begin DMA, if necessary */
set_bit (PC_DMA_IN_PROGRESS, &pc->flags); set_bit(PC_DMA_IN_PROGRESS, &pc->flags);
udma_start(drive, rq); udma_start(drive, rq);
} }
#endif /* CONFIG_BLK_DEV_IDEDMA */ #endif
if (test_bit(IDETAPE_DRQ_INTERRUPT, &tape->flags)) { if (test_bit(IDETAPE_DRQ_INTERRUPT, &tape->flags)) {
ide_set_handler(drive, idetape_transfer_pc, IDETAPE_WAIT_CMD, NULL); ide_set_handler(drive, idetape_transfer_pc, IDETAPE_WAIT_CMD, NULL);
OUT_BYTE(WIN_PACKETCMD, IDE_COMMAND_REG); OUT_BYTE(WIN_PACKETCMD, IDE_COMMAND_REG);
...@@ -2345,25 +2301,24 @@ static ide_startstop_t idetape_issue_packet_command(struct ata_device *drive, st ...@@ -2345,25 +2301,24 @@ static ide_startstop_t idetape_issue_packet_command(struct ata_device *drive, st
/* /*
* General packet command callback function. * General packet command callback function.
*/ */
static ide_startstop_t idetape_pc_callback(struct ata_device *drive, struct request *rq) static void idetape_pc_callback(struct ata_device *drive, struct request *rq)
{ {
idetape_tape_t *tape = drive->driver_data; idetape_tape_t *tape = drive->driver_data;
#if IDETAPE_DEBUG_LOG #if IDETAPE_DEBUG_LOG
if (tape->debug_level >= 4) if (tape->debug_level >= 4)
printk (KERN_INFO "ide-tape: Reached idetape_pc_callback\n"); printk (KERN_INFO "ide-tape: Reached idetape_pc_callback\n");
#endif /* IDETAPE_DEBUG_LOG */ #endif
idetape_end_request(drive, rq, tape->pc->error ? 0 : 1); idetape_end_request(drive, rq, tape->pc->error ? 0 : 1);
return ide_stopped;
} }
/* /*
* A mode sense command is used to "sense" tape parameters. * A mode sense command is used to "sense" tape parameters.
*/ */
static void idetape_create_mode_sense_cmd (idetape_pc_t *pc, byte page_code) static void idetape_create_mode_sense_cmd(struct atapi_packet_command *pc, byte page_code)
{ {
idetape_init_pc (pc); atapi_init_pc(pc);
pc->c[0] = IDETAPE_MODE_SENSE_CMD; pc->c[0] = IDETAPE_MODE_SENSE_CMD;
if (page_code != IDETAPE_BLOCK_DESCRIPTOR) if (page_code != IDETAPE_BLOCK_DESCRIPTOR)
pc->c[1] = 8; /* DBD = 1 - Don't return block descriptors */ pc->c[1] = 8; /* DBD = 1 - Don't return block descriptors */
...@@ -2379,7 +2334,7 @@ static void idetape_create_mode_sense_cmd (idetape_pc_t *pc, byte page_code) ...@@ -2379,7 +2334,7 @@ static void idetape_create_mode_sense_cmd (idetape_pc_t *pc, byte page_code)
pc->callback = idetape_pc_callback; pc->callback = idetape_pc_callback;
} }
static ide_startstop_t idetape_onstream_buffer_fill_callback (struct ata_device *drive, struct request *rq) static void idetape_onstream_buffer_fill_callback (struct ata_device *drive, struct request *rq)
{ {
idetape_tape_t *tape = drive->driver_data; idetape_tape_t *tape = drive->driver_data;
...@@ -2404,12 +2359,11 @@ static ide_startstop_t idetape_onstream_buffer_fill_callback (struct ata_device ...@@ -2404,12 +2359,11 @@ static ide_startstop_t idetape_onstream_buffer_fill_callback (struct ata_device
printk(KERN_INFO "ide-tape: buffer fill callback, %d/%d\n", tape->cur_frames, tape->max_frames); printk(KERN_INFO "ide-tape: buffer fill callback, %d/%d\n", tape->cur_frames, tape->max_frames);
#endif #endif
idetape_end_request(drive, rq, tape->pc->error ? 0 : 1); idetape_end_request(drive, rq, tape->pc->error ? 0 : 1);
return ide_stopped;
} }
static void idetape_queue_onstream_buffer_fill(struct ata_device *drive) static void idetape_queue_onstream_buffer_fill(struct ata_device *drive)
{ {
idetape_pc_t *pc; struct atapi_packet_command *pc;
struct request *rq; struct request *rq;
pc = idetape_next_pc_storage (drive); pc = idetape_next_pc_storage (drive);
...@@ -2467,10 +2421,10 @@ static void calculate_speeds(struct ata_device *drive) ...@@ -2467,10 +2421,10 @@ static void calculate_speeds(struct ata_device *drive)
tape->max_insert_speed = max(tape->max_insert_speed, 500); tape->max_insert_speed = max(tape->max_insert_speed, 500);
} }
static ide_startstop_t idetape_media_access_finished(struct ata_device *drive, struct request *rq) static void idetape_media_access_finished(struct ata_device *drive, struct request *rq)
{ {
idetape_tape_t *tape = drive->driver_data; idetape_tape_t *tape = drive->driver_data;
idetape_pc_t *pc = tape->pc; struct atapi_packet_command *pc = tape->pc;
idetape_status_reg_t status; idetape_status_reg_t status;
if (tape->onstream) if (tape->onstream)
...@@ -2479,7 +2433,8 @@ static ide_startstop_t idetape_media_access_finished(struct ata_device *drive, s ...@@ -2479,7 +2433,8 @@ static ide_startstop_t idetape_media_access_finished(struct ata_device *drive, s
if (status.b.dsc) { if (status.b.dsc) {
if (status.b.check) { /* Error detected */ if (status.b.check) { /* Error detected */
printk (KERN_ERR "ide-tape: %s: I/O error, ",tape->name); printk (KERN_ERR "ide-tape: %s: I/O error, ",tape->name);
return idetape_retry_pc (drive); /* Retry operation */ idetape_retry_pc(drive); /* Retry operation */
return;
} }
pc->error = 0; pc->error = 0;
if (tape->failed_pc == pc) if (tape->failed_pc == pc)
...@@ -2488,10 +2443,10 @@ static ide_startstop_t idetape_media_access_finished(struct ata_device *drive, s ...@@ -2488,10 +2443,10 @@ static ide_startstop_t idetape_media_access_finished(struct ata_device *drive, s
pc->error = IDETAPE_ERROR_GENERAL; pc->error = IDETAPE_ERROR_GENERAL;
tape->failed_pc = NULL; tape->failed_pc = NULL;
} }
return pc->callback(drive, rq); pc->callback(drive, rq);
} }
static ide_startstop_t idetape_rw_callback(struct ata_device *drive, struct request *rq) static void idetape_rw_callback(struct ata_device *drive, struct request *rq)
{ {
idetape_tape_t *tape = drive->driver_data; idetape_tape_t *tape = drive->driver_data;
int blocks = tape->pc->actually_transferred / tape->tape_block_size; int blocks = tape->pc->actually_transferred / tape->tape_block_size;
...@@ -2516,7 +2471,7 @@ static ide_startstop_t idetape_rw_callback(struct ata_device *drive, struct requ ...@@ -2516,7 +2471,7 @@ static ide_startstop_t idetape_rw_callback(struct ata_device *drive, struct requ
#if IDETAPE_DEBUG_LOG #if IDETAPE_DEBUG_LOG
if (tape->debug_level >= 4) if (tape->debug_level >= 4)
printk (KERN_INFO "ide-tape: Reached idetape_rw_callback\n"); printk (KERN_INFO "ide-tape: Reached idetape_rw_callback\n");
#endif /* IDETAPE_DEBUG_LOG */ #endif
tape->first_frame_position += blocks; tape->first_frame_position += blocks;
rq->current_nr_sectors -= blocks; rq->current_nr_sectors -= blocks;
...@@ -2525,14 +2480,15 @@ static ide_startstop_t idetape_rw_callback(struct ata_device *drive, struct requ ...@@ -2525,14 +2480,15 @@ static ide_startstop_t idetape_rw_callback(struct ata_device *drive, struct requ
idetape_end_request(drive, rq, 1); idetape_end_request(drive, rq, 1);
else else
idetape_end_request(drive, rq, tape->pc->error); idetape_end_request(drive, rq, tape->pc->error);
return ide_stopped;
} }
static void idetape_create_read_cmd (idetape_tape_t *tape, idetape_pc_t *pc, unsigned int length, struct bio *bio) static void idetape_create_read_cmd(idetape_tape_t *tape,
struct atapi_packet_command *pc,
unsigned int length, struct bio *bio)
{ {
struct bio *p = bio; struct bio *p = bio;
struct bio_vec *bv = bio_iovec(p); struct bio_vec *bv = bio_iovec(p);
idetape_init_pc (pc); atapi_init_pc(pc);
pc->c[0] = IDETAPE_READ_CMD; pc->c[0] = IDETAPE_READ_CMD;
put_unaligned (htonl (length), (unsigned int *) &pc->c[1]); put_unaligned (htonl (length), (unsigned int *) &pc->c[1]);
pc->c[1] = 1; pc->c[1] = 1;
...@@ -2549,22 +2505,24 @@ static void idetape_create_read_cmd (idetape_tape_t *tape, idetape_pc_t *pc, uns ...@@ -2549,22 +2505,24 @@ static void idetape_create_read_cmd (idetape_tape_t *tape, idetape_pc_t *pc, uns
if (!tape->onstream) { if (!tape->onstream) {
pc->request_transfer = pc->buffer_size = length * tape->tape_block_size; pc->request_transfer = pc->buffer_size = length * tape->tape_block_size;
if (pc->request_transfer == tape->stage_size) if (pc->request_transfer == tape->stage_size)
set_bit (PC_DMA_RECOMMENDED, &pc->flags); set_bit(PC_DMA_RECOMMENDED, &pc->flags);
} else { } else {
if (length) { if (length) {
pc->request_transfer = pc->buffer_size = 32768 + 512; pc->request_transfer = pc->buffer_size = 32768 + 512;
set_bit (PC_DMA_RECOMMENDED, &pc->flags); set_bit(PC_DMA_RECOMMENDED, &pc->flags);
} else } else
pc->request_transfer = 0; pc->request_transfer = 0;
} }
} }
static void idetape_create_read_buffer_cmd(idetape_tape_t *tape, idetape_pc_t *pc, unsigned int length, struct bio *bio) static void idetape_create_read_buffer_cmd(idetape_tape_t *tape,
struct atapi_packet_command *pc,
unsigned int length, struct bio *bio)
{ {
int size = 32768; int size = 32768;
struct bio *p = bio; struct bio *p = bio;
idetape_init_pc (pc); atapi_init_pc(pc);
pc->c[0] = IDETAPE_READ_BUFFER_CMD; pc->c[0] = IDETAPE_READ_BUFFER_CMD;
pc->c[1] = IDETAPE_RETRIEVE_FAULTY_BLOCK; pc->c[1] = IDETAPE_RETRIEVE_FAULTY_BLOCK;
pc->c[7] = size >> 8; pc->c[7] = size >> 8;
...@@ -2580,11 +2538,13 @@ static void idetape_create_read_buffer_cmd(idetape_tape_t *tape, idetape_pc_t *p ...@@ -2580,11 +2538,13 @@ static void idetape_create_read_buffer_cmd(idetape_tape_t *tape, idetape_pc_t *p
pc->request_transfer = pc->buffer_size = size; pc->request_transfer = pc->buffer_size = size;
} }
static void idetape_create_write_cmd (idetape_tape_t *tape, idetape_pc_t *pc, unsigned int length, struct bio *bio) static void idetape_create_write_cmd(idetape_tape_t *tape,
struct atapi_packet_command *pc,
unsigned int length, struct bio *bio)
{ {
struct bio *p = bio; struct bio *p = bio;
struct bio_vec *bv= bio_iovec(p); struct bio_vec *bv= bio_iovec(p);
idetape_init_pc (pc); atapi_init_pc(pc);
pc->c[0] = IDETAPE_WRITE_CMD; pc->c[0] = IDETAPE_WRITE_CMD;
put_unaligned (htonl (length), (unsigned int *) &pc->c[1]); put_unaligned (htonl (length), (unsigned int *) &pc->c[1]);
pc->c[1] = 1; pc->c[1] = 1;
...@@ -2619,16 +2579,16 @@ static void idetape_create_write_cmd (idetape_tape_t *tape, idetape_pc_t *pc, un ...@@ -2619,16 +2579,16 @@ static void idetape_create_write_cmd (idetape_tape_t *tape, idetape_pc_t *pc, un
static ide_startstop_t idetape_do_request(struct ata_device *drive, struct request *rq, sector_t block) static ide_startstop_t idetape_do_request(struct ata_device *drive, struct request *rq, sector_t block)
{ {
idetape_tape_t *tape = drive->driver_data; idetape_tape_t *tape = drive->driver_data;
idetape_pc_t *pc; struct atapi_packet_command *pc;
struct request *postponed_rq = tape->postponed_rq; struct request *postponed_rq = tape->postponed_rq;
idetape_status_reg_t status; idetape_status_reg_t status;
#if IDETAPE_DEBUG_LOG #if IDETAPE_DEBUG_LOG
if (tape->debug_level >= 5) /* if (tape->debug_level >= 5)
/* printk (KERN_INFO "ide-tape: rq_status: %d, rq_dev: %u, cmd: %ld, errors: %d\n",rq->rq_status,(unsigned int) rq->rq_dev,rq->flags,rq->errors); */ printk (KERN_INFO "ide-tape: rq_status: %d, rq_dev: %u, cmd: %ld, errors: %d\n",rq->rq_status,(unsigned int) rq->rq_dev,rq->flags,rq->errors); */
if (tape->debug_level >= 2) if (tape->debug_level >= 2)
printk (KERN_INFO "ide-tape: sector: %ld, nr_sectors: %ld, current_nr_sectors: %d\n",rq->sector,rq->nr_sectors,rq->current_nr_sectors); printk (KERN_INFO "ide-tape: sector: %ld, nr_sectors: %ld, current_nr_sectors: %d\n",rq->sector,rq->nr_sectors,rq->current_nr_sectors);
#endif /* IDETAPE_DEBUG_LOG */ #endif
if (!IDETAPE_RQ_CMD (rq->flags)) { if (!IDETAPE_RQ_CMD (rq->flags)) {
/* /*
...@@ -2652,7 +2612,7 @@ static ide_startstop_t idetape_do_request(struct ata_device *drive, struct reque ...@@ -2652,7 +2612,7 @@ static ide_startstop_t idetape_do_request(struct ata_device *drive, struct reque
idetape_end_request(drive, rq, 0); idetape_end_request(drive, rq, 0);
return ide_stopped; return ide_stopped;
} }
#endif /* IDETAPE_DEBUG_BUGS */ #endif
tape->postponed_rq = NULL; tape->postponed_rq = NULL;
...@@ -2788,7 +2748,8 @@ static ide_startstop_t idetape_do_request(struct ata_device *drive, struct reque ...@@ -2788,7 +2748,8 @@ static ide_startstop_t idetape_do_request(struct ata_device *drive, struct reque
idetape_end_request(drive, rq, IDETAPE_ERROR_EOD); idetape_end_request(drive, rq, IDETAPE_ERROR_EOD);
return ide_stopped; return ide_stopped;
case IDETAPE_PC_RQ1: case IDETAPE_PC_RQ1:
pc = (idetape_pc_t *) rq->buffer; /* FIXME: --mdcki */
pc = (struct atapi_packet_command *) rq->buffer;
rq->flags = IDETAPE_PC_RQ2; rq->flags = IDETAPE_PC_RQ2;
break; break;
case IDETAPE_PC_RQ2: case IDETAPE_PC_RQ2:
...@@ -2912,7 +2873,8 @@ static idetape_stage_t *idetape_kmalloc_stage (idetape_tape_t *tape) ...@@ -2912,7 +2873,8 @@ static idetape_stage_t *idetape_kmalloc_stage (idetape_tape_t *tape)
return __idetape_kmalloc_stage (tape, 0, 0); return __idetape_kmalloc_stage (tape, 0, 0);
} }
static void idetape_copy_stage_from_user (idetape_tape_t *tape, idetape_stage_t *stage, const char *buf, int n) static void idetape_copy_stage_from_user(idetape_tape_t *tape, idetape_stage_t *stage,
const char *buf, unsigned int n)
{ {
struct bio *bio = tape->bio; struct bio *bio = tape->bio;
int count; int count;
...@@ -2949,7 +2911,7 @@ static void idetape_copy_stage_to_user (idetape_tape_t *tape, char *buf, idetape ...@@ -2949,7 +2911,7 @@ static void idetape_copy_stage_to_user (idetape_tape_t *tape, char *buf, idetape
printk (KERN_ERR "ide-tape: bio == NULL in idetape_copy_stage_to_user\n"); printk (KERN_ERR "ide-tape: bio == NULL in idetape_copy_stage_to_user\n");
return; return;
} }
#endif /* IDETAPE_DEBUG_BUGS */ #endif
count = min(tape->b_count, n); count = min(tape->b_count, n);
copy_to_user (buf, tape->b_data, count); copy_to_user (buf, tape->b_data, count);
n -= count; n -= count;
...@@ -3102,7 +3064,7 @@ static void idetape_wait_for_request(struct ata_device *drive, struct request *r ...@@ -3102,7 +3064,7 @@ static void idetape_wait_for_request(struct ata_device *drive, struct request *r
spin_lock_irq(&tape->spinlock); spin_lock_irq(&tape->spinlock);
} }
static ide_startstop_t idetape_read_position_callback(struct ata_device *drive, struct request *rq) static void idetape_read_position_callback(struct ata_device *drive, struct request *rq)
{ {
idetape_tape_t *tape = drive->driver_data; idetape_tape_t *tape = drive->driver_data;
idetape_read_position_result_t *result; idetape_read_position_result_t *result;
...@@ -3110,7 +3072,7 @@ static ide_startstop_t idetape_read_position_callback(struct ata_device *drive, ...@@ -3110,7 +3072,7 @@ static ide_startstop_t idetape_read_position_callback(struct ata_device *drive,
#if IDETAPE_DEBUG_LOG #if IDETAPE_DEBUG_LOG
if (tape->debug_level >= 4) if (tape->debug_level >= 4)
printk (KERN_INFO "ide-tape: Reached idetape_read_position_callback\n"); printk (KERN_INFO "ide-tape: Reached idetape_read_position_callback\n");
#endif /* IDETAPE_DEBUG_LOG */ #endif
if (!tape->pc->error) { if (!tape->pc->error) {
result = (idetape_read_position_result_t *) tape->pc->buffer; result = (idetape_read_position_result_t *) tape->pc->buffer;
...@@ -3119,7 +3081,7 @@ static ide_startstop_t idetape_read_position_callback(struct ata_device *drive, ...@@ -3119,7 +3081,7 @@ static ide_startstop_t idetape_read_position_callback(struct ata_device *drive,
printk (KERN_INFO "ide-tape: BOP - %s\n",result->bop ? "Yes":"No"); printk (KERN_INFO "ide-tape: BOP - %s\n",result->bop ? "Yes":"No");
if (tape->debug_level >= 2) if (tape->debug_level >= 2)
printk (KERN_INFO "ide-tape: EOP - %s\n",result->eop ? "Yes":"No"); printk (KERN_INFO "ide-tape: EOP - %s\n",result->eop ? "Yes":"No");
#endif /* IDETAPE_DEBUG_LOG */ #endif
if (result->bpu) { if (result->bpu) {
printk (KERN_INFO "ide-tape: Block location is unknown to the tape\n"); printk (KERN_INFO "ide-tape: Block location is unknown to the tape\n");
clear_bit (IDETAPE_ADDRESS_VALID, &tape->flags); clear_bit (IDETAPE_ADDRESS_VALID, &tape->flags);
...@@ -3128,7 +3090,7 @@ static ide_startstop_t idetape_read_position_callback(struct ata_device *drive, ...@@ -3128,7 +3090,7 @@ static ide_startstop_t idetape_read_position_callback(struct ata_device *drive,
#if IDETAPE_DEBUG_LOG #if IDETAPE_DEBUG_LOG
if (tape->debug_level >= 2) if (tape->debug_level >= 2)
printk (KERN_INFO "ide-tape: Block Location - %u\n", ntohl (result->first_block)); printk (KERN_INFO "ide-tape: Block Location - %u\n", ntohl (result->first_block));
#endif /* IDETAPE_DEBUG_LOG */ #endif
tape->partition = result->partition; tape->partition = result->partition;
tape->first_frame_position = ntohl (result->first_block); tape->first_frame_position = ntohl (result->first_block);
tape->last_frame_position = ntohl (result->last_block); tape->last_frame_position = ntohl (result->last_block);
...@@ -3139,7 +3101,6 @@ static ide_startstop_t idetape_read_position_callback(struct ata_device *drive, ...@@ -3139,7 +3101,6 @@ static ide_startstop_t idetape_read_position_callback(struct ata_device *drive,
} else { } else {
idetape_end_request(drive, rq, 0); idetape_end_request(drive, rq, 0);
} }
return ide_stopped;
} }
/* /*
...@@ -3150,22 +3111,23 @@ static ide_startstop_t idetape_read_position_callback(struct ata_device *drive, ...@@ -3150,22 +3111,23 @@ static ide_startstop_t idetape_read_position_callback(struct ata_device *drive,
* if write_filemark=0. * if write_filemark=0.
* *
*/ */
static void idetape_create_write_filemark_cmd(struct ata_device *drive, idetape_pc_t *pc,int write_filemark) static void idetape_create_write_filemark_cmd(struct ata_device *drive,
struct atapi_packet_command *pc,int write_filemark)
{ {
idetape_tape_t *tape = drive->driver_data; idetape_tape_t *tape = drive->driver_data;
idetape_init_pc (pc); atapi_init_pc(pc);
pc->c[0] = IDETAPE_WRITE_FILEMARK_CMD; pc->c[0] = IDETAPE_WRITE_FILEMARK_CMD;
if (tape->onstream) if (tape->onstream)
pc->c[1] = 1; /* Immed bit */ pc->c[1] = 1; /* Immed bit */
pc->c[4] = write_filemark; /* not used for OnStream ?? */ pc->c[4] = write_filemark; /* not used for OnStream ?? */
set_bit (PC_WAIT_FOR_DSC, &pc->flags); set_bit(PC_WAIT_FOR_DSC, &pc->flags);
pc->callback = idetape_pc_callback; pc->callback = idetape_pc_callback;
} }
static void idetape_create_test_unit_ready_cmd(idetape_pc_t *pc) static void idetape_create_test_unit_ready_cmd(struct atapi_packet_command *pc)
{ {
idetape_init_pc(pc); atapi_init_pc(pc);
pc->c[0] = IDETAPE_TEST_UNIT_READY_CMD; pc->c[0] = IDETAPE_TEST_UNIT_READY_CMD;
pc->callback = idetape_pc_callback; pc->callback = idetape_pc_callback;
} }
...@@ -3190,21 +3152,23 @@ static void idetape_create_test_unit_ready_cmd(idetape_pc_t *pc) ...@@ -3190,21 +3152,23 @@ static void idetape_create_test_unit_ready_cmd(idetape_pc_t *pc)
* the request to the request list without waiting for it to be serviced ! * the request to the request list without waiting for it to be serviced !
* In that case, we usually use idetape_queue_pc_head. * In that case, we usually use idetape_queue_pc_head.
*/ */
static int __idetape_queue_pc_tail(struct ata_device *drive, idetape_pc_t *pc) static int __idetape_queue_pc_tail(struct ata_device *drive, struct atapi_packet_command *pc)
{ {
struct request rq; struct request rq;
ide_init_drive_cmd (&rq); ide_init_drive_cmd (&rq);
/* FIXME: --mdcki */
rq.buffer = (char *) pc; rq.buffer = (char *) pc;
rq.flags = IDETAPE_PC_RQ1; rq.flags = IDETAPE_PC_RQ1;
return ide_do_drive_cmd(drive, &rq, ide_wait); return ide_do_drive_cmd(drive, &rq, ide_wait);
} }
static void idetape_create_load_unload_cmd(struct ata_device *drive, idetape_pc_t *pc,int cmd) static void idetape_create_load_unload_cmd(struct ata_device *drive,
struct atapi_packet_command *pc, int cmd)
{ {
idetape_tape_t *tape = drive->driver_data; idetape_tape_t *tape = drive->driver_data;
idetape_init_pc (pc); atapi_init_pc(pc);
pc->c[0] = IDETAPE_LOAD_UNLOAD_CMD; pc->c[0] = IDETAPE_LOAD_UNLOAD_CMD;
pc->c[4] = cmd; pc->c[4] = cmd;
if (tape->onstream) { if (tape->onstream) {
...@@ -3219,7 +3183,7 @@ static void idetape_create_load_unload_cmd(struct ata_device *drive, idetape_pc_ ...@@ -3219,7 +3183,7 @@ static void idetape_create_load_unload_cmd(struct ata_device *drive, idetape_pc_
static int idetape_wait_ready(struct ata_device *drive, unsigned long long timeout) static int idetape_wait_ready(struct ata_device *drive, unsigned long long timeout)
{ {
idetape_tape_t *tape = drive->driver_data; idetape_tape_t *tape = drive->driver_data;
idetape_pc_t pc; struct atapi_packet_command pc;
/* /*
* Wait for the tape to become ready * Wait for the tape to become ready
...@@ -3244,7 +3208,7 @@ static int idetape_wait_ready(struct ata_device *drive, unsigned long long timeo ...@@ -3244,7 +3208,7 @@ static int idetape_wait_ready(struct ata_device *drive, unsigned long long timeo
return -EIO; return -EIO;
} }
static int idetape_queue_pc_tail(struct ata_device *drive, idetape_pc_t *pc) static int idetape_queue_pc_tail(struct ata_device *drive, struct atapi_packet_command *pc)
{ {
idetape_tape_t *tape = drive->driver_data; idetape_tape_t *tape = drive->driver_data;
int rc; int rc;
...@@ -3260,7 +3224,7 @@ static int idetape_queue_pc_tail(struct ata_device *drive, idetape_pc_t *pc) ...@@ -3260,7 +3224,7 @@ static int idetape_queue_pc_tail(struct ata_device *drive, idetape_pc_t *pc)
static int idetape_flush_tape_buffers(struct ata_device *drive) static int idetape_flush_tape_buffers(struct ata_device *drive)
{ {
idetape_pc_t pc; struct atapi_packet_command pc;
int rc; int rc;
idetape_create_write_filemark_cmd(drive, &pc, 0); idetape_create_write_filemark_cmd(drive, &pc, 0);
...@@ -3270,9 +3234,9 @@ static int idetape_flush_tape_buffers(struct ata_device *drive) ...@@ -3270,9 +3234,9 @@ static int idetape_flush_tape_buffers(struct ata_device *drive)
return 0; return 0;
} }
static void idetape_create_read_position_cmd (idetape_pc_t *pc) static void idetape_create_read_position_cmd(struct atapi_packet_command *pc)
{ {
idetape_init_pc (pc); atapi_init_pc(pc);
pc->c[0] = IDETAPE_READ_POSITION_CMD; pc->c[0] = IDETAPE_READ_POSITION_CMD;
pc->request_transfer = 20; pc->request_transfer = 20;
pc->callback = idetape_read_position_callback; pc->callback = idetape_read_position_callback;
...@@ -3281,13 +3245,13 @@ static void idetape_create_read_position_cmd (idetape_pc_t *pc) ...@@ -3281,13 +3245,13 @@ static void idetape_create_read_position_cmd (idetape_pc_t *pc)
static int idetape_read_position(struct ata_device *drive) static int idetape_read_position(struct ata_device *drive)
{ {
idetape_tape_t *tape = drive->driver_data; idetape_tape_t *tape = drive->driver_data;
idetape_pc_t pc; struct atapi_packet_command pc;
int position; int position;
#if IDETAPE_DEBUG_LOG #if IDETAPE_DEBUG_LOG
if (tape->debug_level >= 4) if (tape->debug_level >= 4)
printk (KERN_INFO "ide-tape: Reached idetape_read_position\n"); printk (KERN_INFO "ide-tape: Reached idetape_read_position\n");
#endif /* IDETAPE_DEBUG_LOG */ #endif
#ifdef NO_LONGER_REQUIRED #ifdef NO_LONGER_REQUIRED
idetape_flush_tape_buffers(drive); idetape_flush_tape_buffers(drive);
...@@ -3311,11 +3275,13 @@ static int idetape_read_position(struct ata_device *drive) ...@@ -3311,11 +3275,13 @@ static int idetape_read_position(struct ata_device *drive)
return position; return position;
} }
static void idetape_create_locate_cmd(struct ata_device *drive, idetape_pc_t *pc, unsigned int block, byte partition, int skip) static void idetape_create_locate_cmd(struct ata_device *drive,
struct atapi_packet_command *pc,
unsigned int block, u8 partition, int skip)
{ {
idetape_tape_t *tape = drive->driver_data; idetape_tape_t *tape = drive->driver_data;
idetape_init_pc (pc); atapi_init_pc(pc);
pc->c[0] = IDETAPE_LOCATE_CMD; pc->c[0] = IDETAPE_LOCATE_CMD;
if (tape->onstream) if (tape->onstream)
pc->c[1] = 1; /* Immediate bit */ pc->c[1] = 1; /* Immediate bit */
...@@ -3334,17 +3300,19 @@ static void idetape_create_locate_cmd(struct ata_device *drive, idetape_pc_t *pc ...@@ -3334,17 +3300,19 @@ static void idetape_create_locate_cmd(struct ata_device *drive, idetape_pc_t *pc
pc->callback = idetape_pc_callback; pc->callback = idetape_pc_callback;
} }
static int idetape_create_prevent_cmd(struct ata_device *drive, idetape_pc_t *pc, int prevent) static int idetape_create_prevent_cmd(struct ata_device *drive,
struct atapi_packet_command *pc, int prevent)
{ {
idetape_tape_t *tape = drive->driver_data; idetape_tape_t *tape = drive->driver_data;
if (!tape->capabilities.lock) if (!tape->capabilities.lock)
return 0; return 0;
idetape_init_pc(pc); atapi_init_pc(pc);
pc->c[0] = IDETAPE_PREVENT_CMD; pc->c[0] = IDETAPE_PREVENT_CMD;
pc->c[4] = prevent; pc->c[4] = prevent;
pc->callback = idetape_pc_callback; pc->callback = idetape_pc_callback;
return 1; return 1;
} }
...@@ -3393,7 +3361,7 @@ static int idetape_position_tape(struct ata_device *drive, unsigned int block, b ...@@ -3393,7 +3361,7 @@ static int idetape_position_tape(struct ata_device *drive, unsigned int block, b
{ {
idetape_tape_t *tape = drive->driver_data; idetape_tape_t *tape = drive->driver_data;
int retval; int retval;
idetape_pc_t pc; struct atapi_packet_command pc;
if (tape->chrdev_direction == idetape_direction_read) if (tape->chrdev_direction == idetape_direction_read)
__idetape_discard_read_pipeline(drive); __idetape_discard_read_pipeline(drive);
...@@ -3430,7 +3398,7 @@ static void idetape_discard_read_pipeline(struct ata_device *drive, int restore_ ...@@ -3430,7 +3398,7 @@ static void idetape_discard_read_pipeline(struct ata_device *drive, int restore_
static void idetape_update_stats(struct ata_device *drive) static void idetape_update_stats(struct ata_device *drive)
{ {
idetape_pc_t pc; struct atapi_packet_command pc;
idetape_create_mode_sense_cmd (&pc, IDETAPE_BUFFER_FILLING_PAGE); idetape_create_mode_sense_cmd (&pc, IDETAPE_BUFFER_FILLING_PAGE);
pc.callback = idetape_onstream_buffer_fill_callback; pc.callback = idetape_onstream_buffer_fill_callback;
...@@ -3598,30 +3566,31 @@ static void idetape_insert_pipeline_into_queue(struct ata_device *drive) ...@@ -3598,30 +3566,31 @@ static void idetape_insert_pipeline_into_queue(struct ata_device *drive)
} }
} }
static void idetape_create_inquiry_cmd (idetape_pc_t *pc) static void idetape_create_inquiry_cmd(struct atapi_packet_command *pc)
{ {
idetape_init_pc(pc); atapi_init_pc(pc);
pc->c[0] = IDETAPE_INQUIRY_CMD; pc->c[0] = IDETAPE_INQUIRY_CMD;
pc->c[4] = pc->request_transfer = 254; pc->c[4] = pc->request_transfer = 254;
pc->callback = idetape_pc_callback; pc->callback = idetape_pc_callback;
} }
static void idetape_create_rewind_cmd(struct ata_device *drive, idetape_pc_t *pc) static void idetape_create_rewind_cmd(struct ata_device *drive,
struct atapi_packet_command *pc)
{ {
idetape_tape_t *tape = drive->driver_data; idetape_tape_t *tape = drive->driver_data;
idetape_init_pc (pc); atapi_init_pc(pc);
pc->c[0] = IDETAPE_REWIND_CMD; pc->c[0] = IDETAPE_REWIND_CMD;
if (tape->onstream) if (tape->onstream)
pc->c[1] = 1; pc->c[1] = 1;
set_bit (PC_WAIT_FOR_DSC, &pc->flags); set_bit(PC_WAIT_FOR_DSC, &pc->flags);
pc->callback = idetape_pc_callback; pc->callback = idetape_pc_callback;
} }
static void idetape_create_mode_select_cmd (idetape_pc_t *pc, int length) static void idetape_create_mode_select_cmd(struct atapi_packet_command *pc, int length)
{ {
idetape_init_pc (pc); atapi_init_pc(pc);
set_bit (PC_WRITING, &pc->flags); set_bit(PC_WRITING, &pc->flags);
pc->c[0] = IDETAPE_MODE_SELECT_CMD; pc->c[0] = IDETAPE_MODE_SELECT_CMD;
pc->c[1] = 0x10; pc->c[1] = 0x10;
put_unaligned (htons(length), (unsigned short *) &pc->c[3]); put_unaligned (htons(length), (unsigned short *) &pc->c[3]);
...@@ -3629,22 +3598,22 @@ static void idetape_create_mode_select_cmd (idetape_pc_t *pc, int length) ...@@ -3629,22 +3598,22 @@ static void idetape_create_mode_select_cmd (idetape_pc_t *pc, int length)
pc->callback = idetape_pc_callback; pc->callback = idetape_pc_callback;
} }
static void idetape_create_erase_cmd (idetape_pc_t *pc) static void idetape_create_erase_cmd(struct atapi_packet_command *pc)
{ {
idetape_init_pc (pc); atapi_init_pc(pc);
pc->c[0] = IDETAPE_ERASE_CMD; pc->c[0] = IDETAPE_ERASE_CMD;
pc->c[1] = 1; pc->c[1] = 1;
set_bit (PC_WAIT_FOR_DSC, &pc->flags); set_bit(PC_WAIT_FOR_DSC, &pc->flags);
pc->callback = idetape_pc_callback; pc->callback = idetape_pc_callback;
} }
static void idetape_create_space_cmd (idetape_pc_t *pc,int count,byte cmd) static void idetape_create_space_cmd(struct atapi_packet_command *pc, int count, u8 cmd)
{ {
idetape_init_pc (pc); atapi_init_pc(pc);
pc->c[0] = IDETAPE_SPACE_CMD; pc->c[0] = IDETAPE_SPACE_CMD;
put_unaligned (htonl (count), (unsigned int *) &pc->c[1]); put_unaligned (htonl (count), (unsigned int *) &pc->c[1]);
pc->c[1] = cmd; pc->c[1] = cmd;
set_bit (PC_WAIT_FOR_DSC, &pc->flags); set_bit(PC_WAIT_FOR_DSC, &pc->flags);
pc->callback = &idetape_pc_callback; pc->callback = &idetape_pc_callback;
} }
...@@ -3853,7 +3822,7 @@ static void idetape_wait_for_pipeline(struct ata_device *drive) ...@@ -3853,7 +3822,7 @@ static void idetape_wait_for_pipeline(struct ata_device *drive)
static void idetape_empty_write_pipeline(struct ata_device *drive) static void idetape_empty_write_pipeline(struct ata_device *drive)
{ {
idetape_tape_t *tape = drive->driver_data; idetape_tape_t *tape = drive->driver_data;
int blocks, i, min; int blocks, min;
struct bio *bio; struct bio *bio;
#if IDETAPE_DEBUG_BUGS #if IDETAPE_DEBUG_BUGS
...@@ -3865,10 +3834,12 @@ static void idetape_empty_write_pipeline(struct ata_device *drive) ...@@ -3865,10 +3834,12 @@ static void idetape_empty_write_pipeline(struct ata_device *drive)
printk (KERN_ERR "ide-tape: bug: merge_buffer too big\n"); printk (KERN_ERR "ide-tape: bug: merge_buffer too big\n");
tape->merge_stage_size = tape->stage_size; tape->merge_stage_size = tape->stage_size;
} }
#endif /* IDETAPE_DEBUG_BUGS */ #endif
if (tape->merge_stage_size) { if (tape->merge_stage_size) {
blocks = tape->merge_stage_size / tape->tape_block_size; blocks = tape->merge_stage_size / tape->tape_block_size;
if (tape->merge_stage_size % tape->tape_block_size) { if (tape->merge_stage_size % tape->tape_block_size) {
unsigned int i;
blocks++; blocks++;
i = tape->tape_block_size - tape->merge_stage_size % tape->tape_block_size; i = tape->tape_block_size - tape->merge_stage_size % tape->tape_block_size;
bio = tape->bio->bi_next; bio = tape->bio->bi_next;
...@@ -4149,9 +4120,11 @@ static void idetape_pad_zeros(struct ata_device *drive, int bcount) ...@@ -4149,9 +4120,11 @@ static void idetape_pad_zeros(struct ata_device *drive, int bcount)
{ {
idetape_tape_t *tape = drive->driver_data; idetape_tape_t *tape = drive->driver_data;
struct bio *bio; struct bio *bio;
int count, blocks; int blocks;
while (bcount) { while (bcount) {
unsigned int count;
bio = tape->merge_stage->bio; bio = tape->merge_stage->bio;
count = min(tape->stage_size, bcount); count = min(tape->stage_size, bcount);
bcount -= count; bcount -= count;
...@@ -4194,7 +4167,7 @@ static int idetape_pipeline_size(struct ata_device *drive) ...@@ -4194,7 +4167,7 @@ static int idetape_pipeline_size(struct ata_device *drive)
static int idetape_rewind_tape(struct ata_device *drive) static int idetape_rewind_tape(struct ata_device *drive)
{ {
int retval; int retval;
idetape_pc_t pc; struct atapi_packet_command pc;
idetape_tape_t *tape = drive->driver_data; idetape_tape_t *tape = drive->driver_data;
#if IDETAPE_DEBUG_LOG #if IDETAPE_DEBUG_LOG
if (tape->debug_level >= 2) if (tape->debug_level >= 2)
...@@ -4458,7 +4431,7 @@ static int idetape_onstream_space_over_filemarks_forward_fast(struct ata_device ...@@ -4458,7 +4431,7 @@ static int idetape_onstream_space_over_filemarks_forward_fast(struct ata_device
static int idetape_space_over_filemarks(struct ata_device *drive,short mt_op,int mt_count) static int idetape_space_over_filemarks(struct ata_device *drive,short mt_op,int mt_count)
{ {
idetape_tape_t *tape = drive->driver_data; idetape_tape_t *tape = drive->driver_data;
idetape_pc_t pc; struct atapi_packet_command pc;
unsigned long flags; unsigned long flags;
int retval,count=0; int retval,count=0;
int speed_control; int speed_control;
...@@ -4774,7 +4747,7 @@ static void idetape_write_header(struct ata_device *drive, int locate_eod) ...@@ -4774,7 +4747,7 @@ static void idetape_write_header(struct ata_device *drive, int locate_eod)
} }
} }
static ssize_t idetape_chrdev_write (struct file *file, const char *buf, static ssize_t idetape_chrdev_write(struct file *file, const char *buf,
size_t count, loff_t *ppos) size_t count, loff_t *ppos)
{ {
struct inode *inode = file->f_dentry->d_inode; struct inode *inode = file->f_dentry->d_inode;
...@@ -4791,7 +4764,7 @@ static ssize_t idetape_chrdev_write (struct file *file, const char *buf, ...@@ -4791,7 +4764,7 @@ static ssize_t idetape_chrdev_write (struct file *file, const char *buf,
#if IDETAPE_DEBUG_LOG #if IDETAPE_DEBUG_LOG
if (tape->debug_level >= 3) if (tape->debug_level >= 3)
printk (KERN_INFO "ide-tape: Reached idetape_chrdev_write, count %Zd\n", count); printk (KERN_INFO "ide-tape: Reached idetape_chrdev_write, count %Zd\n", count);
#endif /* IDETAPE_DEBUG_LOG */ #endif
if (tape->onstream) { if (tape->onstream) {
if (count != tape->tape_block_size) { if (count != tape->tape_block_size) {
...@@ -4821,7 +4794,7 @@ static ssize_t idetape_chrdev_write (struct file *file, const char *buf, ...@@ -4821,7 +4794,7 @@ static ssize_t idetape_chrdev_write (struct file *file, const char *buf,
printk (KERN_ERR "ide-tape: merge_stage_size should be 0 now\n"); printk (KERN_ERR "ide-tape: merge_stage_size should be 0 now\n");
tape->merge_stage_size = 0; tape->merge_stage_size = 0;
} }
#endif /* IDETAPE_DEBUG_BUGS */ #endif
if ((tape->merge_stage = __idetape_kmalloc_stage (tape, 0, 0)) == NULL) if ((tape->merge_stage = __idetape_kmalloc_stage (tape, 0, 0)) == NULL)
return -ENOMEM; return -ENOMEM;
tape->chrdev_direction = idetape_direction_write; tape->chrdev_direction = idetape_direction_write;
...@@ -4918,7 +4891,7 @@ static int idetape_write_filemark(struct ata_device *drive) ...@@ -4918,7 +4891,7 @@ static int idetape_write_filemark(struct ata_device *drive)
{ {
idetape_tape_t *tape = drive->driver_data; idetape_tape_t *tape = drive->driver_data;
int last_mark_addr; int last_mark_addr;
idetape_pc_t pc; struct atapi_packet_command pc;
if (!tape->onstream) { if (!tape->onstream) {
idetape_create_write_filemark_cmd(drive, &pc, 1); /* Write a filemark */ idetape_create_write_filemark_cmd(drive, &pc, 1); /* Write a filemark */
...@@ -5064,7 +5037,7 @@ int idetape_seek_logical_blk(struct ata_device *drive, int logical_blk_num) ...@@ -5064,7 +5037,7 @@ int idetape_seek_logical_blk(struct ata_device *drive, int logical_blk_num)
static int idetape_mtioctop(struct ata_device *drive,short mt_op,int mt_count) static int idetape_mtioctop(struct ata_device *drive,short mt_op,int mt_count)
{ {
idetape_tape_t *tape = drive->driver_data; idetape_tape_t *tape = drive->driver_data;
idetape_pc_t pc; struct atapi_packet_command pc;
int i,retval; int i,retval;
#if IDETAPE_DEBUG_LOG #if IDETAPE_DEBUG_LOG
...@@ -5403,7 +5376,7 @@ static int idetape_chrdev_open (struct inode *inode, struct file *filp) ...@@ -5403,7 +5376,7 @@ static int idetape_chrdev_open (struct inode *inode, struct file *filp)
{ {
struct ata_device *drive; struct ata_device *drive;
idetape_tape_t *tape; idetape_tape_t *tape;
idetape_pc_t pc; struct atapi_packet_command pc;
unsigned int minor=minor(inode->i_rdev); unsigned int minor=minor(inode->i_rdev);
#if IDETAPE_DEBUG_LOG #if IDETAPE_DEBUG_LOG
...@@ -5486,7 +5459,7 @@ static int idetape_chrdev_release (struct inode *inode, struct file *filp) ...@@ -5486,7 +5459,7 @@ static int idetape_chrdev_release (struct inode *inode, struct file *filp)
{ {
struct ata_device *drive = get_drive_ptr (inode->i_rdev); struct ata_device *drive = get_drive_ptr (inode->i_rdev);
idetape_tape_t *tape; idetape_tape_t *tape;
idetape_pc_t pc; struct atapi_packet_command pc;
unsigned int minor=minor(inode->i_rdev); unsigned int minor=minor(inode->i_rdev);
tape = drive->driver_data; tape = drive->driver_data;
...@@ -5655,7 +5628,7 @@ static int idetape_identify_device(struct ata_device *drive,struct hd_driveid *i ...@@ -5655,7 +5628,7 @@ static int idetape_identify_device(struct ata_device *drive,struct hd_driveid *i
*/ */
static void idetape_onstream_set_vendor(struct ata_device *drive, char *vendor) static void idetape_onstream_set_vendor(struct ata_device *drive, char *vendor)
{ {
idetape_pc_t pc; struct atapi_packet_command pc;
idetape_mode_parameter_header_t *header; idetape_mode_parameter_header_t *header;
idetape_create_mode_select_cmd(&pc, sizeof(*header) + 8); idetape_create_mode_select_cmd(&pc, sizeof(*header) + 8);
...@@ -5682,7 +5655,7 @@ static void idetape_onstream_set_vendor(struct ata_device *drive, char *vendor) ...@@ -5682,7 +5655,7 @@ static void idetape_onstream_set_vendor(struct ata_device *drive, char *vendor)
#if ONSTREAM_DEBUG #if ONSTREAM_DEBUG
static void idetape_onstream_set_retries(struct ata_device *drive, int retries) static void idetape_onstream_set_retries(struct ata_device *drive, int retries)
{ {
idetape_pc_t pc; struct atapi_packet_command pc;
idetape_create_mode_select_cmd(&pc, sizeof(idetape_mode_parameter_header_t) + 4); idetape_create_mode_select_cmd(&pc, sizeof(idetape_mode_parameter_header_t) + 4);
pc.buffer[0] = 3 + 4; pc.buffer[0] = 3 + 4;
...@@ -5703,7 +5676,7 @@ static void idetape_onstream_set_retries(struct ata_device *drive, int retries) ...@@ -5703,7 +5676,7 @@ static void idetape_onstream_set_retries(struct ata_device *drive, int retries)
*/ */
static void idetape_onstream_configure_block_size(struct ata_device *drive) static void idetape_onstream_configure_block_size(struct ata_device *drive)
{ {
idetape_pc_t pc; struct atapi_packet_command pc;
idetape_mode_parameter_header_t *header; idetape_mode_parameter_header_t *header;
idetape_block_size_page_t *bs; idetape_block_size_page_t *bs;
...@@ -5751,7 +5724,7 @@ static void idetape_get_inquiry_results(struct ata_device *drive) ...@@ -5751,7 +5724,7 @@ static void idetape_get_inquiry_results(struct ata_device *drive)
{ {
char *r; char *r;
idetape_tape_t *tape = drive->driver_data; idetape_tape_t *tape = drive->driver_data;
idetape_pc_t pc; struct atapi_packet_command pc;
idetape_inquiry_result_t *inquiry; idetape_inquiry_result_t *inquiry;
idetape_create_inquiry_cmd(&pc); idetape_create_inquiry_cmd(&pc);
...@@ -5804,7 +5777,7 @@ static void idetape_configure_onstream(struct ata_device *drive) ...@@ -5804,7 +5777,7 @@ static void idetape_configure_onstream(struct ata_device *drive)
static void idetape_onstream_mode_sense_tape_parameter_page(struct ata_device *drive, int debug) static void idetape_onstream_mode_sense_tape_parameter_page(struct ata_device *drive, int debug)
{ {
idetape_tape_t *tape = drive->driver_data; idetape_tape_t *tape = drive->driver_data;
idetape_pc_t pc; struct atapi_packet_command pc;
idetape_mode_parameter_header_t *header; idetape_mode_parameter_header_t *header;
onstream_tape_paramtr_page_t *prm; onstream_tape_paramtr_page_t *prm;
...@@ -5833,7 +5806,7 @@ static void idetape_onstream_mode_sense_tape_parameter_page(struct ata_device *d ...@@ -5833,7 +5806,7 @@ static void idetape_onstream_mode_sense_tape_parameter_page(struct ata_device *d
static void idetape_get_mode_sense_results(struct ata_device *drive) static void idetape_get_mode_sense_results(struct ata_device *drive)
{ {
idetape_tape_t *tape = drive->driver_data; idetape_tape_t *tape = drive->driver_data;
idetape_pc_t pc; struct atapi_packet_command pc;
idetape_mode_parameter_header_t *header; idetape_mode_parameter_header_t *header;
idetape_capabilities_page_t *capabilities; idetape_capabilities_page_t *capabilities;
...@@ -5908,7 +5881,7 @@ static void idetape_get_blocksize_from_block_descriptor(struct ata_device *drive ...@@ -5908,7 +5881,7 @@ static void idetape_get_blocksize_from_block_descriptor(struct ata_device *drive
{ {
idetape_tape_t *tape = drive->driver_data; idetape_tape_t *tape = drive->driver_data;
idetape_pc_t pc; struct atapi_packet_command pc;
idetape_mode_parameter_header_t *header; idetape_mode_parameter_header_t *header;
idetape_parameter_block_descriptor_t *block_descrp; idetape_parameter_block_descriptor_t *block_descrp;
...@@ -5943,7 +5916,8 @@ static void idetape_get_blocksize_from_block_descriptor(struct ata_device *drive ...@@ -5943,7 +5916,8 @@ static void idetape_get_blocksize_from_block_descriptor(struct ata_device *drive
*/ */
static void idetape_setup(struct ata_device *drive, idetape_tape_t *tape, int minor) static void idetape_setup(struct ata_device *drive, idetape_tape_t *tape, int minor)
{ {
unsigned long t1, tmid, tn, t; unsigned long t1, tmid, tn;
unsigned long t;
int speed; int speed;
struct idetape_id_gcw gcw; struct idetape_id_gcw gcw;
int stage_size; int stage_size;
...@@ -6035,7 +6009,8 @@ static void idetape_setup(struct ata_device *drive, idetape_tape_t *tape, int mi ...@@ -6035,7 +6009,8 @@ static void idetape_setup(struct ata_device *drive, idetape_tape_t *tape, int mi
* Ensure that the number we got makes sense; limit * Ensure that the number we got makes sense; limit
* it within IDETAPE_DSC_RW_MIN and IDETAPE_DSC_RW_MAX. * it within IDETAPE_DSC_RW_MIN and IDETAPE_DSC_RW_MAX.
*/ */
tape->best_dsc_rw_frequency = max(min(t, IDETAPE_DSC_RW_MAX), IDETAPE_DSC_RW_MIN); tape->best_dsc_rw_frequency = max(min(t, (unsigned long) IDETAPE_DSC_RW_MAX),
(unsigned long) IDETAPE_DSC_RW_MIN);
printk (KERN_INFO "ide-tape: %s <-> %s: %dKBps, %d*%dkB buffer, %dkB pipeline, %lums tDSC%s\n", printk (KERN_INFO "ide-tape: %s <-> %s: %dKBps, %d*%dkB buffer, %dkB pipeline, %lums tDSC%s\n",
drive->name, tape->name, tape->capabilities.speed, (tape->capabilities.buffer_size * 512) / tape->stage_size, drive->name, tape->name, tape->capabilities.speed, (tape->capabilities.buffer_size * 512) / tape->stage_size,
tape->stage_size / 1024, tape->max_stages * tape->stage_size / 1024, tape->stage_size / 1024, tape->max_stages * tape->stage_size / 1024,
......
...@@ -42,6 +42,7 @@ ...@@ -42,6 +42,7 @@
#include <linux/hdreg.h> #include <linux/hdreg.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/ide.h> #include <linux/ide.h>
#include <linux/atapi.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/bitops.h> #include <asm/bitops.h>
...@@ -54,21 +55,6 @@ ...@@ -54,21 +55,6 @@
#define IDESCSI_DEBUG_LOG 0 #define IDESCSI_DEBUG_LOG 0
typedef struct idescsi_pc_s {
u8 c[12]; /* Actual packet bytes */
int request_transfer; /* Bytes to transfer */
int actually_transferred; /* Bytes actually transferred */
int buffer_size; /* Size of our data buffer */
byte *buffer; /* Data buffer */
byte *current_position; /* Pointer into the above buffer */
struct scatterlist *sg; /* Scatter gather table */
int b_count; /* Bytes transferred from current entry */
Scsi_Cmnd *scsi_cmd; /* SCSI command */
void (*done)(Scsi_Cmnd *); /* Scsi completion routine */
unsigned long flags; /* Status/Action flags */
unsigned long timeout; /* Command timeout */
} idescsi_pc_t;
/* /*
* Packet command status bits. * Packet command status bits.
*/ */
...@@ -88,8 +74,8 @@ typedef struct idescsi_pc_s { ...@@ -88,8 +74,8 @@ typedef struct idescsi_pc_s {
#define IDESCSI_LOG_CMD 0 /* Log SCSI commands */ #define IDESCSI_LOG_CMD 0 /* Log SCSI commands */
typedef struct { typedef struct {
ide_drive_t *drive; struct ata_device *drive;
idescsi_pc_t *pc; /* Current packet command */ struct atapi_packet_command *pc; /* Current packet command */
unsigned long flags; /* Status/Action flags */ unsigned long flags; /* Status/Action flags */
unsigned long transform; /* SCSI cmd translation layer */ unsigned long transform; /* SCSI cmd translation layer */
unsigned long log; /* log flags */ unsigned long log; /* log flags */
...@@ -111,61 +97,49 @@ typedef struct { ...@@ -111,61 +97,49 @@ typedef struct {
#define IDESCSI_IREASON_COD 0x1 /* Information transferred is command */ #define IDESCSI_IREASON_COD 0x1 /* Information transferred is command */
#define IDESCSI_IREASON_IO 0x2 /* The device requests us to read */ #define IDESCSI_IREASON_IO 0x2 /* The device requests us to read */
static void idescsi_discard_data (ide_drive_t *drive, unsigned int bcount)
{
while (bcount--)
IN_BYTE (IDE_DATA_REG);
}
static void idescsi_output_zeros (ide_drive_t *drive, unsigned int bcount)
{
while (bcount--)
OUT_BYTE (0, IDE_DATA_REG);
}
/* /*
* PIO data transfer routines using the scatter gather table. * PIO data transfer routines using the scatter gather table.
*/ */
static void idescsi_input_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsigned int bcount) static void idescsi_input_buffers(struct ata_device *drive, struct atapi_packet_command *pc, unsigned int bcount)
{ {
int count; int count;
char *buf; char *buf;
while (bcount) { while (bcount) {
if (pc->sg - (struct scatterlist *) pc->scsi_cmd->request_buffer > pc->scsi_cmd->use_sg) { if (pc->s.sg - (struct scatterlist *) pc->s.scsi_cmd->request_buffer > pc->s.scsi_cmd->use_sg) {
printk (KERN_ERR "ide-scsi: scatter gather table too small, discarding data\n"); printk (KERN_ERR "ide-scsi: scatter gather table too small, discarding data\n");
idescsi_discard_data (drive, bcount); atapi_discard_data(drive, bcount);
return; return;
} }
count = min(pc->sg->length - pc->b_count, bcount); count = min(pc->s.sg->length - pc->s.b_count, bcount);
buf = page_address(pc->sg->page) + pc->sg->offset; buf = page_address(pc->s.sg->page) + pc->s.sg->offset;
atapi_read(drive, buf + pc->b_count, count); atapi_read(drive, buf + pc->s.b_count, count);
bcount -= count; pc->b_count += count; bcount -= count; pc->s.b_count += count;
if (pc->b_count == pc->sg->length) { if (pc->s.b_count == pc->s.sg->length) {
pc->sg++; pc->s.sg++;
pc->b_count = 0; pc->s.b_count = 0;
} }
} }
} }
static void idescsi_output_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsigned int bcount) static void idescsi_output_buffers(struct ata_device *drive, struct atapi_packet_command *pc, unsigned int bcount)
{ {
int count; int count;
char *buf; char *buf;
while (bcount) { while (bcount) {
if (pc->sg - (struct scatterlist *) pc->scsi_cmd->request_buffer > pc->scsi_cmd->use_sg) { if (pc->s.sg - (struct scatterlist *) pc->s.scsi_cmd->request_buffer > pc->s.scsi_cmd->use_sg) {
printk (KERN_ERR "ide-scsi: scatter gather table too small, padding with zeros\n"); printk (KERN_ERR "ide-scsi: scatter gather table too small, padding with zeros\n");
idescsi_output_zeros (drive, bcount); atapi_write_zeros(drive, bcount);
return; return;
} }
count = min(pc->sg->length - pc->b_count, bcount); count = min(pc->s.sg->length - pc->s.b_count, bcount);
buf = page_address(pc->sg->page) + pc->sg->offset; buf = page_address(pc->s.sg->page) + pc->s.sg->offset;
atapi_write(drive, buf + pc->b_count, count); atapi_write(drive, buf + pc->s.b_count, count);
bcount -= count; pc->b_count += count; bcount -= count; pc->s.b_count += count;
if (pc->b_count == pc->sg->length) { if (pc->s.b_count == pc->s.sg->length) {
pc->sg++; pc->s.sg++;
pc->b_count = 0; pc->s.b_count = 0;
} }
} }
} }
...@@ -174,9 +148,11 @@ static void idescsi_output_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsign ...@@ -174,9 +148,11 @@ static void idescsi_output_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsign
* Most of the SCSI commands are supported directly by ATAPI devices. * Most of the SCSI commands are supported directly by ATAPI devices.
* idescsi_transform_pc handles the few exceptions. * idescsi_transform_pc handles the few exceptions.
*/ */
static inline void idescsi_transform_pc1 (ide_drive_t *drive, idescsi_pc_t *pc) static inline void idescsi_transform_pc1(struct ata_device *drive, struct atapi_packet_command *pc)
{ {
u8 *c = pc->c, *scsi_buf = pc->buffer, *sc = pc->scsi_cmd->cmnd; u8 *c = pc->c;
char *scsi_buf = pc->buffer;
u8 *sc = pc->s.scsi_cmd->cmnd;
char *atapi_buf; char *atapi_buf;
if (!test_bit(PC_TRANSFORM, &pc->flags)) if (!test_bit(PC_TRANSFORM, &pc->flags))
...@@ -212,11 +188,11 @@ static inline void idescsi_transform_pc1 (ide_drive_t *drive, idescsi_pc_t *pc) ...@@ -212,11 +188,11 @@ static inline void idescsi_transform_pc1 (ide_drive_t *drive, idescsi_pc_t *pc)
} }
} }
static inline void idescsi_transform_pc2 (ide_drive_t *drive, idescsi_pc_t *pc) static inline void idescsi_transform_pc2(struct ata_device *drive, struct atapi_packet_command *pc)
{ {
u8 *atapi_buf = pc->buffer; u8 *atapi_buf = pc->buffer;
u8 *sc = pc->scsi_cmd->cmnd; u8 *sc = pc->s.scsi_cmd->cmnd;
u8 *scsi_buf = pc->scsi_cmd->request_buffer; u8 *scsi_buf = pc->s.scsi_cmd->request_buffer;
if (!test_bit(PC_TRANSFORM, &pc->flags)) if (!test_bit(PC_TRANSFORM, &pc->flags))
return; return;
...@@ -261,7 +237,7 @@ static void hexdump(u8 *x, int len) ...@@ -261,7 +237,7 @@ static void hexdump(u8 *x, int len)
static int idescsi_end_request(struct ata_device *drive, struct request *rq, int uptodate) static int idescsi_end_request(struct ata_device *drive, struct request *rq, int uptodate)
{ {
idescsi_scsi_t *scsi = drive->driver_data; idescsi_scsi_t *scsi = drive->driver_data;
idescsi_pc_t *pc = (idescsi_pc_t *) rq->special; struct atapi_packet_command *pc = (struct atapi_packet_command *) rq->special;
int log = test_bit(IDESCSI_LOG_CMD, &scsi->log); int log = test_bit(IDESCSI_LOG_CMD, &scsi->log);
struct Scsi_Host *host; struct Scsi_Host *host;
u8 *scsi_buf; u8 *scsi_buf;
...@@ -273,28 +249,28 @@ static int idescsi_end_request(struct ata_device *drive, struct request *rq, int ...@@ -273,28 +249,28 @@ static int idescsi_end_request(struct ata_device *drive, struct request *rq, int
} }
ide_end_drive_cmd(drive, rq, 0, 0); ide_end_drive_cmd(drive, rq, 0, 0);
if (rq->errors >= ERROR_MAX) { if (rq->errors >= ERROR_MAX) {
pc->scsi_cmd->result = DID_ERROR << 16; pc->s.scsi_cmd->result = DID_ERROR << 16;
if (log) if (log)
printk ("ide-scsi: %s: I/O error for %lu\n", drive->name, pc->scsi_cmd->serial_number); printk ("ide-scsi: %s: I/O error for %lu\n", drive->name, pc->s.scsi_cmd->serial_number);
} else if (rq->errors) { } else if (rq->errors) {
pc->scsi_cmd->result = (CHECK_CONDITION << 1) | (DID_OK << 16); pc->s.scsi_cmd->result = (CHECK_CONDITION << 1) | (DID_OK << 16);
if (log) if (log)
printk ("ide-scsi: %s: check condition for %lu\n", drive->name, pc->scsi_cmd->serial_number); printk ("ide-scsi: %s: check condition for %lu\n", drive->name, pc->s.scsi_cmd->serial_number);
} else { } else {
pc->scsi_cmd->result = DID_OK << 16; pc->s.scsi_cmd->result = DID_OK << 16;
idescsi_transform_pc2 (drive, pc); idescsi_transform_pc2 (drive, pc);
if (log) { if (log) {
printk ("ide-scsi: %s: suc %lu", drive->name, pc->scsi_cmd->serial_number); printk ("ide-scsi: %s: suc %lu", drive->name, pc->s.scsi_cmd->serial_number);
if (!test_bit(PC_WRITING, &pc->flags) && pc->actually_transferred && pc->actually_transferred <= 1024 && pc->buffer) { if (!test_bit(PC_WRITING, &pc->flags) && pc->actually_transferred && pc->actually_transferred <= 1024 && pc->buffer) {
printk(", rst = "); printk(", rst = ");
scsi_buf = pc->scsi_cmd->request_buffer; scsi_buf = pc->s.scsi_cmd->request_buffer;
hexdump(scsi_buf, min(16U, pc->scsi_cmd->request_bufflen)); hexdump(scsi_buf, min(16U, pc->s.scsi_cmd->request_bufflen));
} else printk("\n"); } else printk("\n");
} }
} }
host = pc->scsi_cmd->host; host = pc->s.scsi_cmd->host;
spin_lock_irqsave(host->host_lock, flags); spin_lock_irqsave(host->host_lock, flags);
pc->done(pc->scsi_cmd); pc->s.done(pc->s.scsi_cmd);
spin_unlock_irqrestore(host->host_lock, flags); spin_unlock_irqrestore(host->host_lock, flags);
idescsi_free_bio (rq->bio); idescsi_free_bio (rq->bio);
kfree(pc); kfree(rq); kfree(pc); kfree(rq);
...@@ -303,9 +279,9 @@ static int idescsi_end_request(struct ata_device *drive, struct request *rq, int ...@@ -303,9 +279,9 @@ static int idescsi_end_request(struct ata_device *drive, struct request *rq, int
return 0; return 0;
} }
static inline unsigned long get_timeout(idescsi_pc_t *pc) static inline unsigned long get_timeout(struct atapi_packet_command *pc)
{ {
return max((unsigned long) WAIT_CMD, pc->timeout - jiffies); return max((unsigned long) WAIT_CMD, pc->s.timeout - jiffies);
} }
/* /*
...@@ -316,17 +292,17 @@ static ide_startstop_t idescsi_pc_intr(struct ata_device *drive, struct request ...@@ -316,17 +292,17 @@ static ide_startstop_t idescsi_pc_intr(struct ata_device *drive, struct request
idescsi_scsi_t *scsi = drive->driver_data; idescsi_scsi_t *scsi = drive->driver_data;
byte status, ireason; byte status, ireason;
int bcount; int bcount;
idescsi_pc_t *pc=scsi->pc; struct atapi_packet_command *pc = scsi->pc;
unsigned int temp; unsigned int temp;
#if IDESCSI_DEBUG_LOG #if IDESCSI_DEBUG_LOG
printk (KERN_INFO "ide-scsi: Reached idescsi_pc_intr interrupt handler\n"); printk (KERN_INFO "ide-scsi: Reached idescsi_pc_intr interrupt handler\n");
#endif /* IDESCSI_DEBUG_LOG */ #endif
if (test_and_clear_bit (PC_DMA_IN_PROGRESS, &pc->flags)) { if (test_and_clear_bit(PC_DMA_IN_PROGRESS, &pc->flags)) {
#if IDESCSI_DEBUG_LOG #if IDESCSI_DEBUG_LOG
printk ("ide-scsi: %s: DMA complete\n", drive->name); printk ("ide-scsi: %s: DMA complete\n", drive->name);
#endif /* IDESCSI_DEBUG_LOG */ #endif
pc->actually_transferred=pc->request_transfer; pc->actually_transferred=pc->request_transfer;
udma_stop(drive); udma_stop(drive);
} }
...@@ -357,7 +333,7 @@ static ide_startstop_t idescsi_pc_intr(struct ata_device *drive, struct request ...@@ -357,7 +333,7 @@ static ide_startstop_t idescsi_pc_intr(struct ata_device *drive, struct request
temp = pc->buffer_size - pc->actually_transferred; temp = pc->buffer_size - pc->actually_transferred;
if (temp) { if (temp) {
clear_bit(PC_WRITING, &pc->flags); clear_bit(PC_WRITING, &pc->flags);
if (pc->sg) if (pc->s.sg)
idescsi_input_buffers(drive, pc, temp); idescsi_input_buffers(drive, pc, temp);
else else
atapi_read(drive, pc->current_position, temp); atapi_read(drive, pc->current_position, temp);
...@@ -365,24 +341,24 @@ static ide_startstop_t idescsi_pc_intr(struct ata_device *drive, struct request ...@@ -365,24 +341,24 @@ static ide_startstop_t idescsi_pc_intr(struct ata_device *drive, struct request
} }
pc->actually_transferred += temp; pc->actually_transferred += temp;
pc->current_position += temp; pc->current_position += temp;
idescsi_discard_data (drive,bcount - temp); atapi_discard_data(drive,bcount - temp);
ide_set_handler(drive, idescsi_pc_intr, get_timeout(pc), NULL); ide_set_handler(drive, idescsi_pc_intr, get_timeout(pc), NULL);
return ide_started; return ide_started;
} }
#if IDESCSI_DEBUG_LOG #if IDESCSI_DEBUG_LOG
printk (KERN_NOTICE "ide-scsi: The scsi wants to send us more data than expected - allowing transfer\n"); printk (KERN_NOTICE "ide-scsi: The scsi wants to send us more data than expected - allowing transfer\n");
#endif /* IDESCSI_DEBUG_LOG */ #endif
} }
} }
if (ireason & IDESCSI_IREASON_IO) { if (ireason & IDESCSI_IREASON_IO) {
clear_bit(PC_WRITING, &pc->flags); clear_bit(PC_WRITING, &pc->flags);
if (pc->sg) if (pc->s.sg)
idescsi_input_buffers (drive, pc, bcount); idescsi_input_buffers (drive, pc, bcount);
else else
atapi_read(drive,pc->current_position,bcount); atapi_read(drive,pc->current_position,bcount);
} else { } else {
set_bit(PC_WRITING, &pc->flags); set_bit(PC_WRITING, &pc->flags);
if (pc->sg) if (pc->s.sg)
idescsi_output_buffers (drive, pc, bcount); idescsi_output_buffers (drive, pc, bcount);
else else
atapi_write(drive,pc->current_position,bcount); atapi_write(drive,pc->current_position,bcount);
...@@ -397,7 +373,7 @@ static ide_startstop_t idescsi_pc_intr(struct ata_device *drive, struct request ...@@ -397,7 +373,7 @@ static ide_startstop_t idescsi_pc_intr(struct ata_device *drive, struct request
static ide_startstop_t idescsi_transfer_pc(struct ata_device *drive, struct request *rq) static ide_startstop_t idescsi_transfer_pc(struct ata_device *drive, struct request *rq)
{ {
idescsi_scsi_t *scsi = drive->driver_data; idescsi_scsi_t *scsi = drive->driver_data;
idescsi_pc_t *pc = scsi->pc; struct atapi_packet_command *pc = scsi->pc;
byte ireason; byte ireason;
ide_startstop_t startstop; ide_startstop_t startstop;
...@@ -418,7 +394,8 @@ static ide_startstop_t idescsi_transfer_pc(struct ata_device *drive, struct requ ...@@ -418,7 +394,8 @@ static ide_startstop_t idescsi_transfer_pc(struct ata_device *drive, struct requ
/* /*
* Issue a packet command * Issue a packet command
*/ */
static ide_startstop_t idescsi_issue_pc(struct ata_device *drive, struct request *rq, idescsi_pc_t *pc) static ide_startstop_t idescsi_issue_pc(struct ata_device *drive, struct request *rq,
struct atapi_packet_command *pc)
{ {
idescsi_scsi_t *scsi = drive->driver_data; idescsi_scsi_t *scsi = drive->driver_data;
int bcount; int bcount;
...@@ -465,10 +442,10 @@ static ide_startstop_t idescsi_do_request(struct ata_device *drive, struct reque ...@@ -465,10 +442,10 @@ static ide_startstop_t idescsi_do_request(struct ata_device *drive, struct reque
#if IDESCSI_DEBUG_LOG #if IDESCSI_DEBUG_LOG
printk (KERN_INFO "rq_status: %d, rq_dev: %u, cmd: %d, errors: %d\n",rq->rq_status,(unsigned int) rq->rq_dev,rq->cmd,rq->errors); printk (KERN_INFO "rq_status: %d, rq_dev: %u, cmd: %d, errors: %d\n",rq->rq_status,(unsigned int) rq->rq_dev,rq->cmd,rq->errors);
printk (KERN_INFO "sector: %ld, nr_sectors: %ld, current_nr_sectors: %ld\n",rq->sector,rq->nr_sectors,rq->current_nr_sectors); printk (KERN_INFO "sector: %ld, nr_sectors: %ld, current_nr_sectors: %ld\n",rq->sector,rq->nr_sectors,rq->current_nr_sectors);
#endif /* IDESCSI_DEBUG_LOG */ #endif
if (rq->flags & REQ_SPECIAL) { if (rq->flags & REQ_SPECIAL) {
return idescsi_issue_pc(drive, rq, (idescsi_pc_t *) rq->special); return idescsi_issue_pc(drive, rq, (struct atapi_packet_command *) rq->special);
} }
blk_dump_rq_flags(rq, "ide-scsi: unsup command"); blk_dump_rq_flags(rq, "ide-scsi: unsup command");
idescsi_end_request(drive, rq, 0); idescsi_end_request(drive, rq, 0);
...@@ -486,16 +463,14 @@ static void idescsi_ide_release(struct inode *inode, struct file *filp, struct a ...@@ -486,16 +463,14 @@ static void idescsi_ide_release(struct inode *inode, struct file *filp, struct a
MOD_DEC_USE_COUNT; MOD_DEC_USE_COUNT;
} }
static ide_drive_t *idescsi_drives[MAX_HWIFS * MAX_DRIVES]; static struct ata_device *idescsi_drives[MAX_HWIFS * MAX_DRIVES];
static int idescsi_initialized = 0; static int idescsi_initialized = 0;
/* /*
* Driver initialization. * Driver initialization.
*/ */
static void idescsi_setup (ide_drive_t *drive, idescsi_scsi_t *scsi, int id) static void idescsi_setup(struct ata_device *drive, idescsi_scsi_t *scsi, int id)
{ {
MOD_INC_USE_COUNT;
idescsi_drives[id] = drive; idescsi_drives[id] = drive;
drive->driver_data = scsi; drive->driver_data = scsi;
drive->ready_stat = 0; drive->ready_stat = 0;
...@@ -510,7 +485,7 @@ static void idescsi_setup (ide_drive_t *drive, idescsi_scsi_t *scsi, int id) ...@@ -510,7 +485,7 @@ static void idescsi_setup (ide_drive_t *drive, idescsi_scsi_t *scsi, int id)
#endif #endif
} }
static int idescsi_cleanup (ide_drive_t *drive) static int idescsi_cleanup(struct ata_device *drive)
{ {
idescsi_scsi_t *scsi = drive->driver_data; idescsi_scsi_t *scsi = drive->driver_data;
...@@ -521,7 +496,7 @@ static int idescsi_cleanup (ide_drive_t *drive) ...@@ -521,7 +496,7 @@ static int idescsi_cleanup (ide_drive_t *drive)
return 0; return 0;
} }
static void idescsi_revalidate(ide_drive_t *_dummy) static void idescsi_revalidate(struct ata_device *_dummy)
{ {
/* The partition information will be handled by the SCSI layer. /* The partition information will be handled by the SCSI layer.
*/ */
...@@ -549,7 +524,7 @@ static struct ata_operations idescsi_driver = { ...@@ -549,7 +524,7 @@ static struct ata_operations idescsi_driver = {
*/ */
int idescsi_init(void) int idescsi_init(void)
{ {
ide_drive_t *drive; struct ata_device *drive;
idescsi_scsi_t *scsi; idescsi_scsi_t *scsi;
/* FIXME: The following is just plain wrong, since those are definitely *not* the /* FIXME: The following is just plain wrong, since those are definitely *not* the
* media types supported by the ATA layer */ * media types supported by the ATA layer */
...@@ -606,7 +581,7 @@ int idescsi_detect (Scsi_Host_Template *host_template) ...@@ -606,7 +581,7 @@ int idescsi_detect (Scsi_Host_Template *host_template)
int idescsi_release (struct Scsi_Host *host) int idescsi_release (struct Scsi_Host *host)
{ {
ide_drive_t *drive; struct ata_device *drive;
int id; int id;
for (id = 0; id < MAX_HWIFS * MAX_DRIVES; id++) { for (id = 0; id < MAX_HWIFS * MAX_DRIVES; id++) {
...@@ -625,7 +600,7 @@ const char *idescsi_info (struct Scsi_Host *host) ...@@ -625,7 +600,7 @@ const char *idescsi_info (struct Scsi_Host *host)
int idescsi_ioctl (Scsi_Device *dev, int cmd, void *arg) int idescsi_ioctl (Scsi_Device *dev, int cmd, void *arg)
{ {
ide_drive_t *drive = idescsi_drives[dev->id]; struct ata_device *drive = idescsi_drives[dev->id];
idescsi_scsi_t *scsi = drive->driver_data; idescsi_scsi_t *scsi = drive->driver_data;
if (cmd == SG_SET_TRANSFORM) { if (cmd == SG_SET_TRANSFORM) {
...@@ -662,25 +637,29 @@ static inline struct bio *idescsi_kmalloc_bio (int count) ...@@ -662,25 +637,29 @@ static inline struct bio *idescsi_kmalloc_bio (int count)
return NULL; return NULL;
} }
static inline int idescsi_set_direction (idescsi_pc_t *pc) static inline int idescsi_set_direction(struct atapi_packet_command *pc)
{ {
switch (pc->c[0]) { switch (pc->c[0]) {
case READ_6: case READ_10: case READ_12: case READ_6:
clear_bit (PC_WRITING, &pc->flags); case READ_10:
case READ_12:
clear_bit(PC_WRITING, &pc->flags);
return 0; return 0;
case WRITE_6: case WRITE_10: case WRITE_12: case WRITE_6:
set_bit (PC_WRITING, &pc->flags); case WRITE_10:
case WRITE_12:
set_bit(PC_WRITING, &pc->flags);
return 0; return 0;
default: default:
return 1; return 1;
} }
} }
static inline struct bio *idescsi_dma_bio(ide_drive_t *drive, idescsi_pc_t *pc) static inline struct bio *idescsi_dma_bio(struct ata_device *drive, struct atapi_packet_command *pc)
{ {
struct bio *bh = NULL, *first_bh = NULL; struct bio *bh = NULL, *first_bh = NULL;
int segments = pc->scsi_cmd->use_sg; int segments = pc->s.scsi_cmd->use_sg;
struct scatterlist *sg = pc->scsi_cmd->request_buffer; struct scatterlist *sg = pc->s.scsi_cmd->request_buffer;
if (!drive->using_dma || !pc->request_transfer || pc->request_transfer % 1024) if (!drive->using_dma || !pc->request_transfer || pc->request_transfer % 1024)
return NULL; return NULL;
...@@ -691,7 +670,7 @@ static inline struct bio *idescsi_dma_bio(ide_drive_t *drive, idescsi_pc_t *pc) ...@@ -691,7 +670,7 @@ static inline struct bio *idescsi_dma_bio(ide_drive_t *drive, idescsi_pc_t *pc)
return NULL; return NULL;
#if IDESCSI_DEBUG_LOG #if IDESCSI_DEBUG_LOG
printk ("ide-scsi: %s: building DMA table, %d segments, %dkB total\n", drive->name, segments, pc->request_transfer >> 10); printk ("ide-scsi: %s: building DMA table, %d segments, %dkB total\n", drive->name, segments, pc->request_transfer >> 10);
#endif /* IDESCSI_DEBUG_LOG */ #endif
while (segments--) { while (segments--) {
bh->bi_io_vec[0].bv_page = sg->page; bh->bi_io_vec[0].bv_page = sg->page;
bh->bi_io_vec[0].bv_len = sg->length; bh->bi_io_vec[0].bv_len = sg->length;
...@@ -705,16 +684,16 @@ static inline struct bio *idescsi_dma_bio(ide_drive_t *drive, idescsi_pc_t *pc) ...@@ -705,16 +684,16 @@ static inline struct bio *idescsi_dma_bio(ide_drive_t *drive, idescsi_pc_t *pc)
return NULL; return NULL;
#if IDESCSI_DEBUG_LOG #if IDESCSI_DEBUG_LOG
printk ("ide-scsi: %s: building DMA table for a single buffer (%dkB)\n", drive->name, pc->request_transfer >> 10); printk ("ide-scsi: %s: building DMA table for a single buffer (%dkB)\n", drive->name, pc->request_transfer >> 10);
#endif /* IDESCSI_DEBUG_LOG */ #endif
bh->bi_io_vec[0].bv_page = virt_to_page(pc->scsi_cmd->request_buffer); bh->bi_io_vec[0].bv_page = virt_to_page(pc->s.scsi_cmd->request_buffer);
bh->bi_io_vec[0].bv_len = pc->request_transfer; bh->bi_io_vec[0].bv_len = pc->request_transfer;
bh->bi_io_vec[0].bv_offset = (unsigned long) pc->scsi_cmd->request_buffer & ~PAGE_MASK; bh->bi_io_vec[0].bv_offset = (unsigned long) pc->s.scsi_cmd->request_buffer & ~PAGE_MASK;
bh->bi_size = pc->request_transfer; bh->bi_size = pc->request_transfer;
} }
return first_bh; return first_bh;
} }
static inline int should_transform(ide_drive_t *drive, Scsi_Cmnd *cmd) static inline int should_transform(struct ata_device *drive, Scsi_Cmnd *cmd)
{ {
idescsi_scsi_t *scsi = drive->driver_data; idescsi_scsi_t *scsi = drive->driver_data;
...@@ -725,18 +704,18 @@ static inline int should_transform(ide_drive_t *drive, Scsi_Cmnd *cmd) ...@@ -725,18 +704,18 @@ static inline int should_transform(ide_drive_t *drive, Scsi_Cmnd *cmd)
int idescsi_queue (Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *)) int idescsi_queue (Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
{ {
ide_drive_t *drive = idescsi_drives[cmd->target]; struct ata_device *drive = idescsi_drives[cmd->target];
idescsi_scsi_t *scsi; idescsi_scsi_t *scsi;
struct request *rq = NULL; struct request *rq = NULL;
idescsi_pc_t *pc = NULL; struct atapi_packet_command *pc = NULL;
if (!drive) { if (!drive) {
printk (KERN_ERR "ide-scsi: drive id %d not present\n", cmd->target); printk (KERN_ERR "ide-scsi: drive id %d not present\n", cmd->target);
goto abort; goto abort;
} }
scsi = drive->driver_data; scsi = drive->driver_data;
pc = kmalloc (sizeof (idescsi_pc_t), GFP_ATOMIC); pc = kmalloc(sizeof(*pc), GFP_ATOMIC);
rq = kmalloc (sizeof (struct request), GFP_ATOMIC); rq = kmalloc(sizeof(*rq), GFP_ATOMIC);
if (rq == NULL || pc == NULL) { if (rq == NULL || pc == NULL) {
printk (KERN_ERR "ide-scsi: %s: out of memory\n", drive->name); printk (KERN_ERR "ide-scsi: %s: out of memory\n", drive->name);
goto abort; goto abort;
...@@ -747,16 +726,16 @@ int idescsi_queue (Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *)) ...@@ -747,16 +726,16 @@ int idescsi_queue (Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
memcpy (pc->c, cmd->cmnd, cmd->cmd_len); memcpy (pc->c, cmd->cmnd, cmd->cmd_len);
if (cmd->use_sg) { if (cmd->use_sg) {
pc->buffer = NULL; pc->buffer = NULL;
pc->sg = cmd->request_buffer; pc->s.sg = cmd->request_buffer;
} else { } else {
pc->buffer = cmd->request_buffer; pc->buffer = cmd->request_buffer;
pc->sg = NULL; pc->s.sg = NULL;
} }
pc->b_count = 0; pc->s.b_count = 0;
pc->request_transfer = pc->buffer_size = cmd->request_bufflen; pc->request_transfer = pc->buffer_size = cmd->request_bufflen;
pc->scsi_cmd = cmd; pc->s.scsi_cmd = cmd;
pc->done = done; pc->s.done = done;
pc->timeout = jiffies + cmd->timeout_per_command; pc->s.timeout = jiffies + cmd->timeout_per_command;
if (should_transform(drive, cmd)) if (should_transform(drive, cmd))
set_bit(PC_TRANSFORM, &pc->flags); set_bit(PC_TRANSFORM, &pc->flags);
...@@ -797,7 +776,7 @@ int idescsi_device_reset (Scsi_Cmnd *cmd) ...@@ -797,7 +776,7 @@ int idescsi_device_reset (Scsi_Cmnd *cmd)
int idescsi_bios (Disk *disk, kdev_t dev, int *parm) int idescsi_bios (Disk *disk, kdev_t dev, int *parm)
{ {
ide_drive_t *drive = idescsi_drives[disk->device->id]; struct ata_device *drive = idescsi_drives[disk->device->id];
if (drive->bios_cyl && drive->bios_head && drive->bios_sect) { if (drive->bios_cyl && drive->bios_head && drive->bios_sect) {
parm[0] = drive->bios_head; parm[0] = drive->bios_head;
...@@ -835,7 +814,7 @@ static int __init init_idescsi_module(void) ...@@ -835,7 +814,7 @@ static int __init init_idescsi_module(void)
static void __exit exit_idescsi_module(void) static void __exit exit_idescsi_module(void)
{ {
ide_drive_t *drive; struct ata_device *drive;
byte media[] = {TYPE_DISK, TYPE_TAPE, TYPE_PROCESSOR, TYPE_WORM, TYPE_ROM, TYPE_SCANNER, TYPE_MOD, 255}; byte media[] = {TYPE_DISK, TYPE_TAPE, TYPE_PROCESSOR, TYPE_WORM, TYPE_ROM, TYPE_SCANNER, TYPE_MOD, 255};
int i, failed; int i, failed;
......
/**** vi:set ts=8 sts=8 sw=8:************************************************
*
* Copyright (C) 2002 Marcin Dalecki <martin@dalecki.de>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*/
/*
* With each packet command, we allocate a buffer.
* This is used for several packet
* commands (Not for READ/WRITE commands).
*/
#define IDEFLOPPY_PC_BUFFER_SIZE 256
#define IDETAPE_PC_BUFFER_SIZE 256
/* This struct get's shared between different drivers.
*/
struct atapi_packet_command {
u8 c[12]; /* Actual packet bytes */
char *buffer; /* Data buffer */
int buffer_size; /* Size of our data buffer */
char *current_position; /* Pointer into the above buffer */
int request_transfer; /* Bytes to transfer */
int actually_transferred; /* Bytes actually transferred */
unsigned long flags; /* Status/Action bit flags: long for set_bit */
/* FIXME: the following is ugly as hell, but the only way we can start
* actually to unify the code.
*/
/* driver specific data. */
/* floppy/tape */
int retries; /* On each retry, we increment retries */
int error; /* Error code */
char *b_data; /* Pointer which runs on the buffers */
unsigned int b_count; /* Missing/Available data on the current buffer */
u8 pc_buffer[IDEFLOPPY_PC_BUFFER_SIZE]; /* Temporary buffer */
/* Called when this packet command is completed */
void (*callback) (struct ata_device *, struct request *);
/* only tape */
struct bio *bio;
/* only scsi */
struct {
unsigned int b_count; /* Bytes transferred from current entry */
struct scatterlist *sg; /* Scatter gather table */
struct scsi_cmnd *scsi_cmd; /* SCSI command */
void (*done)(struct scsi_cmnd *); /* Scsi completion routine */
unsigned long timeout; /* Command timeout */
} s;
};
extern void atapi_discard_data(struct ata_device *drive, unsigned int bcount);
extern void atapi_write_zeros(struct ata_device *drive, unsigned int bcount);
extern void atapi_init_pc(struct atapi_packet_command *pc);
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment