aboutsummaryrefslogtreecommitdiff
path: root/drivers/scsi/osst.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/osst.c')
-rw-r--r--drivers/scsi/osst.c320
1 files changed, 208 insertions, 112 deletions
diff --git a/drivers/scsi/osst.c b/drivers/scsi/osst.c
index 824fe080d1d..0727ea7cc38 100644
--- a/drivers/scsi/osst.c
+++ b/drivers/scsi/osst.c
@@ -38,6 +38,7 @@ static const char * osst_version = "0.99.4";
#include <linux/sched.h>
#include <linux/proc_fs.h>
#include <linux/mm.h>
+#include <linux/slab.h>
#include <linux/init.h>
#include <linux/string.h>
#include <linux/errno.h>
@@ -50,9 +51,9 @@ static const char * osst_version = "0.99.4";
#include <linux/moduleparam.h>
#include <linux/delay.h>
#include <linux/jiffies.h>
+#include <linux/mutex.h>
#include <asm/uaccess.h>
#include <asm/dma.h>
-#include <asm/system.h>
/* The driver prints some debugging information on the console if DEBUG
is defined and non-zero. */
@@ -78,6 +79,7 @@ static const char * osst_version = "0.99.4";
#include "osst_options.h"
#include "osst_detect.h"
+static DEFINE_MUTEX(osst_int_mutex);
static int max_dev = 0;
static int write_threshold_kbs = 0;
static int max_sg_segs = 0;
@@ -87,6 +89,7 @@ MODULE_AUTHOR("Willem Riede");
MODULE_DESCRIPTION("OnStream {DI-|FW-|SC-|USB}{30|50} Tape Driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS_CHARDEV_MAJOR(OSST_MAJOR);
+MODULE_ALIAS_SCSI_DEVICE(TYPE_TAPE);
module_param(max_dev, int, 0444);
MODULE_PARM_DESC(max_dev, "Maximum number of OnStream Tape Drives to attach (4)");
@@ -278,8 +281,8 @@ static int osst_chk_result(struct osst_tape * STp, struct osst_request * SRpnt)
static int notyetprinted = 1;
printk(KERN_WARNING
- "%s:W: Warning %x (sugg. bt 0x%x, driver bt 0x%x, host bt 0x%x).\n",
- name, result, suggestion(result), driver_byte(result) & DRIVER_MASK,
+ "%s:W: Warning %x (driver bt 0x%x, host bt 0x%x).\n",
+ name, result, driver_byte(result),
host_byte(result));
if (notyetprinted) {
notyetprinted = 0;
@@ -315,18 +318,25 @@ static int osst_chk_result(struct osst_tape * STp, struct osst_request * SRpnt)
/* Wakeup from interrupt */
-static void osst_sleep_done(void *data, char *sense, int result, int resid)
+static void osst_end_async(struct request *req, int update)
{
- struct osst_request *SRpnt = data;
+ struct osst_request *SRpnt = req->end_io_data;
struct osst_tape *STp = SRpnt->stp;
+ struct rq_map_data *mdata = &SRpnt->stp->buffer->map_data;
- memcpy(SRpnt->sense, sense, SCSI_SENSE_BUFFERSIZE);
- STp->buffer->cmdstat.midlevel_result = SRpnt->result = result;
+ STp->buffer->cmdstat.midlevel_result = SRpnt->result = req->errors;
#if DEBUG
STp->write_pending = 0;
#endif
if (SRpnt->waiting)
complete(SRpnt->waiting);
+
+ if (SRpnt->bio) {
+ kfree(mdata->pages);
+ blk_rq_unmap_user(SRpnt->bio);
+ }
+
+ __blk_put_request(req->q, req);
}
/* osst_request memory management */
@@ -340,6 +350,74 @@ static void osst_release_request(struct osst_request *streq)
kfree(streq);
}
+static int osst_execute(struct osst_request *SRpnt, const unsigned char *cmd,
+ int cmd_len, int data_direction, void *buffer, unsigned bufflen,
+ int use_sg, int timeout, int retries)
+{
+ struct request *req;
+ struct page **pages = NULL;
+ struct rq_map_data *mdata = &SRpnt->stp->buffer->map_data;
+
+ int err = 0;
+ int write = (data_direction == DMA_TO_DEVICE);
+
+ req = blk_get_request(SRpnt->stp->device->request_queue, write, GFP_KERNEL);
+ if (!req)
+ return DRIVER_ERROR << 24;
+
+ blk_rq_set_block_pc(req);
+ req->cmd_flags |= REQ_QUIET;
+
+ SRpnt->bio = NULL;
+
+ if (use_sg) {
+ struct scatterlist *sg, *sgl = (struct scatterlist *)buffer;
+ int i;
+
+ pages = kzalloc(use_sg * sizeof(struct page *), GFP_KERNEL);
+ if (!pages)
+ goto free_req;
+
+ for_each_sg(sgl, sg, use_sg, i)
+ pages[i] = sg_page(sg);
+
+ mdata->null_mapped = 1;
+
+ mdata->page_order = get_order(sgl[0].length);
+ mdata->nr_entries =
+ DIV_ROUND_UP(bufflen, PAGE_SIZE << mdata->page_order);
+ mdata->offset = 0;
+
+ err = blk_rq_map_user(req->q, req, mdata, NULL, bufflen, GFP_KERNEL);
+ if (err) {
+ kfree(pages);
+ goto free_req;
+ }
+ SRpnt->bio = req->bio;
+ mdata->pages = pages;
+
+ } else if (bufflen) {
+ err = blk_rq_map_kern(req->q, req, buffer, bufflen, GFP_KERNEL);
+ if (err)
+ goto free_req;
+ }
+
+ req->cmd_len = cmd_len;
+ memset(req->cmd, 0, BLK_MAX_CDB); /* ATAPI hates garbage after CDB */
+ memcpy(req->cmd, cmd, req->cmd_len);
+ req->sense = SRpnt->sense;
+ req->sense_len = 0;
+ req->timeout = timeout;
+ req->retries = retries;
+ req->end_io_data = SRpnt;
+
+ blk_execute_rq_nowait(req->q, NULL, req, 1, osst_end_async);
+ return 0;
+free_req:
+ blk_put_request(req);
+ return DRIVER_ERROR << 24;
+}
+
/* Do the scsi command. Waits until command performed if do_wait is true.
Otherwise osst_write_behind_check() is used to check that the command
has finished. */
@@ -401,8 +479,8 @@ static struct osst_request * osst_do_scsi(struct osst_request *SRpnt, struct oss
STp->buffer->cmdstat.have_sense = 0;
STp->buffer->syscall_result = 0;
- if (scsi_execute_async(STp->device, cmd, COMMAND_SIZE(cmd[0]), direction, bp, bytes,
- use_sg, timeout, retries, SRpnt, osst_sleep_done, GFP_KERNEL))
+ if (osst_execute(SRpnt, cmd, COMMAND_SIZE(cmd[0]), direction, bp, bytes,
+ use_sg, timeout, retries))
/* could not allocate the buffer or request was too large */
(STp->buffer)->syscall_result = (-EBUSY);
else if (do_wait) {
@@ -521,10 +599,10 @@ static void osst_init_aux(struct osst_tape * STp, int frame_type, int frame_seq_
break;
default: ; /* probably FILL */
}
- aux->filemark_cnt = ntohl(STp->filemark_cnt);
- aux->phys_fm = ntohl(0xffffffff);
- aux->last_mark_ppos = ntohl(STp->last_mark_ppos);
- aux->last_mark_lbn = ntohl(STp->last_mark_lbn);
+ aux->filemark_cnt = htonl(STp->filemark_cnt);
+ aux->phys_fm = htonl(0xffffffff);
+ aux->last_mark_ppos = htonl(STp->last_mark_ppos);
+ aux->last_mark_lbn = htonl(STp->last_mark_lbn);
}
/*
@@ -541,7 +619,7 @@ static int osst_verify_frame(struct osst_tape * STp, int frame_seq_number, int q
if (STp->raw) {
if (STp->buffer->syscall_result) {
for (i=0; i < STp->buffer->sg_segs; i++)
- memset(page_address(STp->buffer->sg[i].page),
+ memset(page_address(sg_page(&STp->buffer->sg[i])),
0, STp->buffer->sg[i].length);
strcpy(STp->buffer->b_data, "READ ERROR ON FRAME");
} else
@@ -592,10 +670,11 @@ static int osst_verify_frame(struct osst_tape * STp, int frame_seq_number, int q
if (aux->frame_type != OS_FRAME_TYPE_DATA &&
aux->frame_type != OS_FRAME_TYPE_EOD &&
aux->frame_type != OS_FRAME_TYPE_MARKER) {
- if (!quiet)
+ if (!quiet) {
#if DEBUG
printk(OSST_DEB_MSG "%s:D: Skipping frame, frame type %x\n", name, aux->frame_type);
#endif
+ }
goto err_out;
}
if (aux->frame_type == OS_FRAME_TYPE_EOD &&
@@ -605,11 +684,12 @@ static int osst_verify_frame(struct osst_tape * STp, int frame_seq_number, int q
goto err_out;
}
if (frame_seq_number != -1 && ntohl(aux->frame_seq_num) != frame_seq_number) {
- if (!quiet)
+ if (!quiet) {
#if DEBUG
printk(OSST_DEB_MSG "%s:D: Skipping frame, sequence number %u (expected %d)\n",
name, ntohl(aux->frame_seq_num), frame_seq_number);
#endif
+ }
goto err_out;
}
if (aux->frame_type == OS_FRAME_TYPE_MARKER) {
@@ -1285,7 +1365,7 @@ error:
/* The values below are based on the OnStream frame payload size of 32K == 2**15,
* that is, OSST_FRAME_SHIFT + OSST_SECTOR_SHIFT must be 15. With a minimum block
* size of 512 bytes, we need to be able to resolve 32K/512 == 64 == 2**6 positions
- * inside each frame. Finaly, OSST_SECTOR_MASK == 2**OSST_FRAME_SHIFT - 1.
+ * inside each frame. Finally, OSST_SECTOR_MASK == 2**OSST_FRAME_SHIFT - 1.
*/
#define OSST_FRAME_SHIFT 6
#define OSST_SECTOR_SHIFT 9
@@ -1403,7 +1483,7 @@ static int osst_read_back_buffer_and_rewrite(struct osst_tape * STp, struct osst
int dbg = debugging;
#endif
- if ((buffer = (unsigned char *)vmalloc((nframes + 1) * OS_DATA_SIZE)) == NULL)
+ if ((buffer = vmalloc((nframes + 1) * OS_DATA_SIZE)) == NULL)
return (-EIO);
printk(KERN_INFO "%s:I: Reading back %d frames from drive buffer%s\n",
@@ -2215,7 +2295,7 @@ static int osst_write_header(struct osst_tape * STp, struct osst_request ** aSRp
if (STp->raw) return 0;
if (STp->header_cache == NULL) {
- if ((STp->header_cache = (os_header_t *)vmalloc(sizeof(os_header_t))) == NULL) {
+ if ((STp->header_cache = vmalloc(sizeof(os_header_t))) == NULL) {
printk(KERN_ERR "%s:E: Failed to allocate header cache\n", name);
return (-ENOMEM);
}
@@ -2403,7 +2483,7 @@ static int __osst_analyze_headers(struct osst_tape * STp, struct osst_request **
name, ppos, update_frame_cntr);
#endif
if (STp->header_cache == NULL) {
- if ((STp->header_cache = (os_header_t *)vmalloc(sizeof(os_header_t))) == NULL) {
+ if ((STp->header_cache = vmalloc(sizeof(os_header_t))) == NULL) {
printk(KERN_ERR "%s:E: Failed to allocate header cache\n", name);
return 0;
}
@@ -3050,7 +3130,7 @@ static int osst_flush_write_buffer(struct osst_tape *STp, struct osst_request **
}
#if DEBUG
if (debugging)
- printk(OSST_DEB_MSG "%s:D: Flushing %d bytes, Transfering %d bytes in %d lblocks.\n",
+ printk(OSST_DEB_MSG "%s:D: Flushing %d bytes, Transferring %d bytes in %d lblocks.\n",
name, offset, transfer, blks);
#endif
@@ -3297,7 +3377,7 @@ static ssize_t osst_write(struct file * filp, const char __user * buf, size_t co
char * name = tape_name(STp);
- if (down_interruptible(&STp->lock))
+ if (mutex_lock_interruptible(&STp->lock))
return (-ERESTARTSYS);
/*
@@ -3507,7 +3587,7 @@ if (SRpnt) printk(KERN_ERR "%s:A: Not supposed to have SRpnt at line %d\n", name
if (i == (-ENOSPC)) {
transfer = STp->buffer->writing; /* FIXME -- check this logic */
if (transfer <= do_count) {
- filp->f_pos += do_count - transfer;
+ *ppos += do_count - transfer;
count -= do_count - transfer;
if (STps->drv_block >= 0) {
STps->drv_block += (do_count - transfer) / STp->block_size;
@@ -3545,7 +3625,7 @@ if (SRpnt) printk(KERN_ERR "%s:A: Not supposed to have SRpnt at line %d\n", name
goto out;
}
- filp->f_pos += do_count;
+ *ppos += do_count;
b_point += do_count;
count -= do_count;
if (STps->drv_block >= 0) {
@@ -3567,7 +3647,7 @@ if (SRpnt) printk(KERN_ERR "%s:A: Not supposed to have SRpnt at line %d\n", name
if (STps->drv_block >= 0) {
STps->drv_block += blks;
}
- filp->f_pos += count;
+ *ppos += count;
count = 0;
}
@@ -3599,7 +3679,7 @@ if (SRpnt) printk(KERN_ERR "%s:A: Not supposed to have SRpnt at line %d\n", name
out:
if (SRpnt != NULL) osst_release_request(SRpnt);
- up(&STp->lock);
+ mutex_unlock(&STp->lock);
return retval;
}
@@ -3618,7 +3698,7 @@ static ssize_t osst_read(struct file * filp, char __user * buf, size_t count, lo
char * name = tape_name(STp);
- if (down_interruptible(&STp->lock))
+ if (mutex_lock_interruptible(&STp->lock))
return (-ERESTARTSYS);
/*
@@ -3730,7 +3810,7 @@ static ssize_t osst_read(struct file * filp, char __user * buf, size_t count, lo
if (transfer == 0) {
printk(KERN_WARNING
- "%s:W: Nothing can be transfered, requested %Zd, tape block size (%d%c).\n",
+ "%s:W: Nothing can be transferred, requested %Zd, tape block size (%d%c).\n",
name, count, STp->block_size < 1024?
STp->block_size:STp->block_size/1024,
STp->block_size<1024?'b':'k');
@@ -3743,7 +3823,7 @@ static ssize_t osst_read(struct file * filp, char __user * buf, size_t count, lo
}
STp->logical_blk_num += transfer / STp->block_size;
STps->drv_block += transfer / STp->block_size;
- filp->f_pos += transfer;
+ *ppos += transfer;
buf += transfer;
total += transfer;
}
@@ -3784,7 +3864,7 @@ static ssize_t osst_read(struct file * filp, char __user * buf, size_t count, lo
out:
if (SRpnt != NULL) osst_release_request(SRpnt);
- up(&STp->lock);
+ mutex_unlock(&STp->lock);
return retval;
}
@@ -4356,7 +4436,7 @@ os_bypass:
/* Open the device */
-static int os_scsi_tape_open(struct inode * inode, struct file * filp)
+static int __os_scsi_tape_open(struct inode * inode, struct file * filp)
{
unsigned short flags;
int i, b_size, new_session = 0, retval = 0;
@@ -4436,7 +4516,7 @@ static int os_scsi_tape_open(struct inode * inode, struct file * filp)
for (i = 0, b_size = 0;
(i < STp->buffer->sg_segs) && ((b_size + STp->buffer->sg[i].length) <= OS_DATA_SIZE);
b_size += STp->buffer->sg[i++].length);
- STp->buffer->aux = (os_aux_t *) (page_address(STp->buffer->sg[i].page) + OS_DATA_SIZE - b_size);
+ STp->buffer->aux = (os_aux_t *) (page_address(sg_page(&STp->buffer->sg[i])) + OS_DATA_SIZE - b_size);
#if DEBUG
printk(OSST_DEB_MSG "%s:D: b_data points to %p in segment 0 at %p\n", name,
STp->buffer->b_data, page_address(STp->buffer->sg[0].page));
@@ -4617,12 +4697,14 @@ static int os_scsi_tape_open(struct inode * inode, struct file * filp)
break;
if ((SRpnt->sense[2] & 0x0f) == UNIT_ATTENTION) {
+ int j;
+
STp->pos_unknown = 0;
STp->partition = STp->new_partition = 0;
if (STp->can_partitions)
STp->nbr_partitions = 1; /* This guess will be updated later if necessary */
- for (i=0; i < ST_NBR_PARTITIONS; i++) {
- STps = &(STp->ps[i]);
+ for (j = 0; j < ST_NBR_PARTITIONS; j++) {
+ STps = &(STp->ps[j]);
STps->rw = ST_IDLE;
STps->eof = ST_NOEOF;
STps->at_sm = 0;
@@ -4722,6 +4804,18 @@ err_out:
return retval;
}
+/* BKL pushdown: spaghetti avoidance wrapper */
+static int os_scsi_tape_open(struct inode * inode, struct file * filp)
+{
+ int ret;
+
+ mutex_lock(&osst_int_mutex);
+ ret = __os_scsi_tape_open(inode, filp);
+ mutex_unlock(&osst_int_mutex);
+ return ret;
+}
+
+
/* Flush the tape buffer before close */
static int os_scsi_tape_flush(struct file * filp, fl_owner_t id)
@@ -4840,7 +4934,7 @@ static int os_scsi_tape_close(struct inode * inode, struct file * filp)
/* The ioctl command */
-static int osst_ioctl(struct inode * inode,struct file * file,
+static long osst_ioctl(struct file * file,
unsigned int cmd_in, unsigned long arg)
{
int i, cmd_nr, cmd_type, blk, retval = 0;
@@ -4851,8 +4945,11 @@ static int osst_ioctl(struct inode * inode,struct file * file,
char * name = tape_name(STp);
void __user * p = (void __user *)arg;
- if (down_interruptible(&STp->lock))
+ mutex_lock(&osst_int_mutex);
+ if (mutex_lock_interruptible(&STp->lock)) {
+ mutex_unlock(&osst_int_mutex);
return -ERESTARTSYS;
+ }
#if DEBUG
if (debugging && !STp->in_use) {
@@ -5162,14 +5259,17 @@ static int osst_ioctl(struct inode * inode,struct file * file,
}
if (SRpnt) osst_release_request(SRpnt);
- up(&STp->lock);
+ mutex_unlock(&STp->lock);
- return scsi_ioctl(STp->device, cmd_in, p);
+ retval = scsi_ioctl(STp->device, cmd_in, p);
+ mutex_unlock(&osst_int_mutex);
+ return retval;
out:
if (SRpnt) osst_release_request(SRpnt);
- up(&STp->lock);
+ mutex_unlock(&STp->lock);
+ mutex_unlock(&osst_int_mutex);
return retval;
}
@@ -5251,30 +5351,25 @@ static int enlarge_buffer(struct osst_buffer *STbuffer, int need_dma)
/* Try to allocate the first segment up to OS_DATA_SIZE and the others
big enough to reach the goal (code assumes no segments in place) */
for (b_size = OS_DATA_SIZE, order = OSST_FIRST_ORDER; b_size >= PAGE_SIZE; order--, b_size /= 2) {
- STbuffer->sg[0].page = alloc_pages(priority, order);
+ struct page *page = alloc_pages(priority, order);
+
STbuffer->sg[0].offset = 0;
- if (STbuffer->sg[0].page != NULL) {
- STbuffer->sg[0].length = b_size;
- STbuffer->b_data = page_address(STbuffer->sg[0].page);
+ if (page != NULL) {
+ sg_set_page(&STbuffer->sg[0], page, b_size, 0);
+ STbuffer->b_data = page_address(page);
break;
}
}
- if (STbuffer->sg[0].page == NULL) {
+ if (sg_page(&STbuffer->sg[0]) == NULL) {
printk(KERN_NOTICE "osst :I: Can't allocate tape buffer main segment.\n");
return 0;
}
/* Got initial segment of 'bsize,order', continue with same size if possible, except for AUX */
for (segs=STbuffer->sg_segs=1, got=b_size;
segs < max_segs && got < OS_FRAME_SIZE; ) {
- STbuffer->sg[segs].page =
- alloc_pages(priority, (OS_FRAME_SIZE - got <= PAGE_SIZE) ? 0 : order);
+ struct page *page = alloc_pages(priority, (OS_FRAME_SIZE - got <= PAGE_SIZE) ? 0 : order);
STbuffer->sg[segs].offset = 0;
- if (STbuffer->sg[segs].page == NULL) {
- if (OS_FRAME_SIZE - got <= (max_segs - segs) * b_size / 2 && order) {
- b_size /= 2; /* Large enough for the rest of the buffers */
- order--;
- continue;
- }
+ if (page == NULL) {
printk(KERN_WARNING "osst :W: Failed to enlarge buffer to %d bytes.\n",
OS_FRAME_SIZE);
#if DEBUG
@@ -5283,7 +5378,7 @@ static int enlarge_buffer(struct osst_buffer *STbuffer, int need_dma)
normalize_buffer(STbuffer);
return 0;
}
- STbuffer->sg[segs].length = (OS_FRAME_SIZE - got <= PAGE_SIZE / 2) ? (OS_FRAME_SIZE - got) : b_size;
+ sg_set_page(&STbuffer->sg[segs], page, (OS_FRAME_SIZE - got <= PAGE_SIZE / 2) ? (OS_FRAME_SIZE - got) : b_size, 0);
got += STbuffer->sg[segs].length;
STbuffer->buffer_size = got;
STbuffer->sg_segs = ++segs;
@@ -5315,7 +5410,7 @@ static void normalize_buffer(struct osst_buffer *STbuffer)
b_size < STbuffer->sg[i].length;
b_size *= 2, order++);
- __free_pages(STbuffer->sg[i].page, order);
+ __free_pages(sg_page(&STbuffer->sg[i]), order);
STbuffer->buffer_size -= STbuffer->sg[i].length;
}
#if DEBUG
@@ -5343,7 +5438,7 @@ static int append_to_buffer(const char __user *ubp, struct osst_buffer *st_bp, i
for ( ; i < st_bp->sg_segs && do_count > 0; i++) {
cnt = st_bp->sg[i].length - offset < do_count ?
st_bp->sg[i].length - offset : do_count;
- res = copy_from_user(page_address(st_bp->sg[i].page) + offset, ubp, cnt);
+ res = copy_from_user(page_address(sg_page(&st_bp->sg[i])) + offset, ubp, cnt);
if (res)
return (-EFAULT);
do_count -= cnt;
@@ -5376,7 +5471,7 @@ static int from_buffer(struct osst_buffer *st_bp, char __user *ubp, int do_count
for ( ; i < st_bp->sg_segs && do_count > 0; i++) {
cnt = st_bp->sg[i].length - offset < do_count ?
st_bp->sg[i].length - offset : do_count;
- res = copy_to_user(ubp, page_address(st_bp->sg[i].page) + offset, cnt);
+ res = copy_to_user(ubp, page_address(sg_page(&st_bp->sg[i])) + offset, cnt);
if (res)
return (-EFAULT);
do_count -= cnt;
@@ -5409,7 +5504,7 @@ static int osst_zero_buffer_tail(struct osst_buffer *st_bp)
i < st_bp->sg_segs && do_count > 0; i++) {
cnt = st_bp->sg[i].length - offset < do_count ?
st_bp->sg[i].length - offset : do_count ;
- memset(page_address(st_bp->sg[i].page) + offset, 0, cnt);
+ memset(page_address(sg_page(&st_bp->sg[i])) + offset, 0, cnt);
do_count -= cnt;
offset = 0;
}
@@ -5429,7 +5524,7 @@ static int osst_copy_to_buffer(struct osst_buffer *st_bp, unsigned char *ptr)
for (i = 0; i < st_bp->sg_segs && do_count > 0; i++) {
cnt = st_bp->sg[i].length < do_count ?
st_bp->sg[i].length : do_count ;
- memcpy(page_address(st_bp->sg[i].page), ptr, cnt);
+ memcpy(page_address(sg_page(&st_bp->sg[i])), ptr, cnt);
do_count -= cnt;
ptr += cnt;
}
@@ -5450,7 +5545,7 @@ static int osst_copy_from_buffer(struct osst_buffer *st_bp, unsigned char *ptr)
for (i = 0; i < st_bp->sg_segs && do_count > 0; i++) {
cnt = st_bp->sg[i].length < do_count ?
st_bp->sg[i].length : do_count ;
- memcpy(ptr, page_address(st_bp->sg[i].page), cnt);
+ memcpy(ptr, page_address(sg_page(&st_bp->sg[i])), cnt);
do_count -= cnt;
ptr += cnt;
}
@@ -5522,17 +5617,18 @@ __setup("osst=", osst_setup);
#endif
-static struct file_operations osst_fops = {
+static const struct file_operations osst_fops = {
.owner = THIS_MODULE,
.read = osst_read,
.write = osst_write,
- .ioctl = osst_ioctl,
+ .unlocked_ioctl = osst_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = osst_compat_ioctl,
#endif
.open = os_scsi_tape_open,
.flush = os_scsi_tape_flush,
.release = os_scsi_tape_close,
+ .llseek = noop_llseek,
};
static int osst_supports(struct scsi_device * SDp)
@@ -5574,23 +5670,24 @@ static ssize_t osst_version_show(struct device_driver *ddd, char *buf)
static DRIVER_ATTR(version, S_IRUGO, osst_version_show, NULL);
-static int osst_create_driverfs_files(struct device_driver *driverfs)
+static int osst_create_sysfs_files(struct device_driver *sysfs)
{
- return driver_create_file(driverfs, &driver_attr_version);
+ return driver_create_file(sysfs, &driver_attr_version);
}
-static void osst_remove_driverfs_files(struct device_driver *driverfs)
+static void osst_remove_sysfs_files(struct device_driver *sysfs)
{
- driver_remove_file(driverfs, &driver_attr_version);
+ driver_remove_file(sysfs, &driver_attr_version);
}
/*
* sysfs support for accessing ADR header information
*/
-static ssize_t osst_adr_rev_show(struct class_device *class_dev, char *buf)
+static ssize_t osst_adr_rev_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
- struct osst_tape * STp = (struct osst_tape *) class_get_devdata (class_dev);
+ struct osst_tape * STp = (struct osst_tape *) dev_get_drvdata (dev);
ssize_t l = 0;
if (STp && STp->header_ok && STp->linux_media)
@@ -5598,11 +5695,13 @@ static ssize_t osst_adr_rev_show(struct class_device *class_dev, char *buf)
return l;
}
-CLASS_DEVICE_ATTR(ADR_rev, S_IRUGO, osst_adr_rev_show, NULL);
+DEVICE_ATTR(ADR_rev, S_IRUGO, osst_adr_rev_show, NULL);
-static ssize_t osst_linux_media_version_show(struct class_device *class_dev, char *buf)
+static ssize_t osst_linux_media_version_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
{
- struct osst_tape * STp = (struct osst_tape *) class_get_devdata (class_dev);
+ struct osst_tape * STp = (struct osst_tape *) dev_get_drvdata (dev);
ssize_t l = 0;
if (STp && STp->header_ok && STp->linux_media)
@@ -5610,11 +5709,12 @@ static ssize_t osst_linux_media_version_show(struct class_device *class_dev, cha
return l;
}
-CLASS_DEVICE_ATTR(media_version, S_IRUGO, osst_linux_media_version_show, NULL);
+DEVICE_ATTR(media_version, S_IRUGO, osst_linux_media_version_show, NULL);
-static ssize_t osst_capacity_show(struct class_device *class_dev, char *buf)
+static ssize_t osst_capacity_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
- struct osst_tape * STp = (struct osst_tape *) class_get_devdata (class_dev);
+ struct osst_tape * STp = (struct osst_tape *) dev_get_drvdata (dev);
ssize_t l = 0;
if (STp && STp->header_ok && STp->linux_media)
@@ -5622,11 +5722,13 @@ static ssize_t osst_capacity_show(struct class_device *class_dev, char *buf)
return l;
}
-CLASS_DEVICE_ATTR(capacity, S_IRUGO, osst_capacity_show, NULL);
+DEVICE_ATTR(capacity, S_IRUGO, osst_capacity_show, NULL);
-static ssize_t osst_first_data_ppos_show(struct class_device *class_dev, char *buf)
+static ssize_t osst_first_data_ppos_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
{
- struct osst_tape * STp = (struct osst_tape *) class_get_devdata (class_dev);
+ struct osst_tape * STp = (struct osst_tape *) dev_get_drvdata (dev);
ssize_t l = 0;
if (STp && STp->header_ok && STp->linux_media)
@@ -5634,11 +5736,13 @@ static ssize_t osst_first_data_ppos_show(struct class_device *class_dev, char *b
return l;
}
-CLASS_DEVICE_ATTR(BOT_frame, S_IRUGO, osst_first_data_ppos_show, NULL);
+DEVICE_ATTR(BOT_frame, S_IRUGO, osst_first_data_ppos_show, NULL);
-static ssize_t osst_eod_frame_ppos_show(struct class_device *class_dev, char *buf)
+static ssize_t osst_eod_frame_ppos_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
{
- struct osst_tape * STp = (struct osst_tape *) class_get_devdata (class_dev);
+ struct osst_tape * STp = (struct osst_tape *) dev_get_drvdata (dev);
ssize_t l = 0;
if (STp && STp->header_ok && STp->linux_media)
@@ -5646,11 +5750,12 @@ static ssize_t osst_eod_frame_ppos_show(struct class_device *class_dev, char *bu
return l;
}
-CLASS_DEVICE_ATTR(EOD_frame, S_IRUGO, osst_eod_frame_ppos_show, NULL);
+DEVICE_ATTR(EOD_frame, S_IRUGO, osst_eod_frame_ppos_show, NULL);
-static ssize_t osst_filemark_cnt_show(struct class_device *class_dev, char *buf)
+static ssize_t osst_filemark_cnt_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
- struct osst_tape * STp = (struct osst_tape *) class_get_devdata (class_dev);
+ struct osst_tape * STp = (struct osst_tape *) dev_get_drvdata (dev);
ssize_t l = 0;
if (STp && STp->header_ok && STp->linux_media)
@@ -5658,7 +5763,7 @@ static ssize_t osst_filemark_cnt_show(struct class_device *class_dev, char *buf)
return l;
}
-CLASS_DEVICE_ATTR(file_count, S_IRUGO, osst_filemark_cnt_show, NULL);
+DEVICE_ATTR(file_count, S_IRUGO, osst_filemark_cnt_show, NULL);
static struct class *osst_sysfs_class;
@@ -5675,44 +5780,37 @@ static int osst_sysfs_init(void)
static void osst_sysfs_destroy(dev_t dev)
{
- class_device_destroy(osst_sysfs_class, dev);
+ device_destroy(osst_sysfs_class, dev);
}
static int osst_sysfs_add(dev_t dev, struct device *device, struct osst_tape * STp, char * name)
{
- struct class_device *osst_class_member;
+ struct device *osst_member;
int err;
- osst_class_member = class_device_create(osst_sysfs_class, NULL, dev,
- device, "%s", name);
- if (IS_ERR(osst_class_member)) {
+ osst_member = device_create(osst_sysfs_class, device, dev, STp,
+ "%s", name);
+ if (IS_ERR(osst_member)) {
printk(KERN_WARNING "osst :W: Unable to add sysfs class member %s\n", name);
- return PTR_ERR(osst_class_member);
+ return PTR_ERR(osst_member);
}
- class_set_devdata(osst_class_member, STp);
- err = class_device_create_file(osst_class_member,
- &class_device_attr_ADR_rev);
+ err = device_create_file(osst_member, &dev_attr_ADR_rev);
if (err)
goto err_out;
- err = class_device_create_file(osst_class_member,
- &class_device_attr_media_version);
+ err = device_create_file(osst_member, &dev_attr_media_version);
if (err)
goto err_out;
- err = class_device_create_file(osst_class_member,
- &class_device_attr_capacity);
+ err = device_create_file(osst_member, &dev_attr_capacity);
if (err)
goto err_out;
- err = class_device_create_file(osst_class_member,
- &class_device_attr_BOT_frame);
+ err = device_create_file(osst_member, &dev_attr_BOT_frame);
if (err)
goto err_out;
- err = class_device_create_file(osst_class_member,
- &class_device_attr_EOD_frame);
+ err = device_create_file(osst_member, &dev_attr_EOD_frame);
if (err)
goto err_out;
- err = class_device_create_file(osst_class_member,
- &class_device_attr_file_count);
+ err = device_create_file(osst_member, &dev_attr_file_count);
if (err)
goto err_out;
@@ -5754,9 +5852,7 @@ static int osst_probe(struct device *dev)
/* if this is the first attach, build the infrastructure */
write_lock(&os_scsi_tapes_lock);
if (os_scsi_tapes == NULL) {
- os_scsi_tapes =
- (struct osst_tape **)kmalloc(osst_max_dev * sizeof(struct osst_tape *),
- GFP_ATOMIC);
+ os_scsi_tapes = kmalloc(osst_max_dev * sizeof(struct osst_tape *), GFP_ATOMIC);
if (os_scsi_tapes == NULL) {
write_unlock(&os_scsi_tapes_lock);
printk(KERN_ERR "osst :E: Unable to allocate array for OnStream SCSI tapes.\n");
@@ -5772,18 +5868,18 @@ static int osst_probe(struct device *dev)
}
/* find a free minor number */
- for (i=0; os_scsi_tapes[i] && i<osst_max_dev; i++);
+ for (i = 0; i < osst_max_dev && os_scsi_tapes[i]; i++)
+ ;
if(i >= osst_max_dev) panic ("Scsi_devices corrupt (osst)");
dev_num = i;
/* allocate a struct osst_tape for this device */
- tpnt = (struct osst_tape *)kmalloc(sizeof(struct osst_tape), GFP_ATOMIC);
- if (tpnt == NULL) {
+ tpnt = kzalloc(sizeof(struct osst_tape), GFP_ATOMIC);
+ if (!tpnt) {
write_unlock(&os_scsi_tapes_lock);
printk(KERN_ERR "osst :E: Can't allocate device descriptor, device not attached.\n");
goto out_put_disk;
}
- memset(tpnt, 0, sizeof(struct osst_tape));
/* allocate a buffer for this device */
i = SDp->host->sg_tablesize;
@@ -5865,7 +5961,7 @@ static int osst_probe(struct device *dev)
tpnt->modes[2].defined = 1;
tpnt->density_changed = tpnt->compression_changed = tpnt->blksize_changed = 0;
- init_MUTEX(&tpnt->lock);
+ mutex_init(&tpnt->lock);
osst_nr_dev++;
write_unlock(&os_scsi_tapes_lock);
@@ -5953,7 +6049,7 @@ static int __init init_osst(void)
if (err)
goto err_out_chrdev;
- err = osst_create_driverfs_files(&osst_template.gendrv);
+ err = osst_create_sysfs_files(&osst_template.gendrv);
if (err)
goto err_out_scsidrv;
@@ -5973,7 +6069,7 @@ static void __exit exit_osst (void)
int i;
struct osst_tape * STp;
- osst_remove_driverfs_files(&osst_template.gendrv);
+ osst_remove_sysfs_files(&osst_template.gendrv);
scsi_unregister_driver(&osst_template.gendrv);
unregister_chrdev(OSST_MAJOR, "osst");
osst_sysfs_cleanup();