Skip to content

Commit

Permalink
usb: mass_storage: Add support for SC_REBOOT
Browse files Browse the repository at this point in the history
Add support for a vendor specific SCSI pass through command to
trigger reboot.

SC_REBOOT (0xd7) - triggers reboot into fastboot mode
SC_REBOOT_1 (0xd8) - triggers reboot into normal mode.

Change-Id: I6b5b2b072782e9f804782071552258993df741cb
Signed-off-by: Ravi Vembu <[email protected]>
Reviewed-on: http://gerrit.mot.com/807585
SLTApproved: Slta Waiver <[email protected]>
SME-Granted: SME Approvals Granted
Tested-by: Jira Key <[email protected]>
Submit-Approved: Jira Key <[email protected]>
  • Loading branch information
Ravi Vembu authored and Alberto97 committed Dec 22, 2018
1 parent b2796bd commit 34217ab
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 0 deletions.
64 changes: 64 additions & 0 deletions drivers/usb/gadget/function/f_mass_storage.c
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@
#include <linux/kref.h>
#include <linux/kthread.h>
#include <linux/limits.h>
#include <linux/reboot.h>
#include <linux/rwsem.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
Expand All @@ -228,6 +229,12 @@
#define FSG_DRIVER_DESC "Mass Storage Function"
#define FSG_DRIVER_VERSION "2009/09/11"

enum fsg_restart_type {
FSG_RESTART_NONE,
FSG_REBOOT,
FSG_REBOOT_BL,
};

static const char fsg_string_interface[] = "Mass Storage";

#include "storage_common.h"
Expand Down Expand Up @@ -330,6 +337,8 @@ struct fsg_common {
char name[FSG_MAX_LUNS][LUN_NAME_LEN];
struct kref ref;
struct timer_list vfs_timer;
enum fsg_restart_type restart_type;
struct delayed_work restart_work;
};

struct fsg_dev {
Expand Down Expand Up @@ -2206,6 +2215,34 @@ static int do_scsi_command(struct fsg_common *common)
if (reply == 0)
reply = do_write(common);
break;
case SC_REBOOT:
common->data_size_from_cmnd = 0;
reply = check_command(common, common->cmnd_size,
DATA_DIR_NONE, 0, 0, "REBOOT BL");
if (reply == 0) {
common->curlun->sense_data = SS_INVALID_COMMAND;
reply = -EINVAL;
} else {
pr_err("Triggered Reboot from SCSI Command\n");
common->restart_type = FSG_REBOOT;
schedule_delayed_work(&common->restart_work,
msecs_to_jiffies(1000));
}
break;
case SC_REBOOT_2:
common->data_size_from_cmnd = 0;
reply = check_command(common, common->cmnd_size,
DATA_DIR_NONE, 0, 0, "REBOOT");
if (reply == 0) {
common->curlun->sense_data = SS_INVALID_COMMAND;
reply = -EINVAL;
} else {
pr_err("Triggered Reboot BL from SCSI Command\n");
common->restart_type = FSG_REBOOT_BL;
schedule_delayed_work(&common->restart_work,
msecs_to_jiffies(1000));
}
break;

/*
* Some mandatory commands that we recognize but don't implement.
Expand Down Expand Up @@ -2870,6 +2907,32 @@ static inline int fsg_num_buffers_validate(unsigned int fsg_num_buffers)
return -EINVAL;
}

static int disable_restarts;
module_param(disable_restarts, int, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(disable_restarts, "Disable SCSI Initiated Reboots");
static void fsg_restart_work(struct work_struct *work)
{
struct fsg_common *common = container_of(work,
struct fsg_common,
restart_work.work);

if (disable_restarts) {
pr_err("SCSI Reboots Disabled\n");
return;
}

switch (common->restart_type) {
case FSG_REBOOT:
kernel_restart("");
break;
case FSG_REBOOT_BL:
kernel_restart("bootloader");
break;
default:
break;
}
}

static struct fsg_common *fsg_common_setup(struct fsg_common *common)
{
if (!common) {
Expand All @@ -2885,6 +2948,7 @@ static struct fsg_common *fsg_common_setup(struct fsg_common *common)
kref_init(&common->ref);
init_completion(&common->thread_notifier);
init_waitqueue_head(&common->fsg_wait);
INIT_DELAYED_WORK(&common->restart_work, fsg_restart_work);
common->state = FSG_STATE_TERMINATED;

return common;
Expand Down
4 changes: 4 additions & 0 deletions include/scsi/scsi.h
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,10 @@ enum scsi_timeouts {
#define ATA_16 0x85 /* 16-byte pass-thru */
#define ATA_12 0xa1 /* 12-byte pass-thru */

/* Vendor Specific */
#define SC_REBOOT 0xd7
#define SC_REBOOT_2 0xd8

/*
* SCSI command lengths
*/
Expand Down

0 comments on commit 34217ab

Please sign in to comment.