1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
|
/* eject.c - eject device.
*
* Copyright 2012 Harvind Singh <harvindsingh1981@gmail.com>
* Copyright 2013 Kyungwan Han <asura321@gamil.com>
* Not in SUSv4.
USE_EJECT(NEWTOY(eject, ">1stT[!tT]", TOYFLAG_USR|TOYFLAG_BIN))
config EJECT
bool "eject"
default y
help
usage: eject [-s] [-t] [-T] [...]
Eject DEVICE or default /dev/cdrom
-s SCSI device
-t Close tray
-T Open/close tray (toggle).
*/
#define FOR_eject
#include "toys.h"
#include <scsi/sg.h>
#include <scsi/scsi.h>
#define CDROM_DRIVE_STATUS 0x5326 //Get tray position, etc.
#define CDROM_CLOSE_TRAY 0x5319 //Pendant of CDROM_EJECT.
#define CDROM_EJECT 0x5309 //Ejects the cdrom media.
#define DRIVE_NOT_READY 3 //Drive is busy.
/*
* Remove SCSI Device.
*/
static void remove_scsi(int dscptr)
{
char sg_driver_cmd[3][6] = {
{ ALLOW_MEDIUM_REMOVAL, 0, 0, 0, 0, 0 }, //allow medium removal
{ START_STOP, 0, 0, 0, 1, 0 }, //start the motor
{ START_STOP, 0, 0, 0, 2, 0 } //eject the media
};
unsigned i;
unsigned char buffer1[32],buffer2[2];
sg_io_hdr_t in_out_header;
if ((ioctl(dscptr, SG_GET_VERSION_NUM, &i) < 0) || (i < 30000))
error_exit("not a sg device or old sg driver");
memset(&in_out_header, 0, sizeof(sg_io_hdr_t));
in_out_header.interface_id = 'S';
in_out_header.cmd_len = 6;
in_out_header.mx_sb_len = sizeof(buffer1);
in_out_header.dxfer_direction = SG_DXFER_NONE;
in_out_header.dxferp = buffer2;
in_out_header.sbp = buffer1;
in_out_header.timeout = 2000;
for (i = 0; i < 3; i++) {
in_out_header.cmdp = (void *)sg_driver_cmd[i];
xioctl(dscptr, SG_IO, (void *)&in_out_header);
}
/* force kernel to reread partition table when new disc is inserted */
ioctl(dscptr, BLKRRPART);
}
/*
* eject main function.
*/
void eject_main(void)
{
int fd, out = 0, rc = 0;
char *device_name;
if (!toys.optc) device_name = "/dev/cdrom";
else device_name = toys.optargs[0];
fd = xopen(device_name, O_RDONLY | O_NONBLOCK);
if (!toys.optflags) xioctl(fd, CDROM_EJECT, &out);
else if (toys.optflags & FLAG_s) remove_scsi(fd);
else {
if (toys.optflags & FLAG_T || toys.optflags & FLAG_t) {
rc = ioctl(fd, CDROM_DRIVE_STATUS, &out);
if (toys.optflags & FLAG_t || rc == 2) //CDS_TRAY_OPEN = 2
xioctl(fd, CDROM_CLOSE_TRAY, &out);
else xioctl(fd, CDROM_EJECT, &out);
}
}
xclose(fd);
}
|