blob: 33ea8c048717d51a293306211721e7120fe35117 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
Bartlomiej Zolnierkiewicz59bca8c2008-02-01 23:09:33 +01002 * Copyright (C) 1994-1998 Linus Torvalds & authors (see below)
3 * Copyright (C) 1998-2002 Linux ATA Development
4 * Andre Hedrick <andre@linux-ide.org>
5 * Copyright (C) 2003 Red Hat <alan@redhat.com>
6 * Copyright (C) 2003-2005, 2007 Bartlomiej Zolnierkiewicz
Linus Torvalds1da177e2005-04-16 15:20:36 -07007 */
8
9/*
10 * Mostly written by Mark Lord <mlord@pobox.com>
11 * and Gadi Oxman <gadio@netvision.net.il>
12 * and Andre Hedrick <andre@linux-ide.org>
13 *
14 * This is the IDE/ATA disk driver, as evolved from hd.c and ide.c.
Linus Torvalds1da177e2005-04-16 15:20:36 -070015 */
16
17#define IDEDISK_VERSION "1.18"
18
Linus Torvalds1da177e2005-04-16 15:20:36 -070019#include <linux/module.h>
20#include <linux/types.h>
21#include <linux/string.h>
22#include <linux/kernel.h>
23#include <linux/timer.h>
24#include <linux/mm.h>
25#include <linux/interrupt.h>
26#include <linux/major.h>
27#include <linux/errno.h>
28#include <linux/genhd.h>
29#include <linux/slab.h>
30#include <linux/delay.h>
Arjan van de Vencf8b8972006-03-23 03:00:45 -080031#include <linux/mutex.h>
Richard Purdie2bfb6462006-03-31 02:31:16 -080032#include <linux/leds.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070033
34#define _IDE_DISK
35
36#include <linux/ide.h>
37
38#include <asm/byteorder.h>
39#include <asm/irq.h>
40#include <asm/uaccess.h>
41#include <asm/io.h>
42#include <asm/div64.h>
43
Tejun Heo870d6652008-08-25 19:47:25 +090044#if !defined(CONFIG_DEBUG_BLOCK_EXT_DEVT)
Tejun Heo689d6fa2008-08-25 19:56:16 +090045#define IDE_DISK_MINORS (1 << PARTN_BITS)
Tejun Heo870d6652008-08-25 19:47:25 +090046#else
Tejun Heo3e1a7ff2008-08-25 19:56:17 +090047#define IDE_DISK_MINORS 0
Tejun Heo870d6652008-08-25 19:47:25 +090048#endif
49
Linus Torvalds1da177e2005-04-16 15:20:36 -070050struct ide_disk_obj {
51 ide_drive_t *drive;
52 ide_driver_t *driver;
53 struct gendisk *disk;
54 struct kref kref;
Bartlomiej Zolnierkiewiczc94964a2007-02-17 02:40:24 +010055 unsigned int openers; /* protected by BKL for now */
Linus Torvalds1da177e2005-04-16 15:20:36 -070056};
57
Arjan van de Vencf8b8972006-03-23 03:00:45 -080058static DEFINE_MUTEX(idedisk_ref_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -070059
60#define to_ide_disk(obj) container_of(obj, struct ide_disk_obj, kref)
61
62#define ide_disk_g(disk) \
63 container_of((disk)->private_data, struct ide_disk_obj, driver)
64
Bartlomiej Zolnierkiewicz08da5912008-07-24 22:53:15 +020065static void ide_disk_release(struct kref *);
66
Linus Torvalds1da177e2005-04-16 15:20:36 -070067static struct ide_disk_obj *ide_disk_get(struct gendisk *disk)
68{
69 struct ide_disk_obj *idkp = NULL;
70
Arjan van de Vencf8b8972006-03-23 03:00:45 -080071 mutex_lock(&idedisk_ref_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -070072 idkp = ide_disk_g(disk);
Bartlomiej Zolnierkiewicz08da5912008-07-24 22:53:15 +020073 if (idkp) {
Bartlomiej Zolnierkiewiczd3e33ff2008-08-05 18:16:59 +020074 if (ide_device_get(idkp->drive))
Bartlomiej Zolnierkiewicz08da5912008-07-24 22:53:15 +020075 idkp = NULL;
Bartlomiej Zolnierkiewiczd3e33ff2008-08-05 18:16:59 +020076 else
77 kref_get(&idkp->kref);
Bartlomiej Zolnierkiewicz08da5912008-07-24 22:53:15 +020078 }
Arjan van de Vencf8b8972006-03-23 03:00:45 -080079 mutex_unlock(&idedisk_ref_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -070080 return idkp;
81}
82
Linus Torvalds1da177e2005-04-16 15:20:36 -070083static void ide_disk_put(struct ide_disk_obj *idkp)
84{
Bartlomiej Zolnierkiewiczd3e33ff2008-08-05 18:16:59 +020085 ide_drive_t *drive = idkp->drive;
86
Arjan van de Vencf8b8972006-03-23 03:00:45 -080087 mutex_lock(&idedisk_ref_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -070088 kref_put(&idkp->kref, ide_disk_release);
Bartlomiej Zolnierkiewiczd3e33ff2008-08-05 18:16:59 +020089 ide_device_put(drive);
Arjan van de Vencf8b8972006-03-23 03:00:45 -080090 mutex_unlock(&idedisk_ref_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -070091}
92
93/*
94 * lba_capacity_is_ok() performs a sanity check on the claimed "lba_capacity"
95 * value for this drive (from its reported identification information).
96 *
97 * Returns: 1 if lba_capacity looks sensible
98 * 0 otherwise
99 *
100 * It is called only once for each drive.
101 */
Bartlomiej Zolnierkiewicz98416542008-04-26 17:36:37 +0200102static int lba_capacity_is_ok(struct hd_driveid *id)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700103{
104 unsigned long lba_sects, chs_sects, head, tail;
105
Alan Cox6efd9362005-06-27 15:24:22 -0700106 /* No non-LBA info .. so valid! */
107 if (id->cyls == 0)
108 return 1;
109
Linus Torvalds1da177e2005-04-16 15:20:36 -0700110 /*
111 * The ATA spec tells large drives to return
112 * C/H/S = 16383/16/63 independent of their size.
113 * Some drives can be jumpered to use 15 heads instead of 16.
114 * Some drives can be jumpered to use 4092 cyls instead of 16383.
115 */
116 if ((id->cyls == 16383
117 || (id->cyls == 4092 && id->cur_cyls == 16383)) &&
118 id->sectors == 63 &&
119 (id->heads == 15 || id->heads == 16) &&
120 (id->lba_capacity >= 16383*63*id->heads))
121 return 1;
122
123 lba_sects = id->lba_capacity;
124 chs_sects = id->cyls * id->heads * id->sectors;
125
126 /* perform a rough sanity check on lba_sects: within 10% is OK */
127 if ((lba_sects - chs_sects) < chs_sects/10)
128 return 1;
129
130 /* some drives have the word order reversed */
131 head = ((lba_sects >> 16) & 0xffff);
132 tail = (lba_sects & 0xffff);
133 lba_sects = (head | (tail << 16));
134 if ((lba_sects - chs_sects) < chs_sects/10) {
135 id->lba_capacity = lba_sects;
136 return 1; /* lba_capacity is (now) good */
137 }
138
139 return 0; /* lba_capacity value may be bad */
140}
141
Bartlomiej Zolnierkiewiczba76ae32008-01-25 22:17:16 +0100142static const u8 ide_rw_cmds[] = {
143 WIN_MULTREAD,
144 WIN_MULTWRITE,
145 WIN_MULTREAD_EXT,
146 WIN_MULTWRITE_EXT,
147 WIN_READ,
148 WIN_WRITE,
149 WIN_READ_EXT,
150 WIN_WRITE_EXT,
151 WIN_READDMA,
152 WIN_WRITEDMA,
153 WIN_READDMA_EXT,
154 WIN_WRITEDMA_EXT,
155};
156
157static const u8 ide_data_phases[] = {
158 TASKFILE_MULTI_IN,
159 TASKFILE_MULTI_OUT,
160 TASKFILE_IN,
161 TASKFILE_OUT,
162 TASKFILE_IN_DMA,
163 TASKFILE_OUT_DMA,
164};
165
166static void ide_tf_set_cmd(ide_drive_t *drive, ide_task_t *task, u8 dma)
167{
168 u8 index, lba48, write;
169
170 lba48 = (task->tf_flags & IDE_TFLAG_LBA48) ? 2 : 0;
171 write = (task->tf_flags & IDE_TFLAG_WRITE) ? 1 : 0;
172
173 if (dma)
Bartlomiej Zolnierkiewiczba4b2e62008-07-23 19:55:55 +0200174 index = 8;
Bartlomiej Zolnierkiewiczba76ae32008-01-25 22:17:16 +0100175 else
176 index = drive->mult_count ? 0 : 4;
177
178 task->tf.command = ide_rw_cmds[index + lba48 + write];
179
180 if (dma)
181 index = 8; /* fixup index */
182
183 task->data_phase = ide_data_phases[index / 2 + write];
184}
185
Linus Torvalds1da177e2005-04-16 15:20:36 -0700186/*
187 * __ide_do_rw_disk() issues READ and WRITE commands to a disk,
188 * using LBA if supported, or CHS otherwise, to address sectors.
189 */
Bartlomiej Zolnierkiewicz98416542008-04-26 17:36:37 +0200190static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq,
191 sector_t block)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700192{
193 ide_hwif_t *hwif = HWIF(drive);
194 unsigned int dma = drive->using_dma;
Bartlomiej Zolnierkiewicz790d1232008-01-25 22:17:12 +0100195 u16 nsectors = (u16)rq->nr_sectors;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700196 u8 lba48 = (drive->addressing == 1) ? 1 : 0;
Bartlomiej Zolnierkiewicz9e422372008-01-25 22:17:07 +0100197 ide_task_t task;
198 struct ide_taskfile *tf = &task.tf;
Bartlomiej Zolnierkiewiczf6e29e32008-01-25 22:17:16 +0100199 ide_startstop_t rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700200
Bartlomiej Zolnierkiewicz238e4f12007-10-19 00:30:07 +0200201 if ((hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA) && lba48 && dma) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700202 if (block + rq->nr_sectors > 1ULL << 28)
203 dma = 0;
204 else
205 lba48 = 0;
206 }
207
208 if (!dma) {
209 ide_init_sg_cmd(drive, rq);
210 ide_map_sg(drive, rq);
211 }
212
Bartlomiej Zolnierkiewicz9e422372008-01-25 22:17:07 +0100213 memset(&task, 0, sizeof(task));
Bartlomiej Zolnierkiewicz9a410e72008-07-15 21:21:48 +0200214 task.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
Bartlomiej Zolnierkiewicz2bd06b22008-01-25 22:17:06 +0100215
Linus Torvalds1da177e2005-04-16 15:20:36 -0700216 if (drive->select.b.lba) {
217 if (lba48) {
Michael Richardsonc2f83112006-02-07 12:58:33 -0800218 pr_debug("%s: LBA=0x%012llx\n", drive->name,
219 (unsigned long long)block);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700220
Bartlomiej Zolnierkiewicz790d1232008-01-25 22:17:12 +0100221 tf->hob_nsect = (nsectors >> 8) & 0xff;
Bartlomiej Zolnierkiewicz2bd06b22008-01-25 22:17:06 +0100222 tf->hob_lbal = (u8)(block >> 24);
223 if (sizeof(block) != 4) {
224 tf->hob_lbam = (u8)((u64)block >> 32);
225 tf->hob_lbah = (u8)((u64)block >> 40);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700226 }
Bartlomiej Zolnierkiewicz2bd06b22008-01-25 22:17:06 +0100227
Bartlomiej Zolnierkiewicz790d1232008-01-25 22:17:12 +0100228 tf->nsect = nsectors & 0xff;
Bartlomiej Zolnierkiewicz2bd06b22008-01-25 22:17:06 +0100229 tf->lbal = (u8) block;
230 tf->lbam = (u8)(block >> 8);
231 tf->lbah = (u8)(block >> 16);
Bartlomiej Zolnierkiewicz6dd9b832008-01-26 20:13:03 +0100232
Bartlomiej Zolnierkiewicz657cc1a2008-01-26 20:13:10 +0100233 task.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_HOB);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700234 } else {
Bartlomiej Zolnierkiewicz790d1232008-01-25 22:17:12 +0100235 tf->nsect = nsectors & 0xff;
Bartlomiej Zolnierkiewicz2bd06b22008-01-25 22:17:06 +0100236 tf->lbal = block;
237 tf->lbam = block >>= 8;
238 tf->lbah = block >>= 8;
239 tf->device = (block >> 8) & 0xf;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700240 }
241 } else {
Bartlomiej Zolnierkiewicz98416542008-04-26 17:36:37 +0200242 unsigned int sect, head, cyl, track;
243
Linus Torvalds1da177e2005-04-16 15:20:36 -0700244 track = (int)block / drive->sect;
245 sect = (int)block % drive->sect + 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700246 head = track % drive->head;
247 cyl = track / drive->head;
248
249 pr_debug("%s: CHS=%u/%u/%u\n", drive->name, cyl, head, sect);
250
Bartlomiej Zolnierkiewicz790d1232008-01-25 22:17:12 +0100251 tf->nsect = nsectors & 0xff;
Bartlomiej Zolnierkiewicz2bd06b22008-01-25 22:17:06 +0100252 tf->lbal = sect;
253 tf->lbam = cyl;
254 tf->lbah = cyl >> 8;
255 tf->device = head;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700256 }
257
Bartlomiej Zolnierkiewiczba76ae32008-01-25 22:17:16 +0100258 if (rq_data_dir(rq))
259 task.tf_flags |= IDE_TFLAG_WRITE;
260
261 ide_tf_set_cmd(drive, &task, dma);
Bartlomiej Zolnierkiewiczf6e29e32008-01-25 22:17:16 +0100262 if (!dma)
263 hwif->data_phase = task.data_phase;
264 task.rq = rq;
Bartlomiej Zolnierkiewiczba76ae32008-01-25 22:17:16 +0100265
Bartlomiej Zolnierkiewiczf6e29e32008-01-25 22:17:16 +0100266 rc = do_rw_taskfile(drive, &task);
Bartlomiej Zolnierkiewicz2bd06b22008-01-25 22:17:06 +0100267
Bartlomiej Zolnierkiewiczf6e29e32008-01-25 22:17:16 +0100268 if (rc == ide_stopped && dma) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700269 /* fallback to PIO */
Bartlomiej Zolnierkiewiczf6e29e32008-01-25 22:17:16 +0100270 task.tf_flags |= IDE_TFLAG_DMA_PIO_FALLBACK;
Bartlomiej Zolnierkiewiczba76ae32008-01-25 22:17:16 +0100271 ide_tf_set_cmd(drive, &task, 0);
Bartlomiej Zolnierkiewiczf6e29e32008-01-25 22:17:16 +0100272 hwif->data_phase = task.data_phase;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700273 ide_init_sg_cmd(drive, rq);
Bartlomiej Zolnierkiewiczf6e29e32008-01-25 22:17:16 +0100274 rc = do_rw_taskfile(drive, &task);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700275 }
276
Bartlomiej Zolnierkiewiczf6e29e32008-01-25 22:17:16 +0100277 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700278}
279
280/*
281 * 268435455 == 137439 MB or 28bit limit
282 * 320173056 == 163929 MB or 48bit addressing
283 * 1073741822 == 549756 MB or 48bit addressing fake drive
284 */
285
Bartlomiej Zolnierkiewicz98416542008-04-26 17:36:37 +0200286static ide_startstop_t ide_do_rw_disk(ide_drive_t *drive, struct request *rq,
287 sector_t block)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700288{
289 ide_hwif_t *hwif = HWIF(drive);
290
291 BUG_ON(drive->blocked);
292
293 if (!blk_fs_request(rq)) {
294 blk_dump_rq_flags(rq, "ide_do_rw_disk - bad command");
295 ide_end_request(drive, 0, 0);
296 return ide_stopped;
297 }
298
Richard Purdie2bfb6462006-03-31 02:31:16 -0800299 ledtrig_ide_activity();
300
Linus Torvalds1da177e2005-04-16 15:20:36 -0700301 pr_debug("%s: %sing: block=%llu, sectors=%lu, buffer=0x%08lx\n",
302 drive->name, rq_data_dir(rq) == READ ? "read" : "writ",
Michael Richardsonc2f83112006-02-07 12:58:33 -0800303 (unsigned long long)block, rq->nr_sectors,
304 (unsigned long)rq->buffer);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700305
306 if (hwif->rw_disk)
307 hwif->rw_disk(drive, rq);
308
309 return __ide_do_rw_disk(drive, rq, block);
310}
311
312/*
313 * Queries for true maximum capacity of the drive.
314 * Returns maximum LBA address (> 0) of the drive, 0 if failed.
315 */
Bartlomiej Zolnierkiewicz7a3b7512008-01-25 22:17:06 +0100316static u64 idedisk_read_native_max_address(ide_drive_t *drive, int lba48)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700317{
318 ide_task_t args;
Bartlomiej Zolnierkiewicz650d8412008-01-25 22:17:06 +0100319 struct ide_taskfile *tf = &args.tf;
Bartlomiej Zolnierkiewicz7a3b7512008-01-25 22:17:06 +0100320 u64 addr = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700321
322 /* Create IDE/ATA command request structure */
323 memset(&args, 0, sizeof(ide_task_t));
Bartlomiej Zolnierkiewicz7a3b7512008-01-25 22:17:06 +0100324 if (lba48)
325 tf->command = WIN_READ_NATIVE_MAX_EXT;
326 else
327 tf->command = WIN_READ_NATIVE_MAX;
Bartlomiej Zolnierkiewicz650d8412008-01-25 22:17:06 +0100328 tf->device = ATA_LBA;
Bartlomiej Zolnierkiewicz657cc1a2008-01-26 20:13:10 +0100329 args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
Bartlomiej Zolnierkiewicza3bbb9d2008-01-25 22:17:10 +0100330 if (lba48)
Bartlomiej Zolnierkiewicz657cc1a2008-01-26 20:13:10 +0100331 args.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_HOB);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700332 /* submit command request */
Bartlomiej Zolnierkiewicz9a3c49b2008-01-25 22:17:07 +0100333 ide_no_data_taskfile(drive, &args);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700334
335 /* if OK, compute maximum address value */
Bartlomiej Zolnierkiewicza5016332008-01-25 22:17:17 +0100336 if ((tf->status & 0x01) == 0)
337 addr = ide_get_lba_addr(tf, lba48) + 1;
Bartlomiej Zolnierkiewicz650d8412008-01-25 22:17:06 +0100338
Linus Torvalds1da177e2005-04-16 15:20:36 -0700339 return addr;
340}
341
342/*
343 * Sets maximum virtual LBA address of the drive.
344 * Returns new maximum virtual LBA address (> 0) or 0 on failure.
345 */
Bartlomiej Zolnierkiewicz7a3b7512008-01-25 22:17:06 +0100346static u64 idedisk_set_max_address(ide_drive_t *drive, u64 addr_req, int lba48)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700347{
348 ide_task_t args;
Bartlomiej Zolnierkiewicz650d8412008-01-25 22:17:06 +0100349 struct ide_taskfile *tf = &args.tf;
Bartlomiej Zolnierkiewicz7a3b7512008-01-25 22:17:06 +0100350 u64 addr_set = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700351
352 addr_req--;
353 /* Create IDE/ATA command request structure */
354 memset(&args, 0, sizeof(ide_task_t));
Bartlomiej Zolnierkiewicz650d8412008-01-25 22:17:06 +0100355 tf->lbal = (addr_req >> 0) & 0xff;
356 tf->lbam = (addr_req >>= 8) & 0xff;
357 tf->lbah = (addr_req >>= 8) & 0xff;
Bartlomiej Zolnierkiewicz7a3b7512008-01-25 22:17:06 +0100358 if (lba48) {
359 tf->hob_lbal = (addr_req >>= 8) & 0xff;
360 tf->hob_lbam = (addr_req >>= 8) & 0xff;
361 tf->hob_lbah = (addr_req >>= 8) & 0xff;
362 tf->command = WIN_SET_MAX_EXT;
363 } else {
364 tf->device = (addr_req >>= 8) & 0x0f;
365 tf->command = WIN_SET_MAX;
366 }
367 tf->device |= ATA_LBA;
Bartlomiej Zolnierkiewicz657cc1a2008-01-26 20:13:10 +0100368 args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
Bartlomiej Zolnierkiewicza3bbb9d2008-01-25 22:17:10 +0100369 if (lba48)
Bartlomiej Zolnierkiewicz657cc1a2008-01-26 20:13:10 +0100370 args.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_HOB);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700371 /* submit command request */
Bartlomiej Zolnierkiewicz9a3c49b2008-01-25 22:17:07 +0100372 ide_no_data_taskfile(drive, &args);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700373 /* if OK, compute maximum address value */
Bartlomiej Zolnierkiewicza5016332008-01-25 22:17:17 +0100374 if ((tf->status & 0x01) == 0)
375 addr_set = ide_get_lba_addr(tf, lba48) + 1;
Bartlomiej Zolnierkiewicz650d8412008-01-25 22:17:06 +0100376
Linus Torvalds1da177e2005-04-16 15:20:36 -0700377 return addr_set;
378}
379
380static unsigned long long sectors_to_MB(unsigned long long n)
381{
382 n <<= 9; /* make it bytes */
383 do_div(n, 1000000); /* make it MB */
384 return n;
385}
386
387/*
388 * Bits 10 of command_set_1 and cfs_enable_1 must be equal,
389 * so on non-buggy drives we need test only one.
390 * However, we should also check whether these fields are valid.
391 */
392static inline int idedisk_supports_hpa(const struct hd_driveid *id)
393{
394 return (id->command_set_1 & 0x0400) && (id->cfs_enable_1 & 0x0400);
395}
396
397/*
398 * The same here.
399 */
400static inline int idedisk_supports_lba48(const struct hd_driveid *id)
401{
402 return (id->command_set_2 & 0x0400) && (id->cfs_enable_2 & 0x0400)
403 && id->lba_capacity_2;
404}
405
Bartlomiej Zolnierkiewiczb0244a02007-08-20 22:42:57 +0200406/*
407 * Some disks report total number of sectors instead of
408 * maximum sector address. We list them here.
409 */
410static const struct drive_list_entry hpa_list[] = {
411 { "ST340823A", NULL },
Jorge Juan Chico7062cdc2007-09-17 12:35:30 +0200412 { "ST320413A", NULL },
Mikko Rapelib152fcd2008-02-19 01:41:25 +0100413 { "ST310211A", NULL },
Bartlomiej Zolnierkiewiczb0244a02007-08-20 22:42:57 +0200414 { NULL, NULL }
415};
416
Arjan van de Ven858119e2006-01-14 13:20:43 -0800417static void idedisk_check_hpa(ide_drive_t *drive)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700418{
419 unsigned long long capacity, set_max;
420 int lba48 = idedisk_supports_lba48(drive->id);
421
422 capacity = drive->capacity64;
Bartlomiej Zolnierkiewicz7a3b7512008-01-25 22:17:06 +0100423
424 set_max = idedisk_read_native_max_address(drive, lba48);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700425
Bartlomiej Zolnierkiewiczb0244a02007-08-20 22:42:57 +0200426 if (ide_in_drive_list(drive->id, hpa_list)) {
427 /*
428 * Since we are inclusive wrt to firmware revisions do this
429 * extra check and apply the workaround only when needed.
430 */
431 if (set_max == capacity + 1)
432 set_max--;
433 }
434
Linus Torvalds1da177e2005-04-16 15:20:36 -0700435 if (set_max <= capacity)
436 return;
437
438 printk(KERN_INFO "%s: Host Protected Area detected.\n"
439 "\tcurrent capacity is %llu sectors (%llu MB)\n"
440 "\tnative capacity is %llu sectors (%llu MB)\n",
441 drive->name,
442 capacity, sectors_to_MB(capacity),
443 set_max, sectors_to_MB(set_max));
444
Bartlomiej Zolnierkiewicz7a3b7512008-01-25 22:17:06 +0100445 set_max = idedisk_set_max_address(drive, set_max, lba48);
446
Linus Torvalds1da177e2005-04-16 15:20:36 -0700447 if (set_max) {
448 drive->capacity64 = set_max;
449 printk(KERN_INFO "%s: Host Protected Area disabled.\n",
450 drive->name);
451 }
452}
453
Bartlomiej Zolnierkiewicz98416542008-04-26 17:36:37 +0200454static void init_idedisk_capacity(ide_drive_t *drive)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700455{
456 struct hd_driveid *id = drive->id;
457 /*
458 * If this drive supports the Host Protected Area feature set,
459 * then we may need to change our opinion about the drive's capacity.
460 */
461 int hpa = idedisk_supports_hpa(id);
462
463 if (idedisk_supports_lba48(id)) {
464 /* drive speaks 48-bit LBA */
465 drive->select.b.lba = 1;
466 drive->capacity64 = id->lba_capacity_2;
467 if (hpa)
468 idedisk_check_hpa(drive);
469 } else if ((id->capability & 2) && lba_capacity_is_ok(id)) {
470 /* drive speaks 28-bit LBA */
471 drive->select.b.lba = 1;
472 drive->capacity64 = id->lba_capacity;
473 if (hpa)
474 idedisk_check_hpa(drive);
475 } else {
476 /* drive speaks boring old 28-bit CHS */
477 drive->capacity64 = drive->cyl * drive->head * drive->sect;
478 }
479}
480
Bartlomiej Zolnierkiewicz98416542008-04-26 17:36:37 +0200481static sector_t idedisk_capacity(ide_drive_t *drive)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700482{
483 return drive->capacity64 - drive->sect0;
484}
485
Bartlomiej Zolnierkiewiczecfd80e2007-05-10 00:01:09 +0200486#ifdef CONFIG_IDE_PROC_FS
Linus Torvalds1da177e2005-04-16 15:20:36 -0700487static int smart_enable(ide_drive_t *drive)
488{
489 ide_task_t args;
Bartlomiej Zolnierkiewicz650d8412008-01-25 22:17:06 +0100490 struct ide_taskfile *tf = &args.tf;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700491
492 memset(&args, 0, sizeof(ide_task_t));
Bartlomiej Zolnierkiewicz650d8412008-01-25 22:17:06 +0100493 tf->feature = SMART_ENABLE;
494 tf->lbam = SMART_LCYL_PASS;
495 tf->lbah = SMART_HCYL_PASS;
496 tf->command = WIN_SMART;
Bartlomiej Zolnierkiewicz657cc1a2008-01-26 20:13:10 +0100497 args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
Bartlomiej Zolnierkiewicz9a3c49b2008-01-25 22:17:07 +0100498 return ide_no_data_taskfile(drive, &args);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700499}
500
Bartlomiej Zolnierkiewicz43e7c0c2007-10-20 00:32:37 +0200501static int get_smart_data(ide_drive_t *drive, u8 *buf, u8 sub_cmd)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700502{
503 ide_task_t args;
Bartlomiej Zolnierkiewicz650d8412008-01-25 22:17:06 +0100504 struct ide_taskfile *tf = &args.tf;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700505
506 memset(&args, 0, sizeof(ide_task_t));
Bartlomiej Zolnierkiewicz650d8412008-01-25 22:17:06 +0100507 tf->feature = sub_cmd;
508 tf->nsect = 0x01;
509 tf->lbam = SMART_LCYL_PASS;
510 tf->lbah = SMART_HCYL_PASS;
511 tf->command = WIN_SMART;
Bartlomiej Zolnierkiewicz657cc1a2008-01-26 20:13:10 +0100512 args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
Bartlomiej Zolnierkiewiczac026ff2008-01-25 22:17:14 +0100513 args.data_phase = TASKFILE_IN;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700514 (void) smart_enable(drive);
Bartlomiej Zolnierkiewiczac026ff2008-01-25 22:17:14 +0100515 return ide_raw_taskfile(drive, &args, buf, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700516}
517
518static int proc_idedisk_read_cache
519 (char *page, char **start, off_t off, int count, int *eof, void *data)
520{
521 ide_drive_t *drive = (ide_drive_t *) data;
522 char *out = page;
523 int len;
524
525 if (drive->id_read)
Bartlomiej Zolnierkiewicz98416542008-04-26 17:36:37 +0200526 len = sprintf(out, "%i\n", drive->id->buf_size / 2);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700527 else
Bartlomiej Zolnierkiewicz98416542008-04-26 17:36:37 +0200528 len = sprintf(out, "(none)\n");
529
530 PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700531}
532
533static int proc_idedisk_read_capacity
534 (char *page, char **start, off_t off, int count, int *eof, void *data)
535{
536 ide_drive_t*drive = (ide_drive_t *)data;
537 int len;
538
Bartlomiej Zolnierkiewicz98416542008-04-26 17:36:37 +0200539 len = sprintf(page, "%llu\n", (long long)idedisk_capacity(drive));
540
541 PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700542}
543
Bartlomiej Zolnierkiewicz799ee572008-04-26 17:36:37 +0200544static int proc_idedisk_read_smart(char *page, char **start, off_t off,
545 int count, int *eof, void *data, u8 sub_cmd)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700546{
547 ide_drive_t *drive = (ide_drive_t *)data;
548 int len = 0, i = 0;
549
Bartlomiej Zolnierkiewicz799ee572008-04-26 17:36:37 +0200550 if (get_smart_data(drive, page, sub_cmd) == 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700551 unsigned short *val = (unsigned short *) page;
552 char *out = ((char *)val) + (SECTOR_WORDS * 4);
553 page = out;
554 do {
Bartlomiej Zolnierkiewicz98416542008-04-26 17:36:37 +0200555 out += sprintf(out, "%04x%c", le16_to_cpu(*val),
556 (++i & 7) ? ' ' : '\n');
Linus Torvalds1da177e2005-04-16 15:20:36 -0700557 val += 1;
558 } while (i < (SECTOR_WORDS * 2));
559 len = out - page;
560 }
Bartlomiej Zolnierkiewicz98416542008-04-26 17:36:37 +0200561
562 PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700563}
564
Bartlomiej Zolnierkiewicz799ee572008-04-26 17:36:37 +0200565static int proc_idedisk_read_sv
Linus Torvalds1da177e2005-04-16 15:20:36 -0700566 (char *page, char **start, off_t off, int count, int *eof, void *data)
567{
Bartlomiej Zolnierkiewicz799ee572008-04-26 17:36:37 +0200568 return proc_idedisk_read_smart(page, start, off, count, eof, data,
569 SMART_READ_VALUES);
570}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700571
Bartlomiej Zolnierkiewicz799ee572008-04-26 17:36:37 +0200572static int proc_idedisk_read_st
573 (char *page, char **start, off_t off, int count, int *eof, void *data)
574{
575 return proc_idedisk_read_smart(page, start, off, count, eof, data,
576 SMART_READ_THRESHOLDS);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700577}
578
579static ide_proc_entry_t idedisk_proc[] = {
Bartlomiej Zolnierkiewicz799ee572008-04-26 17:36:37 +0200580 { "cache", S_IFREG|S_IRUGO, proc_idedisk_read_cache, NULL },
581 { "capacity", S_IFREG|S_IRUGO, proc_idedisk_read_capacity, NULL },
582 { "geometry", S_IFREG|S_IRUGO, proc_ide_read_geometry, NULL },
583 { "smart_values", S_IFREG|S_IRUSR, proc_idedisk_read_sv, NULL },
584 { "smart_thresholds", S_IFREG|S_IRUSR, proc_idedisk_read_st, NULL },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700585 { NULL, 0, NULL, NULL }
586};
Bartlomiej Zolnierkiewiczecfd80e2007-05-10 00:01:09 +0200587#endif /* CONFIG_IDE_PROC_FS */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700588
Jens Axboe165125e2007-07-24 09:28:11 +0200589static void idedisk_prepare_flush(struct request_queue *q, struct request *rq)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700590{
591 ide_drive_t *drive = q->queuedata;
Bartlomiej Zolnierkiewicz395d8ef2008-02-11 00:32:14 +0100592 ide_task_t *task = kmalloc(sizeof(*task), GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700593
Bartlomiej Zolnierkiewicz395d8ef2008-02-11 00:32:14 +0100594 /* FIXME: map struct ide_taskfile on rq->cmd[] */
595 BUG_ON(task == NULL);
596
597 memset(task, 0, sizeof(*task));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700598 if (ide_id_has_flush_cache_ext(drive->id) &&
599 (drive->capacity64 >= (1UL << 28)))
Bartlomiej Zolnierkiewicz395d8ef2008-02-11 00:32:14 +0100600 task->tf.command = WIN_FLUSH_CACHE_EXT;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700601 else
Bartlomiej Zolnierkiewicz395d8ef2008-02-11 00:32:14 +0100602 task->tf.command = WIN_FLUSH_CACHE;
603 task->tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE |
604 IDE_TFLAG_DYN;
605 task->data_phase = TASKFILE_NO_DATA;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700606
Bartlomiej Zolnierkiewicz813a0eb2008-01-25 22:17:10 +0100607 rq->cmd_type = REQ_TYPE_ATA_TASKFILE;
Jens Axboe4aff5e22006-08-10 08:44:47 +0200608 rq->cmd_flags |= REQ_SOFTBARRIER;
Bartlomiej Zolnierkiewicz395d8ef2008-02-11 00:32:14 +0100609 rq->special = task;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700610}
611
Linus Torvalds1da177e2005-04-16 15:20:36 -0700612/*
613 * This is tightly woven into the driver->do_special can not touch.
614 * DON'T do it again until a total personality rewrite is committed.
615 */
616static int set_multcount(ide_drive_t *drive, int arg)
617{
FUJITA Tomonoridd470872008-07-15 21:21:43 +0200618 struct request *rq;
619 int error;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700620
Bartlomiej Zolnierkiewicz14979432007-05-10 00:01:10 +0200621 if (arg < 0 || arg > drive->id->max_multsect)
622 return -EINVAL;
623
Linus Torvalds1da177e2005-04-16 15:20:36 -0700624 if (drive->special.b.set_multmode)
625 return -EBUSY;
Bartlomiej Zolnierkiewicz852738f2008-01-26 20:13:12 +0100626
FUJITA Tomonoridd470872008-07-15 21:21:43 +0200627 rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
628 rq->cmd_type = REQ_TYPE_ATA_TASKFILE;
Bartlomiej Zolnierkiewicz852738f2008-01-26 20:13:12 +0100629
Linus Torvalds1da177e2005-04-16 15:20:36 -0700630 drive->mult_req = arg;
631 drive->special.b.set_multmode = 1;
FUJITA Tomonoridd470872008-07-15 21:21:43 +0200632 error = blk_execute_rq(drive->queue, NULL, rq, 0);
633 blk_put_request(rq);
Bartlomiej Zolnierkiewicz98416542008-04-26 17:36:37 +0200634
Linus Torvalds1da177e2005-04-16 15:20:36 -0700635 return (drive->mult_count == arg) ? 0 : -EIO;
636}
637
638static int set_nowerr(ide_drive_t *drive, int arg)
639{
Bartlomiej Zolnierkiewicz14979432007-05-10 00:01:10 +0200640 if (arg < 0 || arg > 1)
641 return -EINVAL;
642
Linus Torvalds1da177e2005-04-16 15:20:36 -0700643 if (ide_spin_wait_hwgroup(drive))
644 return -EBUSY;
645 drive->nowerr = arg;
646 drive->bad_wstat = arg ? BAD_R_STAT : BAD_W_STAT;
647 spin_unlock_irq(&ide_lock);
648 return 0;
649}
650
Tejun Heo3e087b52006-01-06 09:57:31 +0100651static void update_ordered(ide_drive_t *drive)
652{
653 struct hd_driveid *id = drive->id;
654 unsigned ordered = QUEUE_ORDERED_NONE;
655 prepare_flush_fn *prep_fn = NULL;
Tejun Heo3e087b52006-01-06 09:57:31 +0100656
657 if (drive->wcache) {
658 unsigned long long capacity;
659 int barrier;
660 /*
661 * We must avoid issuing commands a drive does not
662 * understand or we may crash it. We check flush cache
663 * is supported. We also check we have the LBA48 flush
664 * cache if the drive capacity is too large. By this
665 * time we have trimmed the drive capacity if LBA48 is
666 * not available so we don't need to recheck that.
667 */
668 capacity = idedisk_capacity(drive);
Jens Axboe36193482006-07-28 08:54:59 +0200669 barrier = ide_id_has_flush_cache(id) && !drive->noflush &&
Tejun Heo3e087b52006-01-06 09:57:31 +0100670 (drive->addressing == 0 || capacity <= (1ULL << 28) ||
671 ide_id_has_flush_cache_ext(id));
672
673 printk(KERN_INFO "%s: cache flushes %ssupported\n",
Jean Delvaref7ad8362006-02-03 03:04:57 -0800674 drive->name, barrier ? "" : "not ");
Tejun Heo3e087b52006-01-06 09:57:31 +0100675
676 if (barrier) {
677 ordered = QUEUE_ORDERED_DRAIN_FLUSH;
678 prep_fn = idedisk_prepare_flush;
Tejun Heo3e087b52006-01-06 09:57:31 +0100679 }
680 } else
681 ordered = QUEUE_ORDERED_DRAIN;
682
683 blk_queue_ordered(drive->queue, ordered, prep_fn);
Tejun Heo3e087b52006-01-06 09:57:31 +0100684}
685
Linus Torvalds1da177e2005-04-16 15:20:36 -0700686static int write_cache(ide_drive_t *drive, int arg)
687{
688 ide_task_t args;
Tejun Heo3e087b52006-01-06 09:57:31 +0100689 int err = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700690
Bartlomiej Zolnierkiewicz14979432007-05-10 00:01:10 +0200691 if (arg < 0 || arg > 1)
692 return -EINVAL;
693
Tejun Heo3e087b52006-01-06 09:57:31 +0100694 if (ide_id_has_flush_cache(drive->id)) {
695 memset(&args, 0, sizeof(ide_task_t));
Bartlomiej Zolnierkiewicz650d8412008-01-25 22:17:06 +0100696 args.tf.feature = arg ?
Linus Torvalds1da177e2005-04-16 15:20:36 -0700697 SETFEATURES_EN_WCACHE : SETFEATURES_DIS_WCACHE;
Bartlomiej Zolnierkiewicz650d8412008-01-25 22:17:06 +0100698 args.tf.command = WIN_SETFEATURES;
Bartlomiej Zolnierkiewicz657cc1a2008-01-26 20:13:10 +0100699 args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
Bartlomiej Zolnierkiewicz9a3c49b2008-01-25 22:17:07 +0100700 err = ide_no_data_taskfile(drive, &args);
Tejun Heo3e087b52006-01-06 09:57:31 +0100701 if (err == 0)
702 drive->wcache = arg;
703 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700704
Tejun Heo3e087b52006-01-06 09:57:31 +0100705 update_ordered(drive);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700706
Tejun Heo3e087b52006-01-06 09:57:31 +0100707 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700708}
709
Bartlomiej Zolnierkiewicz98416542008-04-26 17:36:37 +0200710static int do_idedisk_flushcache(ide_drive_t *drive)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700711{
712 ide_task_t args;
713
714 memset(&args, 0, sizeof(ide_task_t));
715 if (ide_id_has_flush_cache_ext(drive->id))
Bartlomiej Zolnierkiewicz650d8412008-01-25 22:17:06 +0100716 args.tf.command = WIN_FLUSH_CACHE_EXT;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700717 else
Bartlomiej Zolnierkiewicz650d8412008-01-25 22:17:06 +0100718 args.tf.command = WIN_FLUSH_CACHE;
Bartlomiej Zolnierkiewicz657cc1a2008-01-26 20:13:10 +0100719 args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
Bartlomiej Zolnierkiewicz9a3c49b2008-01-25 22:17:07 +0100720 return ide_no_data_taskfile(drive, &args);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700721}
722
Bartlomiej Zolnierkiewicz98416542008-04-26 17:36:37 +0200723static int set_acoustic(ide_drive_t *drive, int arg)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700724{
725 ide_task_t args;
726
Bartlomiej Zolnierkiewicz14979432007-05-10 00:01:10 +0200727 if (arg < 0 || arg > 254)
728 return -EINVAL;
729
Linus Torvalds1da177e2005-04-16 15:20:36 -0700730 memset(&args, 0, sizeof(ide_task_t));
Bartlomiej Zolnierkiewicz650d8412008-01-25 22:17:06 +0100731 args.tf.feature = arg ? SETFEATURES_EN_AAM : SETFEATURES_DIS_AAM;
732 args.tf.nsect = arg;
733 args.tf.command = WIN_SETFEATURES;
Bartlomiej Zolnierkiewicz657cc1a2008-01-26 20:13:10 +0100734 args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
Bartlomiej Zolnierkiewicz9a3c49b2008-01-25 22:17:07 +0100735 ide_no_data_taskfile(drive, &args);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700736 drive->acoustic = arg;
737 return 0;
738}
739
740/*
741 * drive->addressing:
742 * 0: 28-bit
743 * 1: 48-bit
744 * 2: 48-bit capable doing 28-bit
745 */
746static int set_lba_addressing(ide_drive_t *drive, int arg)
747{
Bartlomiej Zolnierkiewicz14979432007-05-10 00:01:10 +0200748 if (arg < 0 || arg > 2)
749 return -EINVAL;
750
Linus Torvalds1da177e2005-04-16 15:20:36 -0700751 drive->addressing = 0;
752
Bartlomiej Zolnierkiewicz238e4f12007-10-19 00:30:07 +0200753 if (drive->hwif->host_flags & IDE_HFLAG_NO_LBA48)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700754 return 0;
755
756 if (!idedisk_supports_lba48(drive->id))
Bartlomiej Zolnierkiewicz98416542008-04-26 17:36:37 +0200757 return -EIO;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700758 drive->addressing = arg;
759 return 0;
760}
761
Bartlomiej Zolnierkiewicz7662d042007-05-10 00:01:10 +0200762#ifdef CONFIG_IDE_PROC_FS
Linus Torvalds1da177e2005-04-16 15:20:36 -0700763static void idedisk_add_settings(ide_drive_t *drive)
764{
765 struct hd_driveid *id = drive->id;
766
Bartlomiej Zolnierkiewicz98416542008-04-26 17:36:37 +0200767 ide_add_setting(drive, "bios_cyl", SETTING_RW, TYPE_INT, 0, 65535, 1, 1,
768 &drive->bios_cyl, NULL);
769 ide_add_setting(drive, "bios_head", SETTING_RW, TYPE_BYTE, 0, 255, 1, 1,
770 &drive->bios_head, NULL);
771 ide_add_setting(drive, "bios_sect", SETTING_RW, TYPE_BYTE, 0, 63, 1, 1,
772 &drive->bios_sect, NULL);
773 ide_add_setting(drive, "address", SETTING_RW, TYPE_BYTE, 0, 2, 1, 1,
774 &drive->addressing, set_lba_addressing);
775 ide_add_setting(drive, "multcount", SETTING_RW, TYPE_BYTE, 0,
776 id->max_multsect, 1, 1, &drive->mult_count,
777 set_multcount);
778 ide_add_setting(drive, "nowerr", SETTING_RW, TYPE_BYTE, 0, 1, 1, 1,
779 &drive->nowerr, set_nowerr);
780 ide_add_setting(drive, "lun", SETTING_RW, TYPE_INT, 0, 7, 1, 1,
781 &drive->lun, NULL);
782 ide_add_setting(drive, "wcache", SETTING_RW, TYPE_BYTE, 0, 1, 1, 1,
783 &drive->wcache, write_cache);
784 ide_add_setting(drive, "acoustic", SETTING_RW, TYPE_BYTE, 0, 254, 1, 1,
785 &drive->acoustic, set_acoustic);
786 ide_add_setting(drive, "failures", SETTING_RW, TYPE_INT, 0, 65535, 1, 1,
787 &drive->failures, NULL);
788 ide_add_setting(drive, "max_failures", SETTING_RW, TYPE_INT, 0, 65535,
789 1, 1, &drive->max_failures, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700790}
Bartlomiej Zolnierkiewicz7662d042007-05-10 00:01:10 +0200791#else
792static inline void idedisk_add_settings(ide_drive_t *drive) { ; }
793#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700794
Bartlomiej Zolnierkiewicz98416542008-04-26 17:36:37 +0200795static void idedisk_setup(ide_drive_t *drive)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700796{
Bartlomiej Zolnierkiewicz238e4f12007-10-19 00:30:07 +0200797 ide_hwif_t *hwif = drive->hwif;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700798 struct hd_driveid *id = drive->id;
799 unsigned long long capacity;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700800
801 idedisk_add_settings(drive);
802
803 if (drive->id_read == 0)
804 return;
805
Richard Purdie98109332006-02-03 03:04:55 -0800806 if (drive->removable) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700807 /*
Bartlomiej Zolnierkiewicz98416542008-04-26 17:36:37 +0200808 * Removable disks (eg. SYQUEST); ignore 'WD' drives
Linus Torvalds1da177e2005-04-16 15:20:36 -0700809 */
Bartlomiej Zolnierkiewicz98416542008-04-26 17:36:37 +0200810 if (id->model[0] != 'W' || id->model[1] != 'D')
Linus Torvalds1da177e2005-04-16 15:20:36 -0700811 drive->doorlocking = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700812 }
813
814 (void)set_lba_addressing(drive, 1);
815
816 if (drive->addressing == 1) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700817 int max_s = 2048;
818
819 if (max_s > hwif->rqsize)
820 max_s = hwif->rqsize;
821
822 blk_queue_max_sectors(drive->queue, max_s);
823 }
824
Bartlomiej Zolnierkiewicz98416542008-04-26 17:36:37 +0200825 printk(KERN_INFO "%s: max request size: %dKiB\n", drive->name,
826 drive->queue->max_sectors / 2);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700827
828 /* calculate drive capacity, and select LBA if possible */
Bartlomiej Zolnierkiewicz98416542008-04-26 17:36:37 +0200829 init_idedisk_capacity(drive);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700830
831 /* limit drive capacity to 137GB if LBA48 cannot be used */
832 if (drive->addressing == 0 && drive->capacity64 > 1ULL << 28) {
833 printk(KERN_WARNING "%s: cannot use LBA48 - full capacity "
834 "%llu sectors (%llu MB)\n",
835 drive->name, (unsigned long long)drive->capacity64,
836 sectors_to_MB(drive->capacity64));
837 drive->capacity64 = 1ULL << 28;
838 }
839
Bartlomiej Zolnierkiewicz238e4f12007-10-19 00:30:07 +0200840 if ((hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA) && drive->addressing) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700841 if (drive->capacity64 > 1ULL << 28) {
Bartlomiej Zolnierkiewicz98416542008-04-26 17:36:37 +0200842 printk(KERN_INFO "%s: cannot use LBA48 DMA - PIO mode"
843 " will be used for accessing sectors "
844 "> %u\n", drive->name, 1 << 28);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700845 } else
846 drive->addressing = 0;
847 }
848
849 /*
850 * if possible, give fdisk access to more of the drive,
851 * by correcting bios_cyls:
852 */
Bartlomiej Zolnierkiewicz98416542008-04-26 17:36:37 +0200853 capacity = idedisk_capacity(drive);
854
Linus Torvalds1da177e2005-04-16 15:20:36 -0700855 if (!drive->forced_geom) {
856
857 if (idedisk_supports_lba48(drive->id)) {
858 /* compatibility */
859 drive->bios_sect = 63;
860 drive->bios_head = 255;
861 }
862
863 if (drive->bios_sect && drive->bios_head) {
864 unsigned int cap0 = capacity; /* truncate to 32 bits */
865 unsigned int cylsz, cyl;
866
867 if (cap0 != capacity)
868 drive->bios_cyl = 65535;
869 else {
870 cylsz = drive->bios_sect * drive->bios_head;
871 cyl = cap0 / cylsz;
872 if (cyl > 65535)
873 cyl = 65535;
874 if (cyl > drive->bios_cyl)
875 drive->bios_cyl = cyl;
876 }
877 }
878 }
879 printk(KERN_INFO "%s: %llu sectors (%llu MB)",
880 drive->name, capacity, sectors_to_MB(capacity));
881
882 /* Only print cache size when it was specified */
883 if (id->buf_size)
Bartlomiej Zolnierkiewiczd12faa22008-02-26 21:50:36 +0100884 printk(KERN_CONT " w/%dKiB Cache", id->buf_size / 2);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700885
Bartlomiej Zolnierkiewicz3ab7efe2007-12-12 23:31:58 +0100886 printk(KERN_CONT ", CHS=%d/%d/%d\n",
887 drive->bios_cyl, drive->bios_head, drive->bios_sect);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700888
Linus Torvalds1da177e2005-04-16 15:20:36 -0700889 /* write cache enabled? */
890 if ((id->csfo & 1) || (id->cfs_enable_1 & (1 << 5)))
891 drive->wcache = 1;
892
893 write_cache(drive, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700894}
895
896static void ide_cacheflush_p(ide_drive_t *drive)
897{
898 if (!drive->wcache || !ide_id_has_flush_cache(drive->id))
899 return;
900
901 if (do_idedisk_flushcache(drive))
902 printk(KERN_INFO "%s: wcache flush failed!\n", drive->name);
903}
904
Russell King4031bbe2006-01-06 11:41:00 +0000905static void ide_disk_remove(ide_drive_t *drive)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700906{
907 struct ide_disk_obj *idkp = drive->driver_data;
908 struct gendisk *g = idkp->disk;
909
Bartlomiej Zolnierkiewicz7662d042007-05-10 00:01:10 +0200910 ide_proc_unregister_driver(drive, idkp->driver);
Bartlomiej Zolnierkiewicz8604aff2005-05-26 14:55:34 +0200911
Linus Torvalds1da177e2005-04-16 15:20:36 -0700912 del_gendisk(g);
913
Bartlomiej Zolnierkiewiczd36fef62005-12-15 02:19:20 +0100914 ide_cacheflush_p(drive);
915
Linus Torvalds1da177e2005-04-16 15:20:36 -0700916 ide_disk_put(idkp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700917}
918
919static void ide_disk_release(struct kref *kref)
920{
921 struct ide_disk_obj *idkp = to_ide_disk(kref);
922 ide_drive_t *drive = idkp->drive;
923 struct gendisk *g = idkp->disk;
924
925 drive->driver_data = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700926 g->private_data = NULL;
927 put_disk(g);
928 kfree(idkp);
929}
930
Russell King4031bbe2006-01-06 11:41:00 +0000931static int ide_disk_probe(ide_drive_t *drive);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700932
Lee Trager0d2157f2007-06-08 15:14:30 +0200933/*
934 * On HPA drives the capacity needs to be
935 * reinitilized on resume otherwise the disk
936 * can not be used and a hard reset is required
937 */
938static void ide_disk_resume(ide_drive_t *drive)
939{
940 if (idedisk_supports_hpa(drive->id))
941 init_idedisk_capacity(drive);
942}
943
Russell King4031bbe2006-01-06 11:41:00 +0000944static void ide_device_shutdown(ide_drive_t *drive)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700945{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700946#ifdef CONFIG_ALPHA
947 /* On Alpha, halt(8) doesn't actually turn the machine off,
948 it puts you into the sort of firmware monitor. Typically,
949 it's used to boot another kernel image, so it's not much
950 different from reboot(8). Therefore, we don't need to
951 spin down the disk in this case, especially since Alpha
952 firmware doesn't handle disks in standby mode properly.
953 On the other hand, it's reasonably safe to turn the power
954 off when the shutdown process reaches the firmware prompt,
955 as the firmware initialization takes rather long time -
956 at least 10 seconds, which should be sufficient for
957 the disk to expire its write cache. */
958 if (system_state != SYSTEM_POWER_OFF) {
959#else
960 if (system_state == SYSTEM_RESTART) {
961#endif
962 ide_cacheflush_p(drive);
963 return;
964 }
965
Bartlomiej Zolnierkiewiczd12faa22008-02-26 21:50:36 +0100966 printk(KERN_INFO "Shutdown: %s\n", drive->name);
967
Russell King4031bbe2006-01-06 11:41:00 +0000968 drive->gendev.bus->suspend(&drive->gendev, PMSG_SUSPEND);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700969}
970
Linus Torvalds1da177e2005-04-16 15:20:36 -0700971static ide_driver_t idedisk_driver = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700972 .gen_driver = {
Laurent Riffard4ef3b8f2005-11-18 22:15:40 +0100973 .owner = THIS_MODULE,
Bartlomiej Zolnierkiewicz8604aff2005-05-26 14:55:34 +0200974 .name = "ide-disk",
975 .bus = &ide_bus_type,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700976 },
Russell King4031bbe2006-01-06 11:41:00 +0000977 .probe = ide_disk_probe,
978 .remove = ide_disk_remove,
Lee Trager0d2157f2007-06-08 15:14:30 +0200979 .resume = ide_disk_resume,
Russell King4031bbe2006-01-06 11:41:00 +0000980 .shutdown = ide_device_shutdown,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700981 .version = IDEDISK_VERSION,
982 .media = ide_disk,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700983 .supports_dsc_overlap = 0,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700984 .do_request = ide_do_rw_disk,
985 .end_request = ide_end_request,
986 .error = __ide_error,
Bartlomiej Zolnierkiewicz7662d042007-05-10 00:01:10 +0200987#ifdef CONFIG_IDE_PROC_FS
Linus Torvalds1da177e2005-04-16 15:20:36 -0700988 .proc = idedisk_proc,
Bartlomiej Zolnierkiewicz7662d042007-05-10 00:01:10 +0200989#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700990};
991
Bartlomiej Zolnierkiewicz29ec6832008-01-26 20:12:59 +0100992static int idedisk_set_doorlock(ide_drive_t *drive, int on)
993{
994 ide_task_t task;
995
996 memset(&task, 0, sizeof(task));
997 task.tf.command = on ? WIN_DOORLOCK : WIN_DOORUNLOCK;
Bartlomiej Zolnierkiewicz657cc1a2008-01-26 20:13:10 +0100998 task.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
Bartlomiej Zolnierkiewicz29ec6832008-01-26 20:12:59 +0100999
1000 return ide_no_data_taskfile(drive, &task);
1001}
1002
Linus Torvalds1da177e2005-04-16 15:20:36 -07001003static int idedisk_open(struct inode *inode, struct file *filp)
1004{
1005 struct gendisk *disk = inode->i_bdev->bd_disk;
1006 struct ide_disk_obj *idkp;
1007 ide_drive_t *drive;
1008
Bartlomiej Zolnierkiewicz98416542008-04-26 17:36:37 +02001009 idkp = ide_disk_get(disk);
1010 if (idkp == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001011 return -ENXIO;
1012
1013 drive = idkp->drive;
1014
Bartlomiej Zolnierkiewiczc94964a2007-02-17 02:40:24 +01001015 idkp->openers++;
1016
1017 if (drive->removable && idkp->openers == 1) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001018 check_disk_change(inode->i_bdev);
1019 /*
1020 * Ignore the return code from door_lock,
1021 * since the open() has already succeeded,
1022 * and the door_lock is irrelevant at this point.
1023 */
Bartlomiej Zolnierkiewicz29ec6832008-01-26 20:12:59 +01001024 if (drive->doorlocking && idedisk_set_doorlock(drive, 1))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001025 drive->doorlocking = 0;
1026 }
1027 return 0;
1028}
1029
1030static int idedisk_release(struct inode *inode, struct file *filp)
1031{
1032 struct gendisk *disk = inode->i_bdev->bd_disk;
1033 struct ide_disk_obj *idkp = ide_disk_g(disk);
1034 ide_drive_t *drive = idkp->drive;
1035
Bartlomiej Zolnierkiewiczc94964a2007-02-17 02:40:24 +01001036 if (idkp->openers == 1)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001037 ide_cacheflush_p(drive);
Bartlomiej Zolnierkiewiczc94964a2007-02-17 02:40:24 +01001038
1039 if (drive->removable && idkp->openers == 1) {
Bartlomiej Zolnierkiewicz29ec6832008-01-26 20:12:59 +01001040 if (drive->doorlocking && idedisk_set_doorlock(drive, 0))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001041 drive->doorlocking = 0;
1042 }
Bartlomiej Zolnierkiewiczc94964a2007-02-17 02:40:24 +01001043
1044 idkp->openers--;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001045
1046 ide_disk_put(idkp);
1047
1048 return 0;
1049}
1050
Christoph Hellwiga885c8c2006-01-08 01:02:50 -08001051static int idedisk_getgeo(struct block_device *bdev, struct hd_geometry *geo)
1052{
1053 struct ide_disk_obj *idkp = ide_disk_g(bdev->bd_disk);
1054 ide_drive_t *drive = idkp->drive;
1055
1056 geo->heads = drive->bios_head;
1057 geo->sectors = drive->bios_sect;
1058 geo->cylinders = (u16)drive->bios_cyl; /* truncate */
1059 return 0;
1060}
1061
Linus Torvalds1da177e2005-04-16 15:20:36 -07001062static int idedisk_ioctl(struct inode *inode, struct file *file,
1063 unsigned int cmd, unsigned long arg)
1064{
Bartlomiej Zolnierkiewicz14979432007-05-10 00:01:10 +02001065 unsigned long flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001066 struct block_device *bdev = inode->i_bdev;
1067 struct ide_disk_obj *idkp = ide_disk_g(bdev->bd_disk);
Bartlomiej Zolnierkiewicz14979432007-05-10 00:01:10 +02001068 ide_drive_t *drive = idkp->drive;
1069 int err, (*setfunc)(ide_drive_t *, int);
1070 u8 *val;
1071
1072 switch (cmd) {
1073 case HDIO_GET_ADDRESS: val = &drive->addressing; goto read_val;
1074 case HDIO_GET_MULTCOUNT: val = &drive->mult_count; goto read_val;
1075 case HDIO_GET_NOWERR: val = &drive->nowerr; goto read_val;
1076 case HDIO_GET_WCACHE: val = &drive->wcache; goto read_val;
1077 case HDIO_GET_ACOUSTIC: val = &drive->acoustic; goto read_val;
1078 case HDIO_SET_ADDRESS: setfunc = set_lba_addressing; goto set_val;
1079 case HDIO_SET_MULTCOUNT: setfunc = set_multcount; goto set_val;
1080 case HDIO_SET_NOWERR: setfunc = set_nowerr; goto set_val;
1081 case HDIO_SET_WCACHE: setfunc = write_cache; goto set_val;
1082 case HDIO_SET_ACOUSTIC: setfunc = set_acoustic; goto set_val;
1083 }
1084
1085 return generic_ide_ioctl(drive, file, bdev, cmd, arg);
1086
1087read_val:
Matthias Kaehlckef9383c42007-07-09 23:17:56 +02001088 mutex_lock(&ide_setting_mtx);
Bartlomiej Zolnierkiewicz14979432007-05-10 00:01:10 +02001089 spin_lock_irqsave(&ide_lock, flags);
1090 err = *val;
1091 spin_unlock_irqrestore(&ide_lock, flags);
Matthias Kaehlckef9383c42007-07-09 23:17:56 +02001092 mutex_unlock(&ide_setting_mtx);
Bartlomiej Zolnierkiewicz14979432007-05-10 00:01:10 +02001093 return err >= 0 ? put_user(err, (long __user *)arg) : err;
1094
1095set_val:
1096 if (bdev != bdev->bd_contains)
1097 err = -EINVAL;
1098 else {
1099 if (!capable(CAP_SYS_ADMIN))
1100 err = -EACCES;
1101 else {
Matthias Kaehlckef9383c42007-07-09 23:17:56 +02001102 mutex_lock(&ide_setting_mtx);
Bartlomiej Zolnierkiewicz14979432007-05-10 00:01:10 +02001103 err = setfunc(drive, arg);
Matthias Kaehlckef9383c42007-07-09 23:17:56 +02001104 mutex_unlock(&ide_setting_mtx);
Bartlomiej Zolnierkiewicz14979432007-05-10 00:01:10 +02001105 }
1106 }
1107 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001108}
1109
1110static int idedisk_media_changed(struct gendisk *disk)
1111{
1112 struct ide_disk_obj *idkp = ide_disk_g(disk);
1113 ide_drive_t *drive = idkp->drive;
1114
1115 /* do not scan partitions twice if this is a removable device */
1116 if (drive->attach) {
1117 drive->attach = 0;
1118 return 0;
1119 }
1120 /* if removable, always assume it was changed */
1121 return drive->removable;
1122}
1123
1124static int idedisk_revalidate_disk(struct gendisk *disk)
1125{
1126 struct ide_disk_obj *idkp = ide_disk_g(disk);
1127 set_capacity(disk, idedisk_capacity(idkp->drive));
1128 return 0;
1129}
1130
1131static struct block_device_operations idedisk_ops = {
Bartlomiej Zolnierkiewicz98416542008-04-26 17:36:37 +02001132 .owner = THIS_MODULE,
1133 .open = idedisk_open,
1134 .release = idedisk_release,
1135 .ioctl = idedisk_ioctl,
1136 .getgeo = idedisk_getgeo,
1137 .media_changed = idedisk_media_changed,
1138 .revalidate_disk = idedisk_revalidate_disk
Linus Torvalds1da177e2005-04-16 15:20:36 -07001139};
1140
1141MODULE_DESCRIPTION("ATA DISK Driver");
1142
Russell King4031bbe2006-01-06 11:41:00 +00001143static int ide_disk_probe(ide_drive_t *drive)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001144{
1145 struct ide_disk_obj *idkp;
1146 struct gendisk *g;
1147
1148 /* strstr("foo", "") is non-NULL */
1149 if (!strstr("ide-disk", drive->driver_req))
1150 goto failed;
1151 if (!drive->present)
1152 goto failed;
1153 if (drive->media != ide_disk)
1154 goto failed;
1155
Deepak Saxenaf5e3c2f2005-11-07 01:01:25 -08001156 idkp = kzalloc(sizeof(*idkp), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001157 if (!idkp)
1158 goto failed;
1159
Tejun Heo689d6fa2008-08-25 19:56:16 +09001160 g = alloc_disk_node(IDE_DISK_MINORS, hwif_to_node(drive->hwif));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001161 if (!g)
1162 goto out_free_idkp;
1163
1164 ide_init_disk(g, drive);
1165
Bartlomiej Zolnierkiewicz7662d042007-05-10 00:01:10 +02001166 ide_proc_register_driver(drive, &idedisk_driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001167
Linus Torvalds1da177e2005-04-16 15:20:36 -07001168 kref_init(&idkp->kref);
1169
1170 idkp->drive = drive;
1171 idkp->driver = &idedisk_driver;
1172 idkp->disk = g;
1173
1174 g->private_data = &idkp->driver;
1175
1176 drive->driver_data = idkp;
1177
Linus Torvalds1da177e2005-04-16 15:20:36 -07001178 idedisk_setup(drive);
1179 if ((!drive->head || drive->head > 16) && !drive->select.b.lba) {
1180 printk(KERN_ERR "%s: INVALID GEOMETRY: %d PHYSICAL HEADS?\n",
1181 drive->name, drive->head);
1182 drive->attach = 0;
1183 } else
1184 drive->attach = 1;
Bartlomiej Zolnierkiewicz8604aff2005-05-26 14:55:34 +02001185
Tejun Heof615b482008-08-25 19:47:24 +09001186 g->minors = IDE_DISK_MINORS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001187 g->driverfs_dev = &drive->gendev;
Tejun Heo689d6fa2008-08-25 19:56:16 +09001188 g->flags |= GENHD_FL_EXT_DEVT;
1189 if (drive->removable)
1190 g->flags |= GENHD_FL_REMOVABLE;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001191 set_capacity(g, idedisk_capacity(drive));
1192 g->fops = &idedisk_ops;
1193 add_disk(g);
1194 return 0;
1195
Linus Torvalds1da177e2005-04-16 15:20:36 -07001196out_free_idkp:
1197 kfree(idkp);
1198failed:
Bartlomiej Zolnierkiewicz8604aff2005-05-26 14:55:34 +02001199 return -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001200}
1201
Bartlomiej Zolnierkiewicz98416542008-04-26 17:36:37 +02001202static void __exit idedisk_exit(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001203{
Bartlomiej Zolnierkiewicz8604aff2005-05-26 14:55:34 +02001204 driver_unregister(&idedisk_driver.gen_driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001205}
1206
Bartlomiej Zolnierkiewicz17514e82005-11-19 22:24:35 +01001207static int __init idedisk_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001208{
Bartlomiej Zolnierkiewicz8604aff2005-05-26 14:55:34 +02001209 return driver_register(&idedisk_driver.gen_driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001210}
1211
Kay Sievers263756e2005-12-12 18:03:44 +01001212MODULE_ALIAS("ide:*m-disk*");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001213module_init(idedisk_init);
1214module_exit(idedisk_exit);
1215MODULE_LICENSE("GPL");