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 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
| static char* find_usb_device_path_from_dev(struct device *dev) { struct usb_device *usb_dev = NULL;
while (dev) { if (dev->bus) { if (strcmp(dev->bus->name, "usb") == 0) {
usb_dev = to_usb_device(dev);
if (!usb_dev || !usb_dev->devpath) { dev = dev->parent; continue; }
if (usb_dev->bus && usb_dev->bus->busnum) { return usb_dev->devpath; } } } dev = dev->parent; } return NULL; }
void check_sr_read_access(struct scsi_cd *cd, fmode_t *mode, unsigned cmd, void __user *argp) { struct sg_io_hdr hdr; u8 opcode;
if (!cd->writeable && cmd == SG_IO) { if (!copy_from_user(&hdr, argp, sizeof(hdr)) && !copy_from_user(&opcode, hdr.cmdp, sizeof(opcode))) { if (opcode == WRITE_10 || opcode == WRITE_BLANK || opcode == FORMAT_UNIT || \ opcode == WRITE_LONG || opcode == WRITE_12 || opcode == WRITE_LONG_2 || \ opcode == WRITE_16 || opcode == WRITE_ATTRIBUTE) { *mode &= ~FMODE_WRITE; } } } }
static int sr_block_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, unsigned long arg) { struct scsi_cd *cd = scsi_cd(bdev->bd_disk); struct scsi_device *sdev = cd->device; void __user *argp = (void __user *)arg; int ret;
mutex_lock(&cd->lock); ...... switch (cmd) { case SCSI_IOCTL_GET_IDLUN: case SCSI_IOCTL_GET_BUS_NUMBER: ret = scsi_ioctl(sdev, cmd, argp); goto put; } #ifdef CONFIG_USB_SMARTCTL if (strstr(cd->device->host->hostt->name, "usb")) check_sr_read_access(cd, &mode, cmd, argp); #endif ...... }
#ifdef CONFIG_COMPAT static int sr_block_compat_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, unsigned long arg) { struct scsi_cd *cd = scsi_cd(bdev->bd_disk); struct scsi_device *sdev = cd->device; void __user *argp = compat_ptr(arg); int ret; ...... switch (cmd) { case SCSI_IOCTL_GET_IDLUN: case SCSI_IOCTL_GET_BUS_NUMBER: ret = scsi_compat_ioctl(sdev, cmd, argp); goto put; }
#ifdef CONFIG_HUAWEI_ARMPC_SMART_USB if (strstr(cd->device->host->hostt->name, "usb")) check_sr_read_access(cd, &mode, cmd, argp); #endif ...... }
static void get_capabilities(struct scsi_cd *cd) { ......
if ((cd->cdi.mask & (CDC_DVD_RAM | CDC_MRW_W | CDC_RAM | CDC_CD_RW)) != (CDC_DVD_RAM | CDC_MRW_W | CDC_RAM | CDC_CD_RW)) { cd->writeable = 1; }
#ifdef CONFIG_USB_SMARTCTL char *usb_path = NULL;
if ((cd->device) && (&(cd->device->sdev_gendev))) usb_path = find_usb_device_path_from_dev(&(cd->device->sdev_gendev));
if (usb_path && check_usb_smart_status(usb_path)) { cd->writeable = 0; set_disk_ro(cd->disk, 1); } #endif ...... }
|