Merge branch 'for-linus' of git://git390.marist.edu/pub/scm/linux-2.6
[safe/jmp/linux-2.6] / drivers / scsi / osst.c
index 331b789..d64b717 100644 (file)
@@ -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,6 +51,7 @@ static const char * osst_version = "0.99.4";
 #include <linux/moduleparam.h>
 #include <linux/delay.h>
 #include <linux/jiffies.h>
+#include <linux/smp_lock.h>
 #include <asm/uaccess.h>
 #include <asm/dma.h>
 #include <asm/system.h>
@@ -279,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;
@@ -316,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 */
@@ -341,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;
+
+       req->cmd_type = REQ_TYPE_BLOCK_PC;
+       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. */
@@ -402,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) {
@@ -542,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
@@ -593,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 &&
@@ -606,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) {
@@ -3508,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;
@@ -3546,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) {
@@ -3568,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;
        }
 
@@ -3744,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;
                }
@@ -4357,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;
@@ -4437,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));
@@ -4723,6 +4802,18 @@ err_out:
        return retval;
 }
 
+/* BKL pushdown: spaghetti avoidance wrapper */
+static int os_scsi_tape_open(struct inode * inode, struct file * filp)
+{
+       int ret;
+
+       lock_kernel();
+       ret = __os_scsi_tape_open(inode, filp);
+       unlock_kernel();
+       return ret;
+}
+
+
 
 /* Flush the tape buffer before close */
 static int os_scsi_tape_flush(struct file * filp, fl_owner_t id)
@@ -4841,7 +4932,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;
@@ -4852,8 +4943,11 @@ static int osst_ioctl(struct inode * inode,struct file * file,
        char                * name  = tape_name(STp);
        void        __user  * p     = (void __user *)arg;
 
-       if (mutex_lock_interruptible(&STp->lock))
+       lock_kernel();
+       if (mutex_lock_interruptible(&STp->lock)) {
+               unlock_kernel();
                return -ERESTARTSYS;
+       }
 
 #if DEBUG
        if (debugging && !STp->in_use) {
@@ -5165,12 +5259,15 @@ static int osst_ioctl(struct inode * inode,struct file * file,
 
        mutex_unlock(&STp->lock);
 
-       return scsi_ioctl(STp->device, cmd_in, p);
+       retval = scsi_ioctl(STp->device, cmd_in, p);
+       unlock_kernel();
+       return retval;
 
 out:
        if (SRpnt) osst_release_request(SRpnt);
 
        mutex_unlock(&STp->lock);
+       unlock_kernel();
 
        return retval;
 }
@@ -5252,30 +5349,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
@@ -5284,7 +5376,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;
@@ -5316,7 +5408,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
@@ -5344,7 +5436,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;
@@ -5377,7 +5469,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;
@@ -5410,7 +5502,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;
        }
@@ -5430,7 +5522,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;
        }
@@ -5451,7 +5543,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;
        }
@@ -5527,13 +5619,14 @@ 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)
@@ -5589,9 +5682,10 @@ static void osst_remove_sysfs_files(struct device_driver *sysfs)
  * 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)
@@ -5599,11 +5693,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)
@@ -5611,11 +5707,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)
@@ -5623,11 +5720,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)
@@ -5635,11 +5734,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)
@@ -5647,11 +5748,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)
@@ -5659,7 +5761,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;
 
@@ -5676,44 +5778,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;