aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/pktcdvd.c
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@infradead.org>2006-02-06 07:43:13 -0500
committerMauro Carvalho Chehab <mchehab@infradead.org>2006-02-06 07:43:13 -0500
commitb2faf597d93bdf5e2d12d93ea0815935a73f749e (patch)
tree1876616290ff282b8a0814e2429d23e0104f3701 /drivers/block/pktcdvd.c
parent638e174688f58200d0deb7435093435e7d737b09 (diff)
parent410c05427a69f53851637ccb85c2212131409fbd (diff)
Merge branch 'origin'
Diffstat (limited to 'drivers/block/pktcdvd.c')
-rw-r--r--drivers/block/pktcdvd.c58
1 files changed, 29 insertions, 29 deletions
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index 93affeeef7bd..4e7dbcc425ff 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -43,8 +43,6 @@
43 * 43 *
44 *************************************************************************/ 44 *************************************************************************/
45 45
46#define VERSION_CODE "v0.2.0a 2004-07-14 Jens Axboe (axboe@suse.de) and petero2@telia.com"
47
48#include <linux/pktcdvd.h> 46#include <linux/pktcdvd.h>
49#include <linux/config.h> 47#include <linux/config.h>
50#include <linux/module.h> 48#include <linux/module.h>
@@ -131,7 +129,7 @@ static struct bio *pkt_bio_alloc(int nr_iovecs)
131/* 129/*
132 * Allocate a packet_data struct 130 * Allocate a packet_data struct
133 */ 131 */
134static struct packet_data *pkt_alloc_packet_data(void) 132static struct packet_data *pkt_alloc_packet_data(int frames)
135{ 133{
136 int i; 134 int i;
137 struct packet_data *pkt; 135 struct packet_data *pkt;
@@ -140,11 +138,12 @@ static struct packet_data *pkt_alloc_packet_data(void)
140 if (!pkt) 138 if (!pkt)
141 goto no_pkt; 139 goto no_pkt;
142 140
143 pkt->w_bio = pkt_bio_alloc(PACKET_MAX_SIZE); 141 pkt->frames = frames;
142 pkt->w_bio = pkt_bio_alloc(frames);
144 if (!pkt->w_bio) 143 if (!pkt->w_bio)
145 goto no_bio; 144 goto no_bio;
146 145
147 for (i = 0; i < PAGES_PER_PACKET; i++) { 146 for (i = 0; i < frames / FRAMES_PER_PAGE; i++) {
148 pkt->pages[i] = alloc_page(GFP_KERNEL|__GFP_ZERO); 147 pkt->pages[i] = alloc_page(GFP_KERNEL|__GFP_ZERO);
149 if (!pkt->pages[i]) 148 if (!pkt->pages[i])
150 goto no_page; 149 goto no_page;
@@ -152,7 +151,7 @@ static struct packet_data *pkt_alloc_packet_data(void)
152 151
153 spin_lock_init(&pkt->lock); 152 spin_lock_init(&pkt->lock);
154 153
155 for (i = 0; i < PACKET_MAX_SIZE; i++) { 154 for (i = 0; i < frames; i++) {
156 struct bio *bio = pkt_bio_alloc(1); 155 struct bio *bio = pkt_bio_alloc(1);
157 if (!bio) 156 if (!bio)
158 goto no_rd_bio; 157 goto no_rd_bio;
@@ -162,14 +161,14 @@ static struct packet_data *pkt_alloc_packet_data(void)
162 return pkt; 161 return pkt;
163 162
164no_rd_bio: 163no_rd_bio:
165 for (i = 0; i < PACKET_MAX_SIZE; i++) { 164 for (i = 0; i < frames; i++) {
166 struct bio *bio = pkt->r_bios[i]; 165 struct bio *bio = pkt->r_bios[i];
167 if (bio) 166 if (bio)
168 bio_put(bio); 167 bio_put(bio);
169 } 168 }
170 169
171no_page: 170no_page:
172 for (i = 0; i < PAGES_PER_PACKET; i++) 171 for (i = 0; i < frames / FRAMES_PER_PAGE; i++)
173 if (pkt->pages[i]) 172 if (pkt->pages[i])
174 __free_page(pkt->pages[i]); 173 __free_page(pkt->pages[i]);
175 bio_put(pkt->w_bio); 174 bio_put(pkt->w_bio);
@@ -186,12 +185,12 @@ static void pkt_free_packet_data(struct packet_data *pkt)
186{ 185{
187 int i; 186 int i;
188 187
189 for (i = 0; i < PACKET_MAX_SIZE; i++) { 188 for (i = 0; i < pkt->frames; i++) {
190 struct bio *bio = pkt->r_bios[i]; 189 struct bio *bio = pkt->r_bios[i];
191 if (bio) 190 if (bio)
192 bio_put(bio); 191 bio_put(bio);
193 } 192 }
194 for (i = 0; i < PAGES_PER_PACKET; i++) 193 for (i = 0; i < pkt->frames / FRAMES_PER_PAGE; i++)
195 __free_page(pkt->pages[i]); 194 __free_page(pkt->pages[i]);
196 bio_put(pkt->w_bio); 195 bio_put(pkt->w_bio);
197 kfree(pkt); 196 kfree(pkt);
@@ -206,17 +205,17 @@ static void pkt_shrink_pktlist(struct pktcdvd_device *pd)
206 list_for_each_entry_safe(pkt, next, &pd->cdrw.pkt_free_list, list) { 205 list_for_each_entry_safe(pkt, next, &pd->cdrw.pkt_free_list, list) {
207 pkt_free_packet_data(pkt); 206 pkt_free_packet_data(pkt);
208 } 207 }
208 INIT_LIST_HEAD(&pd->cdrw.pkt_free_list);
209} 209}
210 210
211static int pkt_grow_pktlist(struct pktcdvd_device *pd, int nr_packets) 211static int pkt_grow_pktlist(struct pktcdvd_device *pd, int nr_packets)
212{ 212{
213 struct packet_data *pkt; 213 struct packet_data *pkt;
214 214
215 INIT_LIST_HEAD(&pd->cdrw.pkt_free_list); 215 BUG_ON(!list_empty(&pd->cdrw.pkt_free_list));
216 INIT_LIST_HEAD(&pd->cdrw.pkt_active_list); 216
217 spin_lock_init(&pd->cdrw.active_list_lock);
218 while (nr_packets > 0) { 217 while (nr_packets > 0) {
219 pkt = pkt_alloc_packet_data(); 218 pkt = pkt_alloc_packet_data(pd->settings.size >> 2);
220 if (!pkt) { 219 if (!pkt) {
221 pkt_shrink_pktlist(pd); 220 pkt_shrink_pktlist(pd);
222 return 0; 221 return 0;
@@ -951,7 +950,7 @@ try_next_bio:
951 950
952 pd->current_sector = zone + pd->settings.size; 951 pd->current_sector = zone + pd->settings.size;
953 pkt->sector = zone; 952 pkt->sector = zone;
954 pkt->frames = pd->settings.size >> 2; 953 BUG_ON(pkt->frames != pd->settings.size >> 2);
955 pkt->write_size = 0; 954 pkt->write_size = 0;
956 955
957 /* 956 /*
@@ -1639,7 +1638,7 @@ static int pkt_probe_settings(struct pktcdvd_device *pd)
1639 pd->settings.size = be32_to_cpu(ti.fixed_packet_size) << 2; 1638 pd->settings.size = be32_to_cpu(ti.fixed_packet_size) << 2;
1640 if (pd->settings.size == 0) { 1639 if (pd->settings.size == 0) {
1641 printk("pktcdvd: detected zero packet size!\n"); 1640 printk("pktcdvd: detected zero packet size!\n");
1642 pd->settings.size = 128; 1641 return -ENXIO;
1643 } 1642 }
1644 if (pd->settings.size > PACKET_MAX_SECTORS) { 1643 if (pd->settings.size > PACKET_MAX_SECTORS) {
1645 printk("pktcdvd: packet size is too big\n"); 1644 printk("pktcdvd: packet size is too big\n");
@@ -1987,8 +1986,14 @@ static int pkt_open_dev(struct pktcdvd_device *pd, int write)
1987 if ((ret = pkt_set_segment_merging(pd, q))) 1986 if ((ret = pkt_set_segment_merging(pd, q)))
1988 goto out_unclaim; 1987 goto out_unclaim;
1989 1988
1990 if (write) 1989 if (write) {
1990 if (!pkt_grow_pktlist(pd, CONFIG_CDROM_PKTCDVD_BUFFERS)) {
1991 printk("pktcdvd: not enough memory for buffers\n");
1992 ret = -ENOMEM;
1993 goto out_unclaim;
1994 }
1991 printk("pktcdvd: %lukB available on disc\n", lba << 1); 1995 printk("pktcdvd: %lukB available on disc\n", lba << 1);
1996 }
1992 1997
1993 return 0; 1998 return 0;
1994 1999
@@ -2014,6 +2019,8 @@ static void pkt_release_dev(struct pktcdvd_device *pd, int flush)
2014 pkt_set_speed(pd, MAX_SPEED, MAX_SPEED); 2019 pkt_set_speed(pd, MAX_SPEED, MAX_SPEED);
2015 bd_release(pd->bdev); 2020 bd_release(pd->bdev);
2016 blkdev_put(pd->bdev); 2021 blkdev_put(pd->bdev);
2022
2023 pkt_shrink_pktlist(pd);
2017} 2024}
2018 2025
2019static struct pktcdvd_device *pkt_find_dev_from_minor(int dev_minor) 2026static struct pktcdvd_device *pkt_find_dev_from_minor(int dev_minor)
@@ -2379,12 +2386,6 @@ static int pkt_new_dev(struct pktcdvd_device *pd, dev_t dev)
2379 /* This is safe, since we have a reference from open(). */ 2386 /* This is safe, since we have a reference from open(). */
2380 __module_get(THIS_MODULE); 2387 __module_get(THIS_MODULE);
2381 2388
2382 if (!pkt_grow_pktlist(pd, CONFIG_CDROM_PKTCDVD_BUFFERS)) {
2383 printk("pktcdvd: not enough memory for buffers\n");
2384 ret = -ENOMEM;
2385 goto out_mem;
2386 }
2387
2388 pd->bdev = bdev; 2389 pd->bdev = bdev;
2389 set_blocksize(bdev, CD_FRAMESIZE); 2390 set_blocksize(bdev, CD_FRAMESIZE);
2390 2391
@@ -2395,7 +2396,7 @@ static int pkt_new_dev(struct pktcdvd_device *pd, dev_t dev)
2395 if (IS_ERR(pd->cdrw.thread)) { 2396 if (IS_ERR(pd->cdrw.thread)) {
2396 printk("pktcdvd: can't start kernel thread\n"); 2397 printk("pktcdvd: can't start kernel thread\n");
2397 ret = -ENOMEM; 2398 ret = -ENOMEM;
2398 goto out_thread; 2399 goto out_mem;
2399 } 2400 }
2400 2401
2401 proc = create_proc_entry(pd->name, 0, pkt_proc); 2402 proc = create_proc_entry(pd->name, 0, pkt_proc);
@@ -2406,8 +2407,6 @@ static int pkt_new_dev(struct pktcdvd_device *pd, dev_t dev)
2406 DPRINTK("pktcdvd: writer %s mapped to %s\n", pd->name, bdevname(bdev, b)); 2407 DPRINTK("pktcdvd: writer %s mapped to %s\n", pd->name, bdevname(bdev, b));
2407 return 0; 2408 return 0;
2408 2409
2409out_thread:
2410 pkt_shrink_pktlist(pd);
2411out_mem: 2410out_mem:
2412 blkdev_put(bdev); 2411 blkdev_put(bdev);
2413 /* This is safe: open() is still holding a reference. */ 2412 /* This is safe: open() is still holding a reference. */
@@ -2503,6 +2502,10 @@ static int pkt_setup_dev(struct pkt_ctrl_command *ctrl_cmd)
2503 goto out_mem; 2502 goto out_mem;
2504 pd->disk = disk; 2503 pd->disk = disk;
2505 2504
2505 INIT_LIST_HEAD(&pd->cdrw.pkt_free_list);
2506 INIT_LIST_HEAD(&pd->cdrw.pkt_active_list);
2507 spin_lock_init(&pd->cdrw.active_list_lock);
2508
2506 spin_lock_init(&pd->lock); 2509 spin_lock_init(&pd->lock);
2507 spin_lock_init(&pd->iosched.lock); 2510 spin_lock_init(&pd->iosched.lock);
2508 sprintf(pd->name, "pktcdvd%d", idx); 2511 sprintf(pd->name, "pktcdvd%d", idx);
@@ -2567,8 +2570,6 @@ static int pkt_remove_dev(struct pkt_ctrl_command *ctrl_cmd)
2567 2570
2568 blkdev_put(pd->bdev); 2571 blkdev_put(pd->bdev);
2569 2572
2570 pkt_shrink_pktlist(pd);
2571
2572 remove_proc_entry(pd->name, pkt_proc); 2573 remove_proc_entry(pd->name, pkt_proc);
2573 DPRINTK("pktcdvd: writer %s unmapped\n", pd->name); 2574 DPRINTK("pktcdvd: writer %s unmapped\n", pd->name);
2574 2575
@@ -2678,7 +2679,6 @@ static int __init pkt_init(void)
2678 2679
2679 pkt_proc = proc_mkdir("pktcdvd", proc_root_driver); 2680 pkt_proc = proc_mkdir("pktcdvd", proc_root_driver);
2680 2681
2681 DPRINTK("pktcdvd: %s\n", VERSION_CODE);
2682 return 0; 2682 return 0;
2683 2683
2684out: 2684out: