aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide/ide-gd.c
diff options
context:
space:
mode:
authorBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2008-10-17 12:09:14 -0400
committerBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2008-10-17 12:09:14 -0400
commit806f80a6fc203ad0bde84e5a9e94572617d2ae45 (patch)
tree20c684323e6e9f24af96df84008f06425a67ec6a /drivers/ide/ide-gd.c
parent79cb380397c834a35952d8497651d93b543ef968 (diff)
ide: add generic ATA/ATAPI disk driver
* Add struct ide_disk_ops containing protocol specific methods. * Add 'struct ide_disk_ops *' to ide_drive_t. * Convert ide-{disk,floppy} drivers to use struct ide_disk_ops. * Merge ide-{disk,floppy} drivers into generic ide-gd driver. While at it: - ide_disk_init_capacity() -> ide_disk_get_capacity() Acked-by: Borislav Petkov <petkovbb@gmail.com> Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Diffstat (limited to 'drivers/ide/ide-gd.c')
-rw-r--r--drivers/ide/ide-gd.c122
1 files changed, 104 insertions, 18 deletions
diff --git a/drivers/ide/ide-gd.c b/drivers/ide/ide-gd.c
index a3d4ad7db2af..d44898f46c33 100644
--- a/drivers/ide/ide-gd.c
+++ b/drivers/ide/ide-gd.c
@@ -15,9 +15,14 @@
15#endif 15#endif
16 16
17#include "ide-disk.h" 17#include "ide-disk.h"
18#include "ide-floppy.h"
18 19
19#define IDE_GD_VERSION "1.18" 20#define IDE_GD_VERSION "1.18"
20 21
22/* module parameters */
23static unsigned long debug_mask;
24module_param(debug_mask, ulong, 0644);
25
21static DEFINE_MUTEX(ide_disk_ref_mutex); 26static DEFINE_MUTEX(ide_disk_ref_mutex);
22 27
23static void ide_disk_release(struct kref *); 28static void ide_disk_release(struct kref *);
@@ -64,7 +69,7 @@ static void ide_gd_remove(ide_drive_t *drive)
64 69
65 del_gendisk(g); 70 del_gendisk(g);
66 71
67 ide_disk_flush(drive); 72 drive->disk_ops->flush(drive);
68 73
69 ide_disk_put(idkp); 74 ide_disk_put(idkp);
70} 75}
@@ -75,6 +80,7 @@ static void ide_disk_release(struct kref *kref)
75 ide_drive_t *drive = idkp->drive; 80 ide_drive_t *drive = idkp->drive;
76 struct gendisk *g = idkp->disk; 81 struct gendisk *g = idkp->disk;
77 82
83 drive->disk_ops = NULL;
78 drive->driver_data = NULL; 84 drive->driver_data = NULL;
79 g->private_data = NULL; 85 g->private_data = NULL;
80 put_disk(g); 86 put_disk(g);
@@ -89,7 +95,7 @@ static void ide_disk_release(struct kref *kref)
89static void ide_gd_resume(ide_drive_t *drive) 95static void ide_gd_resume(ide_drive_t *drive)
90{ 96{
91 if (ata_id_hpa_enabled(drive->id)) 97 if (ata_id_hpa_enabled(drive->id))
92 ide_disk_init_capacity(drive); 98 (void)drive->disk_ops->get_capacity(drive);
93} 99}
94 100
95static void ide_gd_shutdown(ide_drive_t *drive) 101static void ide_gd_shutdown(ide_drive_t *drive)
@@ -110,7 +116,7 @@ static void ide_gd_shutdown(ide_drive_t *drive)
110#else 116#else
111 if (system_state == SYSTEM_RESTART) { 117 if (system_state == SYSTEM_RESTART) {
112#endif 118#endif
113 ide_disk_flush(drive); 119 drive->disk_ops->flush(drive);
114 return; 120 return;
115 } 121 }
116 122
@@ -122,19 +128,31 @@ static void ide_gd_shutdown(ide_drive_t *drive)
122#ifdef CONFIG_IDE_PROC_FS 128#ifdef CONFIG_IDE_PROC_FS
123static ide_proc_entry_t *ide_disk_proc_entries(ide_drive_t *drive) 129static ide_proc_entry_t *ide_disk_proc_entries(ide_drive_t *drive)
124{ 130{
125 return ide_disk_proc; 131 return (drive->media == ide_disk) ? ide_disk_proc : ide_floppy_proc;
126} 132}
127 133
128static const struct ide_proc_devset *ide_disk_proc_devsets(ide_drive_t *drive) 134static const struct ide_proc_devset *ide_disk_proc_devsets(ide_drive_t *drive)
129{ 135{
130 return ide_disk_settings; 136 return (drive->media == ide_disk) ? ide_disk_settings
137 : ide_floppy_settings;
131} 138}
132#endif 139#endif
133 140
141static ide_startstop_t ide_gd_do_request(ide_drive_t *drive,
142 struct request *rq, sector_t sector)
143{
144 return drive->disk_ops->do_request(drive, rq, sector);
145}
146
147static int ide_gd_end_request(ide_drive_t *drive, int uptodate, int nrsecs)
148{
149 return drive->disk_ops->end_request(drive, uptodate, nrsecs);
150}
151
134static ide_driver_t ide_gd_driver = { 152static ide_driver_t ide_gd_driver = {
135 .gen_driver = { 153 .gen_driver = {
136 .owner = THIS_MODULE, 154 .owner = THIS_MODULE,
137 .name = "ide-disk", 155 .name = "ide-gd",
138 .bus = &ide_bus_type, 156 .bus = &ide_bus_type,
139 }, 157 },
140 .probe = ide_gd_probe, 158 .probe = ide_gd_probe,
@@ -142,8 +160,8 @@ static ide_driver_t ide_gd_driver = {
142 .resume = ide_gd_resume, 160 .resume = ide_gd_resume,
143 .shutdown = ide_gd_shutdown, 161 .shutdown = ide_gd_shutdown,
144 .version = IDE_GD_VERSION, 162 .version = IDE_GD_VERSION,
145 .do_request = ide_do_rw_disk, 163 .do_request = ide_gd_do_request,
146 .end_request = ide_end_request, 164 .end_request = ide_gd_end_request,
147 .error = __ide_error, 165 .error = __ide_error,
148#ifdef CONFIG_IDE_PROC_FS 166#ifdef CONFIG_IDE_PROC_FS
149 .proc_entries = ide_disk_proc_entries, 167 .proc_entries = ide_disk_proc_entries,
@@ -156,6 +174,7 @@ static int ide_gd_open(struct inode *inode, struct file *filp)
156 struct gendisk *disk = inode->i_bdev->bd_disk; 174 struct gendisk *disk = inode->i_bdev->bd_disk;
157 struct ide_disk_obj *idkp; 175 struct ide_disk_obj *idkp;
158 ide_drive_t *drive; 176 ide_drive_t *drive;
177 int ret = 0;
159 178
160 idkp = ide_disk_get(disk); 179 idkp = ide_disk_get(disk);
161 if (idkp == NULL) 180 if (idkp == NULL)
@@ -163,19 +182,49 @@ static int ide_gd_open(struct inode *inode, struct file *filp)
163 182
164 drive = idkp->drive; 183 drive = idkp->drive;
165 184
185 ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
186
166 idkp->openers++; 187 idkp->openers++;
167 188
168 if ((drive->dev_flags & IDE_DFLAG_REMOVABLE) && idkp->openers == 1) { 189 if ((drive->dev_flags & IDE_DFLAG_REMOVABLE) && idkp->openers == 1) {
190 drive->dev_flags &= ~IDE_DFLAG_FORMAT_IN_PROGRESS;
191 /* Just in case */
192
193 ret = drive->disk_ops->init_media(drive, disk);
194
195 /*
196 * Allow O_NDELAY to open a drive without a disk, or with an
197 * unreadable disk, so that we can get the format capacity
198 * of the drive or begin the format - Sam
199 */
200 if (ret && (filp->f_flags & O_NDELAY) == 0) {
201 ret = -EIO;
202 goto out_put_idkp;
203 }
204
205 if ((drive->dev_flags & IDE_DFLAG_WP) && (filp->f_mode & 2)) {
206 ret = -EROFS;
207 goto out_put_idkp;
208 }
209
169 /* 210 /*
170 * Ignore the return code from door_lock, 211 * Ignore the return code from door_lock,
171 * since the open() has already succeeded, 212 * since the open() has already succeeded,
172 * and the door_lock is irrelevant at this point. 213 * and the door_lock is irrelevant at this point.
173 */ 214 */
174 ide_disk_set_doorlock(drive, 1); 215 drive->disk_ops->set_doorlock(drive, disk, 1);
175 drive->dev_flags |= IDE_DFLAG_MEDIA_CHANGED; 216 drive->dev_flags |= IDE_DFLAG_MEDIA_CHANGED;
176 check_disk_change(inode->i_bdev); 217 check_disk_change(inode->i_bdev);
218 } else if (drive->dev_flags & IDE_DFLAG_FORMAT_IN_PROGRESS) {
219 ret = -EBUSY;
220 goto out_put_idkp;
177 } 221 }
178 return 0; 222 return 0;
223
224out_put_idkp:
225 idkp->openers--;
226 ide_disk_put(idkp);
227 return ret;
179} 228}
180 229
181static int ide_gd_release(struct inode *inode, struct file *filp) 230static int ide_gd_release(struct inode *inode, struct file *filp)
@@ -184,11 +233,15 @@ static int ide_gd_release(struct inode *inode, struct file *filp)
184 struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj); 233 struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj);
185 ide_drive_t *drive = idkp->drive; 234 ide_drive_t *drive = idkp->drive;
186 235
236 ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
237
187 if (idkp->openers == 1) 238 if (idkp->openers == 1)
188 ide_disk_flush(drive); 239 drive->disk_ops->flush(drive);
189 240
190 if ((drive->dev_flags & IDE_DFLAG_REMOVABLE) && idkp->openers == 1) 241 if ((drive->dev_flags & IDE_DFLAG_REMOVABLE) && idkp->openers == 1) {
191 ide_disk_set_doorlock(drive, 0); 242 drive->disk_ops->set_doorlock(drive, disk, 0);
243 drive->dev_flags &= ~IDE_DFLAG_FORMAT_IN_PROGRESS;
244 }
192 245
193 idkp->openers--; 246 idkp->openers--;
194 247
@@ -233,11 +286,21 @@ static int ide_gd_revalidate_disk(struct gendisk *disk)
233 return 0; 286 return 0;
234} 287}
235 288
289static int ide_gd_ioctl(struct inode *inode, struct file *file,
290 unsigned int cmd, unsigned long arg)
291{
292 struct block_device *bdev = inode->i_bdev;
293 struct ide_disk_obj *idkp = ide_drv_g(bdev->bd_disk, ide_disk_obj);
294 ide_drive_t *drive = idkp->drive;
295
296 return drive->disk_ops->ioctl(drive, inode, file, cmd, arg);
297}
298
236static struct block_device_operations ide_gd_ops = { 299static struct block_device_operations ide_gd_ops = {
237 .owner = THIS_MODULE, 300 .owner = THIS_MODULE,
238 .open = ide_gd_open, 301 .open = ide_gd_open,
239 .release = ide_gd_release, 302 .release = ide_gd_release,
240 .ioctl = ide_disk_ioctl, 303 .ioctl = ide_gd_ioctl,
241 .getgeo = ide_gd_getgeo, 304 .getgeo = ide_gd_getgeo,
242 .media_changed = ide_gd_media_changed, 305 .media_changed = ide_gd_media_changed,
243 .revalidate_disk = ide_gd_revalidate_disk 306 .revalidate_disk = ide_gd_revalidate_disk
@@ -245,19 +308,37 @@ static struct block_device_operations ide_gd_ops = {
245 308
246static int ide_gd_probe(ide_drive_t *drive) 309static int ide_gd_probe(ide_drive_t *drive)
247{ 310{
311 const struct ide_disk_ops *disk_ops = NULL;
248 struct ide_disk_obj *idkp; 312 struct ide_disk_obj *idkp;
249 struct gendisk *g; 313 struct gendisk *g;
250 314
251 /* strstr("foo", "") is non-NULL */ 315 /* strstr("foo", "") is non-NULL */
252 if (!strstr("ide-disk", drive->driver_req)) 316 if (!strstr("ide-gd", drive->driver_req))
317 goto failed;
318
319#ifdef CONFIG_IDE_GD_ATA
320 if (drive->media == ide_disk)
321 disk_ops = &ide_ata_disk_ops;
322#endif
323#ifdef CONFIG_IDE_GD_ATAPI
324 if (drive->media == ide_floppy)
325 disk_ops = &ide_atapi_disk_ops;
326#endif
327 if (disk_ops == NULL)
253 goto failed; 328 goto failed;
254 329
255 if (drive->media != ide_disk) 330 if (disk_ops->check(drive, DRV_NAME) == 0) {
331 printk(KERN_ERR PFX "%s: not supported by this driver\n",
332 drive->name);
256 goto failed; 333 goto failed;
334 }
257 335
258 idkp = kzalloc(sizeof(*idkp), GFP_KERNEL); 336 idkp = kzalloc(sizeof(*idkp), GFP_KERNEL);
259 if (!idkp) 337 if (!idkp) {
338 printk(KERN_ERR PFX "%s: can't allocate a disk structure\n",
339 drive->name);
260 goto failed; 340 goto failed;
341 }
261 342
262 g = alloc_disk_node(IDE_DISK_MINORS, hwif_to_node(drive->hwif)); 343 g = alloc_disk_node(IDE_DISK_MINORS, hwif_to_node(drive->hwif));
263 if (!g) 344 if (!g)
@@ -274,8 +355,10 @@ static int ide_gd_probe(ide_drive_t *drive)
274 g->private_data = &idkp->driver; 355 g->private_data = &idkp->driver;
275 356
276 drive->driver_data = idkp; 357 drive->driver_data = idkp;
358 drive->debug_mask = debug_mask;
359 drive->disk_ops = disk_ops;
277 360
278 ide_disk_setup(drive); 361 disk_ops->setup(drive);
279 362
280 set_capacity(g, ide_gd_capacity(drive)); 363 set_capacity(g, ide_gd_capacity(drive));
281 364
@@ -296,6 +379,7 @@ failed:
296 379
297static int __init ide_gd_init(void) 380static int __init ide_gd_init(void)
298{ 381{
382 printk(KERN_INFO DRV_NAME " driver " IDE_GD_VERSION "\n");
299 return driver_register(&ide_gd_driver.gen_driver); 383 return driver_register(&ide_gd_driver.gen_driver);
300} 384}
301 385
@@ -306,7 +390,9 @@ static void __exit ide_gd_exit(void)
306 390
307MODULE_ALIAS("ide:*m-disk*"); 391MODULE_ALIAS("ide:*m-disk*");
308MODULE_ALIAS("ide-disk"); 392MODULE_ALIAS("ide-disk");
393MODULE_ALIAS("ide:*m-floppy*");
394MODULE_ALIAS("ide-floppy");
309module_init(ide_gd_init); 395module_init(ide_gd_init);
310module_exit(ide_gd_exit); 396module_exit(ide_gd_exit);
311MODULE_LICENSE("GPL"); 397MODULE_LICENSE("GPL");
312MODULE_DESCRIPTION("ATA DISK Driver"); 398MODULE_DESCRIPTION("generic ATA/ATAPI disk driver");