Loading drivers/block/paride/pcd.c +127 −159 Original line number Diff line number Diff line Loading @@ -183,8 +183,6 @@ static int pcd_audio_ioctl(struct cdrom_device_info *cdi, static int pcd_packet(struct cdrom_device_info *cdi, struct packet_command *cgc); static int pcd_detect(void); static void pcd_probe_capabilities(void); static void do_pcd_read_drq(void); static blk_status_t pcd_queue_rq(struct blk_mq_hw_ctx *hctx, const struct blk_mq_queue_data *bd); Loading Loading @@ -302,53 +300,6 @@ static const struct blk_mq_ops pcd_mq_ops = { .queue_rq = pcd_queue_rq, }; static void pcd_init_units(void) { struct pcd_unit *cd; int unit; pcd_drive_count = 0; for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) { struct gendisk *disk; if (blk_mq_alloc_sq_tag_set(&cd->tag_set, &pcd_mq_ops, 1, BLK_MQ_F_SHOULD_MERGE)) continue; disk = blk_mq_alloc_disk(&cd->tag_set, cd); if (IS_ERR(disk)) { blk_mq_free_tag_set(&cd->tag_set); continue; } INIT_LIST_HEAD(&cd->rq_list); blk_queue_bounce_limit(disk->queue, BLK_BOUNCE_HIGH); cd->disk = disk; cd->pi = &cd->pia; cd->present = 0; cd->last_sense = 0; cd->changed = 1; cd->drive = (*drives[unit])[D_SLV]; if ((*drives[unit])[D_PRT]) pcd_drive_count++; cd->name = &cd->info.name[0]; snprintf(cd->name, sizeof(cd->info.name), "%s%d", name, unit); cd->info.ops = &pcd_dops; cd->info.handle = cd; cd->info.speed = 0; cd->info.capacity = 1; cd->info.mask = 0; disk->major = major; disk->first_minor = unit; disk->minors = 1; strcpy(disk->disk_name, cd->name); /* umm... */ disk->fops = &pcd_bdops; disk->flags = GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE; disk->events = DISK_EVENT_MEDIA_CHANGE; } } static int pcd_open(struct cdrom_device_info *cdi, int purpose) { struct pcd_unit *cd = cdi->handle; Loading Loading @@ -679,19 +630,16 @@ static int pcd_probe(struct pcd_unit *cd, int ms) return -1; } static void pcd_probe_capabilities(void) static int pcd_probe_capabilities(struct pcd_unit *cd) { int unit, r; char buffer[32]; char cmd[12] = { 0x5a, 1 << 3, 0x2a, 0, 0, 0, 0, 18, 0, 0, 0, 0 }; struct pcd_unit *cd; char buffer[32]; int ret; ret = pcd_atapi(cd, cmd, 18, buffer, "mode sense capabilities"); if (ret) return ret; for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) { if (!cd->present) continue; r = pcd_atapi(cd, cmd, 18, buffer, "mode sense capabilities"); if (r) continue; /* we should now have the cap page */ if ((buffer[11] & 1) == 0) cd->info.mask |= CDC_CD_R; Loading @@ -705,64 +653,8 @@ static void pcd_probe_capabilities(void) cd->info.mask |= CDC_OPEN_TRAY; if ((buffer[14] >> 6) == 0) cd->info.mask |= CDC_CLOSE_TRAY; } } static int pcd_detect(void) { int k, unit; struct pcd_unit *cd; printk("%s: %s version %s, major %d, nice %d\n", name, name, PCD_VERSION, major, nice); par_drv = pi_register_driver(name); if (!par_drv) { pr_err("failed to register %s driver\n", name); return -1; } k = 0; if (pcd_drive_count == 0) { /* nothing spec'd - so autoprobe for 1 */ cd = pcd; if (cd->disk && pi_init(cd->pi, 1, -1, -1, -1, -1, -1, pcd_buffer, PI_PCD, verbose, cd->name)) { if (!pcd_probe(cd, -1)) { cd->present = 1; k++; } else pi_release(cd->pi); } } else { for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) { int *conf = *drives[unit]; if (!conf[D_PRT]) continue; if (!cd->disk) continue; if (!pi_init(cd->pi, 0, conf[D_PRT], conf[D_MOD], conf[D_UNI], conf[D_PRO], conf[D_DLY], pcd_buffer, PI_PCD, verbose, cd->name)) continue; if (!pcd_probe(cd, conf[D_SLV])) { cd->present = 1; k++; } else pi_release(cd->pi); } } if (k) return 0; printk("%s: No CD-ROM drive found\n", name); for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) { if (!cd->disk) continue; blk_cleanup_disk(cd->disk); blk_mq_free_tag_set(&cd->tag_set); } pi_unregister_driver(par_drv); return -1; } /* I/O request processing */ Loading Loading @@ -999,43 +891,121 @@ static int pcd_get_mcn(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn) return 0; } static int __init pcd_init(void) static int pcd_init_unit(struct pcd_unit *cd, bool autoprobe, int port, int mode, int unit, int protocol, int delay, int ms) { struct pcd_unit *cd; int unit; struct gendisk *disk; int ret; if (disable) return -EINVAL; ret = blk_mq_alloc_sq_tag_set(&cd->tag_set, &pcd_mq_ops, 1, BLK_MQ_F_SHOULD_MERGE); if (ret) return ret; pcd_init_units(); disk = blk_mq_alloc_disk(&cd->tag_set, cd); if (IS_ERR(disk)) { ret = PTR_ERR(disk); goto out_free_tag_set; } if (pcd_detect()) return -ENODEV; INIT_LIST_HEAD(&cd->rq_list); blk_queue_bounce_limit(disk->queue, BLK_BOUNCE_HIGH); cd->disk = disk; cd->pi = &cd->pia; cd->present = 0; cd->last_sense = 0; cd->changed = 1; cd->drive = (*drives[cd - pcd])[D_SLV]; /* get the atapi capabilities page */ pcd_probe_capabilities(); cd->name = &cd->info.name[0]; snprintf(cd->name, sizeof(cd->info.name), "%s%d", name, unit); cd->info.ops = &pcd_dops; cd->info.handle = cd; cd->info.speed = 0; cd->info.capacity = 1; cd->info.mask = 0; disk->major = major; disk->first_minor = unit; disk->minors = 1; strcpy(disk->disk_name, cd->name); /* umm... */ disk->fops = &pcd_bdops; disk->flags = GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE; disk->events = DISK_EVENT_MEDIA_CHANGE; if (register_blkdev(major, name)) { for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) { if (!cd->disk) continue; if (!pi_init(cd->pi, autoprobe, port, mode, unit, protocol, delay, pcd_buffer, PI_PCD, verbose, cd->name)) goto out_free_disk; if (pcd_probe(cd, ms)) goto out_pi_release; blk_cleanup_queue(cd->disk->queue); cd->present = 1; pcd_probe_capabilities(cd); register_cdrom(cd->disk, &cd->info); add_disk(cd->disk); return 0; out_pi_release: pi_release(cd->pi); out_free_disk: blk_cleanup_disk(cd->disk); out_free_tag_set: blk_mq_free_tag_set(&cd->tag_set); put_disk(cd->disk); return ret; } static int __init pcd_init(void) { int found = 0, unit; if (disable) return -EINVAL; if (register_blkdev(major, name)) return -EBUSY; pr_info("%s: %s version %s, major %d, nice %d\n", name, name, PCD_VERSION, major, nice); par_drv = pi_register_driver(name); if (!par_drv) { pr_err("failed to register %s driver\n", name); goto out_unregister_blkdev; } for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) { if (cd->present) { register_cdrom(cd->disk, &cd->info); cd->disk->private_data = cd; add_disk(cd->disk); for (unit = 0; unit < PCD_UNITS; unit++) { if ((*drives[unit])[D_PRT]) pcd_drive_count++; } if (pcd_drive_count == 0) { /* nothing spec'd - so autoprobe for 1 */ if (!pcd_init_unit(pcd, 1, -1, -1, -1, -1, -1, -1)) found++; } else { for (unit = 0; unit < PCD_UNITS; unit++) { struct pcd_unit *cd = &pcd[unit]; int *conf = *drives[unit]; if (!conf[D_PRT]) continue; if (!pcd_init_unit(cd, 0, conf[D_PRT], conf[D_MOD], conf[D_UNI], conf[D_PRO], conf[D_DLY], conf[D_SLV])) found++; } } if (!found) { pr_info("%s: No CD-ROM drive found\n", name); goto out_unregister_pi_driver; } return 0; out_unregister_pi_driver: pi_unregister_driver(par_drv); out_unregister_blkdev: unregister_blkdev(major, name); return -ENODEV; } static void __exit pcd_exit(void) Loading @@ -1044,20 +1014,18 @@ static void __exit pcd_exit(void) int unit; for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) { if (!cd->disk) if (!cd->present) continue; if (cd->present) { del_gendisk(cd->disk); pi_release(cd->pi); unregister_cdrom(&cd->info); } blk_cleanup_queue(cd->disk->queue); blk_cleanup_disk(cd->disk); blk_mq_free_tag_set(&cd->tag_set); put_disk(cd->disk); } unregister_blkdev(major, name); pi_unregister_driver(par_drv); unregister_blkdev(major, name); } MODULE_LICENSE("GPL"); Loading Loading
drivers/block/paride/pcd.c +127 −159 Original line number Diff line number Diff line Loading @@ -183,8 +183,6 @@ static int pcd_audio_ioctl(struct cdrom_device_info *cdi, static int pcd_packet(struct cdrom_device_info *cdi, struct packet_command *cgc); static int pcd_detect(void); static void pcd_probe_capabilities(void); static void do_pcd_read_drq(void); static blk_status_t pcd_queue_rq(struct blk_mq_hw_ctx *hctx, const struct blk_mq_queue_data *bd); Loading Loading @@ -302,53 +300,6 @@ static const struct blk_mq_ops pcd_mq_ops = { .queue_rq = pcd_queue_rq, }; static void pcd_init_units(void) { struct pcd_unit *cd; int unit; pcd_drive_count = 0; for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) { struct gendisk *disk; if (blk_mq_alloc_sq_tag_set(&cd->tag_set, &pcd_mq_ops, 1, BLK_MQ_F_SHOULD_MERGE)) continue; disk = blk_mq_alloc_disk(&cd->tag_set, cd); if (IS_ERR(disk)) { blk_mq_free_tag_set(&cd->tag_set); continue; } INIT_LIST_HEAD(&cd->rq_list); blk_queue_bounce_limit(disk->queue, BLK_BOUNCE_HIGH); cd->disk = disk; cd->pi = &cd->pia; cd->present = 0; cd->last_sense = 0; cd->changed = 1; cd->drive = (*drives[unit])[D_SLV]; if ((*drives[unit])[D_PRT]) pcd_drive_count++; cd->name = &cd->info.name[0]; snprintf(cd->name, sizeof(cd->info.name), "%s%d", name, unit); cd->info.ops = &pcd_dops; cd->info.handle = cd; cd->info.speed = 0; cd->info.capacity = 1; cd->info.mask = 0; disk->major = major; disk->first_minor = unit; disk->minors = 1; strcpy(disk->disk_name, cd->name); /* umm... */ disk->fops = &pcd_bdops; disk->flags = GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE; disk->events = DISK_EVENT_MEDIA_CHANGE; } } static int pcd_open(struct cdrom_device_info *cdi, int purpose) { struct pcd_unit *cd = cdi->handle; Loading Loading @@ -679,19 +630,16 @@ static int pcd_probe(struct pcd_unit *cd, int ms) return -1; } static void pcd_probe_capabilities(void) static int pcd_probe_capabilities(struct pcd_unit *cd) { int unit, r; char buffer[32]; char cmd[12] = { 0x5a, 1 << 3, 0x2a, 0, 0, 0, 0, 18, 0, 0, 0, 0 }; struct pcd_unit *cd; char buffer[32]; int ret; ret = pcd_atapi(cd, cmd, 18, buffer, "mode sense capabilities"); if (ret) return ret; for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) { if (!cd->present) continue; r = pcd_atapi(cd, cmd, 18, buffer, "mode sense capabilities"); if (r) continue; /* we should now have the cap page */ if ((buffer[11] & 1) == 0) cd->info.mask |= CDC_CD_R; Loading @@ -705,64 +653,8 @@ static void pcd_probe_capabilities(void) cd->info.mask |= CDC_OPEN_TRAY; if ((buffer[14] >> 6) == 0) cd->info.mask |= CDC_CLOSE_TRAY; } } static int pcd_detect(void) { int k, unit; struct pcd_unit *cd; printk("%s: %s version %s, major %d, nice %d\n", name, name, PCD_VERSION, major, nice); par_drv = pi_register_driver(name); if (!par_drv) { pr_err("failed to register %s driver\n", name); return -1; } k = 0; if (pcd_drive_count == 0) { /* nothing spec'd - so autoprobe for 1 */ cd = pcd; if (cd->disk && pi_init(cd->pi, 1, -1, -1, -1, -1, -1, pcd_buffer, PI_PCD, verbose, cd->name)) { if (!pcd_probe(cd, -1)) { cd->present = 1; k++; } else pi_release(cd->pi); } } else { for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) { int *conf = *drives[unit]; if (!conf[D_PRT]) continue; if (!cd->disk) continue; if (!pi_init(cd->pi, 0, conf[D_PRT], conf[D_MOD], conf[D_UNI], conf[D_PRO], conf[D_DLY], pcd_buffer, PI_PCD, verbose, cd->name)) continue; if (!pcd_probe(cd, conf[D_SLV])) { cd->present = 1; k++; } else pi_release(cd->pi); } } if (k) return 0; printk("%s: No CD-ROM drive found\n", name); for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) { if (!cd->disk) continue; blk_cleanup_disk(cd->disk); blk_mq_free_tag_set(&cd->tag_set); } pi_unregister_driver(par_drv); return -1; } /* I/O request processing */ Loading Loading @@ -999,43 +891,121 @@ static int pcd_get_mcn(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn) return 0; } static int __init pcd_init(void) static int pcd_init_unit(struct pcd_unit *cd, bool autoprobe, int port, int mode, int unit, int protocol, int delay, int ms) { struct pcd_unit *cd; int unit; struct gendisk *disk; int ret; if (disable) return -EINVAL; ret = blk_mq_alloc_sq_tag_set(&cd->tag_set, &pcd_mq_ops, 1, BLK_MQ_F_SHOULD_MERGE); if (ret) return ret; pcd_init_units(); disk = blk_mq_alloc_disk(&cd->tag_set, cd); if (IS_ERR(disk)) { ret = PTR_ERR(disk); goto out_free_tag_set; } if (pcd_detect()) return -ENODEV; INIT_LIST_HEAD(&cd->rq_list); blk_queue_bounce_limit(disk->queue, BLK_BOUNCE_HIGH); cd->disk = disk; cd->pi = &cd->pia; cd->present = 0; cd->last_sense = 0; cd->changed = 1; cd->drive = (*drives[cd - pcd])[D_SLV]; /* get the atapi capabilities page */ pcd_probe_capabilities(); cd->name = &cd->info.name[0]; snprintf(cd->name, sizeof(cd->info.name), "%s%d", name, unit); cd->info.ops = &pcd_dops; cd->info.handle = cd; cd->info.speed = 0; cd->info.capacity = 1; cd->info.mask = 0; disk->major = major; disk->first_minor = unit; disk->minors = 1; strcpy(disk->disk_name, cd->name); /* umm... */ disk->fops = &pcd_bdops; disk->flags = GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE; disk->events = DISK_EVENT_MEDIA_CHANGE; if (register_blkdev(major, name)) { for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) { if (!cd->disk) continue; if (!pi_init(cd->pi, autoprobe, port, mode, unit, protocol, delay, pcd_buffer, PI_PCD, verbose, cd->name)) goto out_free_disk; if (pcd_probe(cd, ms)) goto out_pi_release; blk_cleanup_queue(cd->disk->queue); cd->present = 1; pcd_probe_capabilities(cd); register_cdrom(cd->disk, &cd->info); add_disk(cd->disk); return 0; out_pi_release: pi_release(cd->pi); out_free_disk: blk_cleanup_disk(cd->disk); out_free_tag_set: blk_mq_free_tag_set(&cd->tag_set); put_disk(cd->disk); return ret; } static int __init pcd_init(void) { int found = 0, unit; if (disable) return -EINVAL; if (register_blkdev(major, name)) return -EBUSY; pr_info("%s: %s version %s, major %d, nice %d\n", name, name, PCD_VERSION, major, nice); par_drv = pi_register_driver(name); if (!par_drv) { pr_err("failed to register %s driver\n", name); goto out_unregister_blkdev; } for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) { if (cd->present) { register_cdrom(cd->disk, &cd->info); cd->disk->private_data = cd; add_disk(cd->disk); for (unit = 0; unit < PCD_UNITS; unit++) { if ((*drives[unit])[D_PRT]) pcd_drive_count++; } if (pcd_drive_count == 0) { /* nothing spec'd - so autoprobe for 1 */ if (!pcd_init_unit(pcd, 1, -1, -1, -1, -1, -1, -1)) found++; } else { for (unit = 0; unit < PCD_UNITS; unit++) { struct pcd_unit *cd = &pcd[unit]; int *conf = *drives[unit]; if (!conf[D_PRT]) continue; if (!pcd_init_unit(cd, 0, conf[D_PRT], conf[D_MOD], conf[D_UNI], conf[D_PRO], conf[D_DLY], conf[D_SLV])) found++; } } if (!found) { pr_info("%s: No CD-ROM drive found\n", name); goto out_unregister_pi_driver; } return 0; out_unregister_pi_driver: pi_unregister_driver(par_drv); out_unregister_blkdev: unregister_blkdev(major, name); return -ENODEV; } static void __exit pcd_exit(void) Loading @@ -1044,20 +1014,18 @@ static void __exit pcd_exit(void) int unit; for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) { if (!cd->disk) if (!cd->present) continue; if (cd->present) { del_gendisk(cd->disk); pi_release(cd->pi); unregister_cdrom(&cd->info); } blk_cleanup_queue(cd->disk->queue); blk_cleanup_disk(cd->disk); blk_mq_free_tag_set(&cd->tag_set); put_disk(cd->disk); } unregister_blkdev(major, name); pi_unregister_driver(par_drv); unregister_blkdev(major, name); } MODULE_LICENSE("GPL"); Loading