diff options
author | Mauro Carvalho Chehab <mchehab@infradead.org> | 2006-02-06 07:43:13 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2006-02-06 07:43:13 -0500 |
commit | b2faf597d93bdf5e2d12d93ea0815935a73f749e (patch) | |
tree | 1876616290ff282b8a0814e2429d23e0104f3701 /drivers/block/pktcdvd.c | |
parent | 638e174688f58200d0deb7435093435e7d737b09 (diff) | |
parent | 410c05427a69f53851637ccb85c2212131409fbd (diff) |
Merge branch 'origin'
Diffstat (limited to 'drivers/block/pktcdvd.c')
-rw-r--r-- | drivers/block/pktcdvd.c | 58 |
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 | */ |
134 | static struct packet_data *pkt_alloc_packet_data(void) | 132 | static 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 | ||
164 | no_rd_bio: | 163 | no_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 | ||
171 | no_page: | 170 | no_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 | ||
211 | static int pkt_grow_pktlist(struct pktcdvd_device *pd, int nr_packets) | 211 | static 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 | ||
2019 | static struct pktcdvd_device *pkt_find_dev_from_minor(int dev_minor) | 2026 | static 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 | ||
2409 | out_thread: | ||
2410 | pkt_shrink_pktlist(pd); | ||
2411 | out_mem: | 2410 | out_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 | ||
2684 | out: | 2684 | out: |