diff options
Diffstat (limited to 'drivers/scsi/ch.c')
| -rw-r--r-- | drivers/scsi/ch.c | 92 |
1 files changed, 50 insertions, 42 deletions
diff --git a/drivers/scsi/ch.c b/drivers/scsi/ch.c index 7ab29eaec6f3..fa07a6f54003 100644 --- a/drivers/scsi/ch.c +++ b/drivers/scsi/ch.c @@ -102,7 +102,9 @@ do { \ #define MAX_RETRIES 1 -static struct class * ch_sysfs_class; +static const struct class ch_sysfs_class = { + .name = "scsi_changer", +}; typedef struct { struct kref ref; @@ -113,7 +115,6 @@ typedef struct { struct scsi_device **dt; /* ptrs to data transfer elements */ u_int firsts[CH_TYPES]; u_int counts[CH_TYPES]; - u_int unit_attention; u_int voltags; struct mutex lock; } scsi_changer; @@ -184,34 +185,39 @@ static int ch_find_errno(struct scsi_sense_hdr *sshdr) static int ch_do_scsi(scsi_changer *ch, unsigned char *cmd, int cmd_len, - void *buffer, unsigned buflength, - enum dma_data_direction direction) + void *buffer, unsigned int buflength, enum req_op op) { - int errno, retries = 0, timeout, result; + int errno = 0, timeout, result; struct scsi_sense_hdr sshdr; + struct scsi_failure failure_defs[] = { + { + .sense = UNIT_ATTENTION, + .asc = SCMD_FAILURE_ASC_ANY, + .ascq = SCMD_FAILURE_ASCQ_ANY, + .allowed = 3, + .result = SAM_STAT_CHECK_CONDITION, + }, + {} + }; + struct scsi_failures failures = { + .failure_definitions = failure_defs, + }; + const struct scsi_exec_args exec_args = { + .sshdr = &sshdr, + .failures = &failures, + }; timeout = (cmd[0] == INITIALIZE_ELEMENT_STATUS) ? timeout_init : timeout_move; - retry: - errno = 0; - result = scsi_execute_req(ch->device, cmd, direction, buffer, - buflength, &sshdr, timeout * HZ, - MAX_RETRIES, NULL); + result = scsi_execute_cmd(ch->device, cmd, op, buffer, buflength, + timeout * HZ, MAX_RETRIES, &exec_args); if (result < 0) return result; if (scsi_sense_valid(&sshdr)) { if (debug) scsi_print_sense_hdr(ch->device, ch->name, &sshdr); errno = ch_find_errno(&sshdr); - - switch(sshdr.sense_key) { - case UNIT_ATTENTION: - ch->unit_attention = 1; - if (retries++ < 3) - goto retry; - break; - } } return errno; } @@ -254,7 +260,7 @@ ch_read_element_status(scsi_changer *ch, u_int elem, char *data) cmd[5] = 1; cmd[9] = 255; if (0 == (result = ch_do_scsi(ch, cmd, 12, - buffer, 256, DMA_FROM_DEVICE))) { + buffer, 256, REQ_OP_DRV_IN))) { if (((buffer[16] << 8) | buffer[17]) != elem) { DPRINTK("asked for element 0x%02x, got 0x%02x\n", elem,(buffer[16] << 8) | buffer[17]); @@ -284,7 +290,7 @@ ch_init_elem(scsi_changer *ch) memset(cmd,0,sizeof(cmd)); cmd[0] = INITIALIZE_ELEMENT_STATUS; cmd[1] = (ch->device->lun & 0x7) << 5; - err = ch_do_scsi(ch, cmd, 6, NULL, 0, DMA_NONE); + err = ch_do_scsi(ch, cmd, 6, NULL, 0, REQ_OP_DRV_IN); VPRINTK(KERN_INFO, "... finished\n"); return err; } @@ -306,10 +312,10 @@ ch_readconfig(scsi_changer *ch) cmd[1] = (ch->device->lun & 0x7) << 5; cmd[2] = 0x1d; cmd[4] = 255; - result = ch_do_scsi(ch, cmd, 10, buffer, 255, DMA_FROM_DEVICE); + result = ch_do_scsi(ch, cmd, 10, buffer, 255, REQ_OP_DRV_IN); if (0 != result) { cmd[1] |= (1<<3); - result = ch_do_scsi(ch, cmd, 10, buffer, 255, DMA_FROM_DEVICE); + result = ch_do_scsi(ch, cmd, 10, buffer, 255, REQ_OP_DRV_IN); } if (0 == result) { ch->firsts[CHET_MT] = @@ -434,7 +440,7 @@ ch_position(scsi_changer *ch, u_int trans, u_int elem, int rotate) cmd[4] = (elem >> 8) & 0xff; cmd[5] = elem & 0xff; cmd[8] = rotate ? 1 : 0; - return ch_do_scsi(ch, cmd, 10, NULL, 0, DMA_NONE); + return ch_do_scsi(ch, cmd, 10, NULL, 0, REQ_OP_DRV_IN); } static int @@ -455,7 +461,7 @@ ch_move(scsi_changer *ch, u_int trans, u_int src, u_int dest, int rotate) cmd[6] = (dest >> 8) & 0xff; cmd[7] = dest & 0xff; cmd[10] = rotate ? 1 : 0; - return ch_do_scsi(ch, cmd, 12, NULL,0, DMA_NONE); + return ch_do_scsi(ch, cmd, 12, NULL, 0, REQ_OP_DRV_IN); } static int @@ -481,7 +487,7 @@ ch_exchange(scsi_changer *ch, u_int trans, u_int src, cmd[9] = dest2 & 0xff; cmd[10] = (rotate1 ? 1 : 0) | (rotate2 ? 2 : 0); - return ch_do_scsi(ch, cmd, 12, NULL, 0, DMA_NONE); + return ch_do_scsi(ch, cmd, 12, NULL, 0, REQ_OP_DRV_IN); } static void @@ -531,7 +537,7 @@ ch_set_voltag(scsi_changer *ch, u_int elem, memcpy(buffer,tag,32); ch_check_voltag(buffer); - result = ch_do_scsi(ch, cmd, 12, buffer, 256, DMA_TO_DEVICE); + result = ch_do_scsi(ch, cmd, 12, buffer, 256, REQ_OP_DRV_OUT); kfree(buffer); return result; } @@ -658,19 +664,23 @@ static long ch_ioctl(struct file *file, memset(&vparams,0,sizeof(vparams)); if (ch->counts[CHET_V1]) { vparams.cvp_n1 = ch->counts[CHET_V1]; - strncpy(vparams.cvp_label1,vendor_labels[0],16); + strscpy(vparams.cvp_label1, vendor_labels[0], + sizeof(vparams.cvp_label1)); } if (ch->counts[CHET_V2]) { vparams.cvp_n2 = ch->counts[CHET_V2]; - strncpy(vparams.cvp_label2,vendor_labels[1],16); + strscpy(vparams.cvp_label2, vendor_labels[1], + sizeof(vparams.cvp_label2)); } if (ch->counts[CHET_V3]) { vparams.cvp_n3 = ch->counts[CHET_V3]; - strncpy(vparams.cvp_label3,vendor_labels[2],16); + strscpy(vparams.cvp_label3, vendor_labels[2], + sizeof(vparams.cvp_label3)); } if (ch->counts[CHET_V4]) { vparams.cvp_n4 = ch->counts[CHET_V4]; - strncpy(vparams.cvp_label4,vendor_labels[3],16); + strscpy(vparams.cvp_label4, vendor_labels[3], + sizeof(vparams.cvp_label4)); } if (copy_to_user(argp, &vparams, sizeof(vparams))) return -EFAULT; @@ -799,8 +809,7 @@ static long ch_ioctl(struct file *file, ch_cmd[5] = 1; ch_cmd[9] = 255; - result = ch_do_scsi(ch, ch_cmd, 12, - buffer, 256, DMA_FROM_DEVICE); + result = ch_do_scsi(ch, ch_cmd, 12, buffer, 256, REQ_OP_DRV_IN); if (!result) { cge.cge_status = buffer[18]; cge.cge_flags = 0; @@ -877,7 +886,8 @@ static long ch_ioctl(struct file *file, } default: - return scsi_ioctl(ch->device, file->f_mode, cmd, argp); + return scsi_ioctl(ch->device, file->f_mode & FMODE_WRITE, cmd, + argp); } } @@ -922,7 +932,7 @@ static int ch_probe(struct device *dev) mutex_init(&ch->lock); kref_init(&ch->ref); ch->device = sd; - class_dev = device_create(ch_sysfs_class, dev, + class_dev = device_create(&ch_sysfs_class, dev, MKDEV(SCSI_CHANGER_MAJOR, ch->minor), ch, "s%s", ch->name); if (IS_ERR(class_dev)) { @@ -947,7 +957,7 @@ static int ch_probe(struct device *dev) return 0; destroy_dev: - device_destroy(ch_sysfs_class, MKDEV(SCSI_CHANGER_MAJOR, ch->minor)); + device_destroy(&ch_sysfs_class, MKDEV(SCSI_CHANGER_MAJOR, ch->minor)); put_device: scsi_device_put(sd); remove_idr: @@ -966,7 +976,7 @@ static int ch_remove(struct device *dev) dev_set_drvdata(dev, NULL); spin_unlock(&ch_index_lock); - device_destroy(ch_sysfs_class, MKDEV(SCSI_CHANGER_MAJOR,ch->minor)); + device_destroy(&ch_sysfs_class, MKDEV(SCSI_CHANGER_MAJOR, ch->minor)); scsi_device_put(ch->device); kref_put(&ch->ref, ch_destroy); return 0; @@ -995,11 +1005,9 @@ static int __init init_ch_module(void) int rc; printk(KERN_INFO "SCSI Media Changer driver v" VERSION " \n"); - ch_sysfs_class = class_create(THIS_MODULE, "scsi_changer"); - if (IS_ERR(ch_sysfs_class)) { - rc = PTR_ERR(ch_sysfs_class); + rc = class_register(&ch_sysfs_class); + if (rc) return rc; - } rc = register_chrdev(SCSI_CHANGER_MAJOR,"ch",&changer_fops); if (rc < 0) { printk("Unable to get major %d for SCSI-Changer\n", @@ -1014,7 +1022,7 @@ static int __init init_ch_module(void) fail2: unregister_chrdev(SCSI_CHANGER_MAJOR, "ch"); fail1: - class_destroy(ch_sysfs_class); + class_unregister(&ch_sysfs_class); return rc; } @@ -1022,7 +1030,7 @@ static void __exit exit_ch_module(void) { scsi_unregister_driver(&ch_template.gendrv); unregister_chrdev(SCSI_CHANGER_MAJOR, "ch"); - class_destroy(ch_sysfs_class); + class_unregister(&ch_sysfs_class); idr_destroy(&ch_index_idr); } |
