iwlwifi: Fix built-in compilation of iwlcore
[safe/jmp/linux-2.6] / drivers / scsi / osst.c
index 9ecb323..abef704 100644 (file)
@@ -87,6 +87,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)");
@@ -521,10 +522,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 +542,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 +593,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 +607,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) {
@@ -3297,7 +3300,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);
 
        /*
@@ -3599,7 +3602,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 +3621,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);
 
        /*
@@ -3784,7 +3787,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;
 }
@@ -4436,7 +4439,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));
@@ -4851,7 +4854,7 @@ 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))
+       if (mutex_lock_interruptible(&STp->lock))
                return -ERESTARTSYS;
 
 #if DEBUG
@@ -5162,14 +5165,14 @@ 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);
 
 out:
        if (SRpnt) osst_release_request(SRpnt);
 
-       up(&STp->lock);
+       mutex_unlock(&STp->lock);
 
        return retval;
 }
@@ -5206,12 +5209,12 @@ static struct osst_buffer * new_tape_buffer( int from_initialization, int need_d
                priority = GFP_KERNEL;
 
        i = sizeof(struct osst_buffer) + (osst_max_sg_segs - 1) * sizeof(struct scatterlist);
-       tb = (struct osst_buffer *)kmalloc(i, priority);
+       tb = kzalloc(i, priority);
        if (!tb) {
                printk(KERN_NOTICE "osst :I: Can't allocate new tape buffer.\n");
                return NULL;
        }
-       memset(tb, 0, i);
+
        tb->sg_segs = tb->orig_sg_segs = 0;
        tb->use_sg = max_sg;
        tb->in_use = 1;
@@ -5251,25 +5254,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 (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--;
@@ -5283,7 +5286,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 +5318,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 +5346,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 +5379,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 +5412,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 +5432,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 +5453,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,7 +5525,7 @@ __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,
@@ -5574,14 +5577,14 @@ static ssize_t osst_version_show(struct device_driver *ddd, char *buf)
 
 static DRIVER_ATTR(version, S_IRUGO, osst_version_show, NULL);
 
-static void osst_create_driverfs_files(struct device_driver *driverfs)
+static int osst_create_sysfs_files(struct device_driver *sysfs)
 {
-       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);
 }
 
 /*
@@ -5662,50 +5665,70 @@ CLASS_DEVICE_ATTR(file_count, S_IRUGO, osst_filemark_cnt_show, NULL);
 
 static struct class *osst_sysfs_class;
 
-static int osst_sysfs_valid = 0;
-
-static void osst_sysfs_init(void)
+static int osst_sysfs_init(void)
 {
        osst_sysfs_class = class_create(THIS_MODULE, "onstream_tape");
-       if ( IS_ERR(osst_sysfs_class) )
-               printk(KERN_WARNING "osst :W: Unable to register sysfs class\n");
-       else
-               osst_sysfs_valid = 1;
+       if (IS_ERR(osst_sysfs_class)) {
+               printk(KERN_ERR "osst :W: Unable to register sysfs class\n");
+               return PTR_ERR(osst_sysfs_class);
+       }
+
+       return 0;
 }
 
-static void osst_sysfs_add(dev_t dev, struct device *device, struct osst_tape * STp, char * name)
+static void osst_sysfs_destroy(dev_t dev)
 {
-       struct class_device *osst_class_member;
+       class_device_destroy(osst_sysfs_class, dev);
+}
 
-       if (!osst_sysfs_valid) return;
+static int osst_sysfs_add(dev_t dev, struct device *device, struct osst_tape * STp, char * name)
+{
+       struct class_device *osst_class_member;
+       int err;
 
-       osst_class_member = class_device_create(osst_sysfs_class, NULL, dev, device, "%s", name);
+       osst_class_member = class_device_create(osst_sysfs_class, NULL, dev,
+                                               device, "%s", name);
        if (IS_ERR(osst_class_member)) {
                printk(KERN_WARNING "osst :W: Unable to add sysfs class member %s\n", name);
-               return;
+               return PTR_ERR(osst_class_member);
        }
+
        class_set_devdata(osst_class_member, STp);
-       class_device_create_file(osst_class_member, &class_device_attr_ADR_rev);
-       class_device_create_file(osst_class_member, &class_device_attr_media_version);
-       class_device_create_file(osst_class_member, &class_device_attr_capacity);
-       class_device_create_file(osst_class_member, &class_device_attr_BOT_frame);
-       class_device_create_file(osst_class_member, &class_device_attr_EOD_frame);
-       class_device_create_file(osst_class_member, &class_device_attr_file_count);
-}
+       err = class_device_create_file(osst_class_member,
+                                      &class_device_attr_ADR_rev);
+       if (err)
+               goto err_out;
+       err = class_device_create_file(osst_class_member,
+                                      &class_device_attr_media_version);
+       if (err)
+               goto err_out;
+       err = class_device_create_file(osst_class_member,
+                                      &class_device_attr_capacity);
+       if (err)
+               goto err_out;
+       err = class_device_create_file(osst_class_member,
+                                      &class_device_attr_BOT_frame);
+       if (err)
+               goto err_out;
+       err = class_device_create_file(osst_class_member,
+                                      &class_device_attr_EOD_frame);
+       if (err)
+               goto err_out;
+       err = class_device_create_file(osst_class_member,
+                                      &class_device_attr_file_count);
+       if (err)
+               goto err_out;
 
-static void osst_sysfs_destroy(dev_t dev)
-{
-       if (!osst_sysfs_valid) return; 
+       return 0;
 
-       class_device_destroy(osst_sysfs_class, dev);
+err_out:
+       osst_sysfs_destroy(dev);
+       return err;
 }
 
 static void osst_sysfs_cleanup(void)
 {
-       if (osst_sysfs_valid) {
-               class_destroy(osst_sysfs_class);
-               osst_sysfs_valid = 0;
-       }
+       class_destroy(osst_sysfs_class);
 }
 
 /*
@@ -5720,7 +5743,7 @@ static int osst_probe(struct device *dev)
        struct st_partstat * STps;
        struct osst_buffer * buffer;
        struct gendisk     * drive;
-       int                  i, dev_num;
+       int                  i, dev_num, err = -ENODEV;
 
        if (SDp->type != TYPE_TAPE || !osst_supports(SDp))
                return -ENODEV;
@@ -5757,13 +5780,12 @@ static int osst_probe(struct device *dev)
        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;
@@ -5845,16 +5867,23 @@ 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);
+
        {
                char name[8];
+
                /*  Rewind entry  */
-               osst_sysfs_add(MKDEV(OSST_MAJOR, dev_num), dev, tpnt, tape_name(tpnt));
+               err = osst_sysfs_add(MKDEV(OSST_MAJOR, dev_num), dev, tpnt, tape_name(tpnt));
+               if (err)
+                       goto out_free_buffer;
+
                /*  No-rewind entry  */
                snprintf(name, 8, "%s%s", "n", tape_name(tpnt));
-               osst_sysfs_add(MKDEV(OSST_MAJOR, dev_num + 128), dev, tpnt, name);
+               err = osst_sysfs_add(MKDEV(OSST_MAJOR, dev_num + 128), dev, tpnt, name);
+               if (err)
+                       goto out_free_sysfs1;
        }
 
        sdev_printk(KERN_INFO, SDp,
@@ -5863,9 +5892,13 @@ static int osst_probe(struct device *dev)
 
        return 0;
 
+out_free_sysfs1:
+       osst_sysfs_destroy(MKDEV(OSST_MAJOR, dev_num));
+out_free_buffer:
+       kfree(buffer);
 out_put_disk:
         put_disk(drive);
-        return -ENODEV;
+        return err;
 };
 
 static int osst_remove(struct device *dev)
@@ -5902,19 +5935,39 @@ static int osst_remove(struct device *dev)
 
 static int __init init_osst(void) 
 {
+       int err;
+
        printk(KERN_INFO "osst :I: Tape driver with OnStream support version %s\nosst :I: %s\n", osst_version, cvsid);
 
        validate_options();
-       osst_sysfs_init();
 
-       if ((register_chrdev(OSST_MAJOR,"osst", &osst_fops) < 0) || scsi_register_driver(&osst_template.gendrv)) {
+       err = osst_sysfs_init();
+       if (err)
+               return err;
+
+       err = register_chrdev(OSST_MAJOR, "osst", &osst_fops);
+       if (err < 0) {
                printk(KERN_ERR "osst :E: Unable to register major %d for OnStream tapes\n", OSST_MAJOR);
-               osst_sysfs_cleanup();
-               return 1;
+               goto err_out;
        }
-       osst_create_driverfs_files(&osst_template.gendrv);
+
+       err = scsi_register_driver(&osst_template.gendrv);
+       if (err)
+               goto err_out_chrdev;
+
+       err = osst_create_sysfs_files(&osst_template.gendrv);
+       if (err)
+               goto err_out_scsidrv;
 
        return 0;
+
+err_out_scsidrv:
+       scsi_unregister_driver(&osst_template.gendrv);
+err_out_chrdev:
+       unregister_chrdev(OSST_MAJOR, "osst");
+err_out:
+       osst_sysfs_cleanup();
+       return err;
 }
 
 static void __exit exit_osst (void)
@@ -5922,7 +5975,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();