aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ide')
-rw-r--r--drivers/ide/Kconfig2
-rw-r--r--drivers/ide/Makefile2
-rw-r--r--drivers/ide/cy82c693.c2
-rw-r--r--drivers/ide/ide-atapi.c3
-rw-r--r--drivers/ide/ide-cd.c22
-rw-r--r--drivers/ide/ide-cd.h3
-rw-r--r--drivers/ide/ide-cd_ioctl.c14
-rw-r--r--drivers/ide/ide-floppy.c2
-rw-r--r--drivers/ide/ide-gd.c19
-rw-r--r--drivers/ide/ide-io.c45
-rw-r--r--drivers/ide/ide-park.c2
-rw-r--r--drivers/ide/ide-taskfile.c2
-rw-r--r--drivers/ide/piix.c4
-rw-r--r--drivers/ide/sis5513.c4
-rw-r--r--drivers/ide/triflex.c2
-rw-r--r--drivers/ide/via82cxxx.c2
16 files changed, 70 insertions, 60 deletions
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig
index 98ccfeb3f5a..9827c5e686c 100644
--- a/drivers/ide/Kconfig
+++ b/drivers/ide/Kconfig
@@ -134,7 +134,7 @@ config BLK_DEV_IDECD
134 module will be called ide-cd. 134 module will be called ide-cd.
135 135
136config BLK_DEV_IDECD_VERBOSE_ERRORS 136config BLK_DEV_IDECD_VERBOSE_ERRORS
137 bool "Verbose error logging for IDE/ATAPI CDROM driver" if EMBEDDED 137 bool "Verbose error logging for IDE/ATAPI CDROM driver" if EXPERT
138 depends on BLK_DEV_IDECD 138 depends on BLK_DEV_IDECD
139 default y 139 default y
140 help 140 help
diff --git a/drivers/ide/Makefile b/drivers/ide/Makefile
index 81df925f0e8..7f879b2397b 100644
--- a/drivers/ide/Makefile
+++ b/drivers/ide/Makefile
@@ -2,7 +2,7 @@
2# link order is important here 2# link order is important here
3# 3#
4 4
5EXTRA_CFLAGS += -Idrivers/ide 5ccflags-y := -Idrivers/ide
6 6
7ide-core-y += ide.o ide-ioctls.o ide-io.o ide-iops.o ide-lib.o ide-probe.o \ 7ide-core-y += ide.o ide-ioctls.o ide-io.o ide-iops.o ide-lib.o ide-probe.o \
8 ide-taskfile.o ide-pm.o ide-park.o ide-sysfs.o ide-devsets.o \ 8 ide-taskfile.o ide-pm.o ide-park.o ide-sysfs.o ide-devsets.o \
diff --git a/drivers/ide/cy82c693.c b/drivers/ide/cy82c693.c
index 9383f67deae..3be60da5212 100644
--- a/drivers/ide/cy82c693.c
+++ b/drivers/ide/cy82c693.c
@@ -67,7 +67,7 @@ static void cy82c693_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
67 67
68 /* 68 /*
69 * note: below we set the value for Bus Master IDE TimeOut Register 69 * note: below we set the value for Bus Master IDE TimeOut Register
70 * I'm not absolutly sure what this does, but it solved my problem 70 * I'm not absolutely sure what this does, but it solved my problem
71 * with IDE DMA and sound, so I now can play sound and work with 71 * with IDE DMA and sound, so I now can play sound and work with
72 * my IDE driver at the same time :-) 72 * my IDE driver at the same time :-)
73 * 73 *
diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c
index e88a2cf1771..6f218e014e9 100644
--- a/drivers/ide/ide-atapi.c
+++ b/drivers/ide/ide-atapi.c
@@ -233,8 +233,7 @@ int ide_queue_sense_rq(ide_drive_t *drive, void *special)
233 233
234 drive->hwif->rq = NULL; 234 drive->hwif->rq = NULL;
235 235
236 elv_add_request(drive->queue, &drive->sense_rq, 236 elv_add_request(drive->queue, &drive->sense_rq, ELEVATOR_INSERT_FRONT);
237 ELEVATOR_INSERT_FRONT, 0);
238 return 0; 237 return 0;
239} 238}
240EXPORT_SYMBOL_GPL(ide_queue_sense_rq); 239EXPORT_SYMBOL_GPL(ide_queue_sense_rq);
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index 0c73fe39a23..a5ec5a7cb38 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -258,17 +258,10 @@ static int ide_cd_breathe(ide_drive_t *drive, struct request *rq)
258 if (time_after(jiffies, info->write_timeout)) 258 if (time_after(jiffies, info->write_timeout))
259 return 0; 259 return 0;
260 else { 260 else {
261 struct request_queue *q = drive->queue;
262 unsigned long flags;
263
264 /* 261 /*
265 * take a breather relying on the unplug timer to kick us again 262 * take a breather
266 */ 263 */
267 264 blk_delay_queue(drive->queue, 1);
268 spin_lock_irqsave(q->queue_lock, flags);
269 blk_plug_device(q);
270 spin_unlock_irqrestore(q->queue_lock, flags);
271
272 return 1; 265 return 1;
273 } 266 }
274} 267}
@@ -1177,7 +1170,7 @@ static struct cdrom_device_ops ide_cdrom_dops = {
1177 .open = ide_cdrom_open_real, 1170 .open = ide_cdrom_open_real,
1178 .release = ide_cdrom_release_real, 1171 .release = ide_cdrom_release_real,
1179 .drive_status = ide_cdrom_drive_status, 1172 .drive_status = ide_cdrom_drive_status,
1180 .media_changed = ide_cdrom_check_media_change_real, 1173 .check_events = ide_cdrom_check_events_real,
1181 .tray_move = ide_cdrom_tray_move, 1174 .tray_move = ide_cdrom_tray_move,
1182 .lock_door = ide_cdrom_lock_door, 1175 .lock_door = ide_cdrom_lock_door,
1183 .select_speed = ide_cdrom_select_speed, 1176 .select_speed = ide_cdrom_select_speed,
@@ -1514,8 +1507,6 @@ static int ide_cdrom_setup(ide_drive_t *drive)
1514 blk_queue_dma_alignment(q, 31); 1507 blk_queue_dma_alignment(q, 31);
1515 blk_queue_update_dma_pad(q, 15); 1508 blk_queue_update_dma_pad(q, 15);
1516 1509
1517 q->unplug_delay = max((1 * HZ) / 1000, 1);
1518
1519 drive->dev_flags |= IDE_DFLAG_MEDIA_CHANGED; 1510 drive->dev_flags |= IDE_DFLAG_MEDIA_CHANGED;
1520 drive->atapi_flags = IDE_AFLAG_NO_EJECT | ide_cd_flags(id); 1511 drive->atapi_flags = IDE_AFLAG_NO_EJECT | ide_cd_flags(id);
1521 1512
@@ -1702,10 +1693,11 @@ static int idecd_ioctl(struct block_device *bdev, fmode_t mode,
1702} 1693}
1703 1694
1704 1695
1705static int idecd_media_changed(struct gendisk *disk) 1696static unsigned int idecd_check_events(struct gendisk *disk,
1697 unsigned int clearing)
1706{ 1698{
1707 struct cdrom_info *info = ide_drv_g(disk, cdrom_info); 1699 struct cdrom_info *info = ide_drv_g(disk, cdrom_info);
1708 return cdrom_media_changed(&info->devinfo); 1700 return cdrom_check_events(&info->devinfo, clearing);
1709} 1701}
1710 1702
1711static int idecd_revalidate_disk(struct gendisk *disk) 1703static int idecd_revalidate_disk(struct gendisk *disk)
@@ -1723,7 +1715,7 @@ static const struct block_device_operations idecd_ops = {
1723 .open = idecd_open, 1715 .open = idecd_open,
1724 .release = idecd_release, 1716 .release = idecd_release,
1725 .ioctl = idecd_ioctl, 1717 .ioctl = idecd_ioctl,
1726 .media_changed = idecd_media_changed, 1718 .check_events = idecd_check_events,
1727 .revalidate_disk = idecd_revalidate_disk 1719 .revalidate_disk = idecd_revalidate_disk
1728}; 1720};
1729 1721
diff --git a/drivers/ide/ide-cd.h b/drivers/ide/ide-cd.h
index 93a3cf1b0f3..1efc936f5b6 100644
--- a/drivers/ide/ide-cd.h
+++ b/drivers/ide/ide-cd.h
@@ -111,7 +111,8 @@ int cdrom_check_status(ide_drive_t *, struct request_sense *);
111int ide_cdrom_open_real(struct cdrom_device_info *, int); 111int ide_cdrom_open_real(struct cdrom_device_info *, int);
112void ide_cdrom_release_real(struct cdrom_device_info *); 112void ide_cdrom_release_real(struct cdrom_device_info *);
113int ide_cdrom_drive_status(struct cdrom_device_info *, int); 113int ide_cdrom_drive_status(struct cdrom_device_info *, int);
114int ide_cdrom_check_media_change_real(struct cdrom_device_info *, int); 114unsigned int ide_cdrom_check_events_real(struct cdrom_device_info *,
115 unsigned int clearing, int slot_nr);
115int ide_cdrom_tray_move(struct cdrom_device_info *, int); 116int ide_cdrom_tray_move(struct cdrom_device_info *, int);
116int ide_cdrom_lock_door(struct cdrom_device_info *, int); 117int ide_cdrom_lock_door(struct cdrom_device_info *, int);
117int ide_cdrom_select_speed(struct cdrom_device_info *, int); 118int ide_cdrom_select_speed(struct cdrom_device_info *, int);
diff --git a/drivers/ide/ide-cd_ioctl.c b/drivers/ide/ide-cd_ioctl.c
index 766b3deeb23..02caa7dd51c 100644
--- a/drivers/ide/ide-cd_ioctl.c
+++ b/drivers/ide/ide-cd_ioctl.c
@@ -79,8 +79,14 @@ int ide_cdrom_drive_status(struct cdrom_device_info *cdi, int slot_nr)
79 return CDS_DRIVE_NOT_READY; 79 return CDS_DRIVE_NOT_READY;
80} 80}
81 81
82int ide_cdrom_check_media_change_real(struct cdrom_device_info *cdi, 82/*
83 int slot_nr) 83 * ide-cd always generates media changed event if media is missing, which
84 * makes it impossible to use for proper event reporting, so disk->events
85 * is cleared to 0 and the following function is used only to trigger
86 * revalidation and never propagated to userland.
87 */
88unsigned int ide_cdrom_check_events_real(struct cdrom_device_info *cdi,
89 unsigned int clearing, int slot_nr)
84{ 90{
85 ide_drive_t *drive = cdi->handle; 91 ide_drive_t *drive = cdi->handle;
86 int retval; 92 int retval;
@@ -89,9 +95,9 @@ int ide_cdrom_check_media_change_real(struct cdrom_device_info *cdi,
89 (void) cdrom_check_status(drive, NULL); 95 (void) cdrom_check_status(drive, NULL);
90 retval = (drive->dev_flags & IDE_DFLAG_MEDIA_CHANGED) ? 1 : 0; 96 retval = (drive->dev_flags & IDE_DFLAG_MEDIA_CHANGED) ? 1 : 0;
91 drive->dev_flags &= ~IDE_DFLAG_MEDIA_CHANGED; 97 drive->dev_flags &= ~IDE_DFLAG_MEDIA_CHANGED;
92 return retval; 98 return retval ? DISK_EVENT_MEDIA_CHANGE : 0;
93 } else { 99 } else {
94 return -EINVAL; 100 return 0;
95 } 101 }
96} 102}
97 103
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c
index 536ff68062a..61fdf544fbd 100644
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -107,7 +107,7 @@ static int ide_floppy_callback(ide_drive_t *drive, int dsc)
107static void ide_floppy_report_error(struct ide_disk_obj *floppy, 107static void ide_floppy_report_error(struct ide_disk_obj *floppy,
108 struct ide_atapi_pc *pc) 108 struct ide_atapi_pc *pc)
109{ 109{
110 /* supress error messages resulting from Medium not present */ 110 /* suppress error messages resulting from Medium not present */
111 if (floppy->sense_key == 0x02 && 111 if (floppy->sense_key == 0x02 &&
112 floppy->asc == 0x3a && 112 floppy->asc == 0x3a &&
113 floppy->ascq == 0x00) 113 floppy->ascq == 0x00)
diff --git a/drivers/ide/ide-gd.c b/drivers/ide/ide-gd.c
index 35c4b43585e..70ea8763567 100644
--- a/drivers/ide/ide-gd.c
+++ b/drivers/ide/ide-gd.c
@@ -285,11 +285,12 @@ static int ide_gd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
285 return 0; 285 return 0;
286} 286}
287 287
288static int ide_gd_media_changed(struct gendisk *disk) 288static unsigned int ide_gd_check_events(struct gendisk *disk,
289 unsigned int clearing)
289{ 290{
290 struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj); 291 struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj);
291 ide_drive_t *drive = idkp->drive; 292 ide_drive_t *drive = idkp->drive;
292 int ret; 293 bool ret;
293 294
294 /* do not scan partitions twice if this is a removable device */ 295 /* do not scan partitions twice if this is a removable device */
295 if (drive->dev_flags & IDE_DFLAG_ATTACH) { 296 if (drive->dev_flags & IDE_DFLAG_ATTACH) {
@@ -297,10 +298,16 @@ static int ide_gd_media_changed(struct gendisk *disk)
297 return 0; 298 return 0;
298 } 299 }
299 300
300 ret = !!(drive->dev_flags & IDE_DFLAG_MEDIA_CHANGED); 301 /*
302 * The following is used to force revalidation on the first open on
303 * removeable devices, and never gets reported to userland as
304 * genhd->events is 0. This is intended as removeable ide disk
305 * can't really detect MEDIA_CHANGE events.
306 */
307 ret = drive->dev_flags & IDE_DFLAG_MEDIA_CHANGED;
301 drive->dev_flags &= ~IDE_DFLAG_MEDIA_CHANGED; 308 drive->dev_flags &= ~IDE_DFLAG_MEDIA_CHANGED;
302 309
303 return ret; 310 return ret ? DISK_EVENT_MEDIA_CHANGE : 0;
304} 311}
305 312
306static void ide_gd_unlock_native_capacity(struct gendisk *disk) 313static void ide_gd_unlock_native_capacity(struct gendisk *disk)
@@ -318,7 +325,7 @@ static int ide_gd_revalidate_disk(struct gendisk *disk)
318 struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj); 325 struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj);
319 ide_drive_t *drive = idkp->drive; 326 ide_drive_t *drive = idkp->drive;
320 327
321 if (ide_gd_media_changed(disk)) 328 if (ide_gd_check_events(disk, 0))
322 drive->disk_ops->get_capacity(drive); 329 drive->disk_ops->get_capacity(drive);
323 330
324 set_capacity(disk, ide_gd_capacity(drive)); 331 set_capacity(disk, ide_gd_capacity(drive));
@@ -340,7 +347,7 @@ static const struct block_device_operations ide_gd_ops = {
340 .release = ide_gd_release, 347 .release = ide_gd_release,
341 .ioctl = ide_gd_ioctl, 348 .ioctl = ide_gd_ioctl,
342 .getgeo = ide_gd_getgeo, 349 .getgeo = ide_gd_getgeo,
343 .media_changed = ide_gd_media_changed, 350 .check_events = ide_gd_check_events,
344 .unlock_native_capacity = ide_gd_unlock_native_capacity, 351 .unlock_native_capacity = ide_gd_unlock_native_capacity,
345 .revalidate_disk = ide_gd_revalidate_disk 352 .revalidate_disk = ide_gd_revalidate_disk
346}; 353};
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
index 999dac054bc..177db6d5b2f 100644
--- a/drivers/ide/ide-io.c
+++ b/drivers/ide/ide-io.c
@@ -430,6 +430,26 @@ static inline void ide_unlock_host(struct ide_host *host)
430 } 430 }
431} 431}
432 432
433static void __ide_requeue_and_plug(struct request_queue *q, struct request *rq)
434{
435 if (rq)
436 blk_requeue_request(q, rq);
437 if (rq || blk_peek_request(q)) {
438 /* Use 3ms as that was the old plug delay */
439 blk_delay_queue(q, 3);
440 }
441}
442
443void ide_requeue_and_plug(ide_drive_t *drive, struct request *rq)
444{
445 struct request_queue *q = drive->queue;
446 unsigned long flags;
447
448 spin_lock_irqsave(q->queue_lock, flags);
449 __ide_requeue_and_plug(q, rq);
450 spin_unlock_irqrestore(q->queue_lock, flags);
451}
452
433/* 453/*
434 * Issue a new request to a device. 454 * Issue a new request to a device.
435 */ 455 */
@@ -440,6 +460,7 @@ void do_ide_request(struct request_queue *q)
440 struct ide_host *host = hwif->host; 460 struct ide_host *host = hwif->host;
441 struct request *rq = NULL; 461 struct request *rq = NULL;
442 ide_startstop_t startstop; 462 ide_startstop_t startstop;
463 unsigned long queue_run_ms = 3; /* old plug delay */
443 464
444 spin_unlock_irq(q->queue_lock); 465 spin_unlock_irq(q->queue_lock);
445 466
@@ -459,6 +480,9 @@ repeat:
459 prev_port = hwif->host->cur_port; 480 prev_port = hwif->host->cur_port;
460 if (drive->dev_flags & IDE_DFLAG_SLEEPING && 481 if (drive->dev_flags & IDE_DFLAG_SLEEPING &&
461 time_after(drive->sleep, jiffies)) { 482 time_after(drive->sleep, jiffies)) {
483 unsigned long left = jiffies - drive->sleep;
484
485 queue_run_ms = jiffies_to_msecs(left + 1);
462 ide_unlock_port(hwif); 486 ide_unlock_port(hwif);
463 goto plug_device; 487 goto plug_device;
464 } 488 }
@@ -546,26 +570,7 @@ plug_device:
546 ide_unlock_host(host); 570 ide_unlock_host(host);
547plug_device_2: 571plug_device_2:
548 spin_lock_irq(q->queue_lock); 572 spin_lock_irq(q->queue_lock);
549 573 __ide_requeue_and_plug(q, rq);
550 if (rq)
551 blk_requeue_request(q, rq);
552 if (!elv_queue_empty(q))
553 blk_plug_device(q);
554}
555
556void ide_requeue_and_plug(ide_drive_t *drive, struct request *rq)
557{
558 struct request_queue *q = drive->queue;
559 unsigned long flags;
560
561 spin_lock_irqsave(q->queue_lock, flags);
562
563 if (rq)
564 blk_requeue_request(q, rq);
565 if (!elv_queue_empty(q))
566 blk_plug_device(q);
567
568 spin_unlock_irqrestore(q->queue_lock, flags);
569} 574}
570 575
571static int drive_is_ready(ide_drive_t *drive) 576static int drive_is_ready(ide_drive_t *drive)
diff --git a/drivers/ide/ide-park.c b/drivers/ide/ide-park.c
index 88a380c5a47..6ab9ab2a508 100644
--- a/drivers/ide/ide-park.c
+++ b/drivers/ide/ide-park.c
@@ -52,7 +52,7 @@ static void issue_park_cmd(ide_drive_t *drive, unsigned long timeout)
52 rq->cmd[0] = REQ_UNPARK_HEADS; 52 rq->cmd[0] = REQ_UNPARK_HEADS;
53 rq->cmd_len = 1; 53 rq->cmd_len = 1;
54 rq->cmd_type = REQ_TYPE_SPECIAL; 54 rq->cmd_type = REQ_TYPE_SPECIAL;
55 elv_add_request(q, rq, ELEVATOR_INSERT_FRONT, 1); 55 elv_add_request(q, rq, ELEVATOR_INSERT_FRONT);
56 56
57out: 57out:
58 return; 58 return;
diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c
index 34b9872f35d..600c89a3d13 100644
--- a/drivers/ide/ide-taskfile.c
+++ b/drivers/ide/ide-taskfile.c
@@ -201,7 +201,7 @@ static u8 wait_drive_not_busy(ide_drive_t *drive)
201 u8 stat; 201 u8 stat;
202 202
203 /* 203 /*
204 * Last sector was transfered, wait until device is ready. This can 204 * Last sector was transferred, wait until device is ready. This can
205 * take up to 6 ms on some ATAPI devices, so we will wait max 10 ms. 205 * take up to 6 ms on some ATAPI devices, so we will wait max 10 ms.
206 */ 206 */
207 for (retries = 0; retries < 1000; retries++) { 207 for (retries = 0; retries < 1000; retries++) {
diff --git a/drivers/ide/piix.c b/drivers/ide/piix.c
index 1bdca49e5a0..b59d04c7205 100644
--- a/drivers/ide/piix.c
+++ b/drivers/ide/piix.c
@@ -8,8 +8,8 @@
8 * 8 *
9 * Documentation: 9 * Documentation:
10 * 10 *
11 * Publically available from Intel web site. Errata documentation 11 * Publicly available from Intel web site. Errata documentation
12 * is also publically available. As an aide to anyone hacking on this 12 * is also publicly available. As an aide to anyone hacking on this
13 * driver the list of errata that are relevant is below.going back to 13 * driver the list of errata that are relevant is below.going back to
14 * PIIX4. Older device documentation is now a bit tricky to find. 14 * PIIX4. Older device documentation is now a bit tricky to find.
15 * 15 *
diff --git a/drivers/ide/sis5513.c b/drivers/ide/sis5513.c
index db7f4e761db..4a002256775 100644
--- a/drivers/ide/sis5513.c
+++ b/drivers/ide/sis5513.c
@@ -53,7 +53,7 @@
53 53
54#define DRV_NAME "sis5513" 54#define DRV_NAME "sis5513"
55 55
56/* registers layout and init values are chipset family dependant */ 56/* registers layout and init values are chipset family dependent */
57 57
58#define ATA_16 0x01 58#define ATA_16 0x01
59#define ATA_33 0x02 59#define ATA_33 0x02
@@ -406,7 +406,7 @@ static int __devinit sis_find_family(struct pci_dev *dev)
406 pci_name(dev)); 406 pci_name(dev));
407 chipset_family = ATA_133; 407 chipset_family = ATA_133;
408 408
409 /* Check for 5513 compability mapping 409 /* Check for 5513 compatibility mapping
410 * We must use this, else the port enabled code will fail, 410 * We must use this, else the port enabled code will fail,
411 * as it expects the enablebits at 0x4a. 411 * as it expects the enablebits at 0x4a.
412 */ 412 */
diff --git a/drivers/ide/triflex.c b/drivers/ide/triflex.c
index 7953447eae0..e53a1b78378 100644
--- a/drivers/ide/triflex.c
+++ b/drivers/ide/triflex.c
@@ -22,7 +22,7 @@
22 * Loosely based on the piix & svwks drivers. 22 * Loosely based on the piix & svwks drivers.
23 * 23 *
24 * Documentation: 24 * Documentation:
25 * Not publically available. 25 * Not publicly available.
26 */ 26 */
27 27
28#include <linux/types.h> 28#include <linux/types.h>
diff --git a/drivers/ide/via82cxxx.c b/drivers/ide/via82cxxx.c
index d2a0997b78f..f46f49cfcc2 100644
--- a/drivers/ide/via82cxxx.c
+++ b/drivers/ide/via82cxxx.c
@@ -14,7 +14,7 @@
14 * Andre Hedrick 14 * Andre Hedrick
15 * 15 *
16 * Documentation: 16 * Documentation:
17 * Obsolete device documentation publically available from via.com.tw 17 * Obsolete device documentation publicly available from via.com.tw
18 * Current device documentation available under NDA only 18 * Current device documentation available under NDA only
19 */ 19 */
20 20