|
@@ -371,7 +371,7 @@ static __always_inline unsigned long parse_hex(const char **string)
|
|
|
}
|
|
|
|
|
|
static int process_set_region_mappings(struct switch_ctx *sctx,
|
|
|
- unsigned argc, char **argv)
|
|
|
+ unsigned argc, char **argv)
|
|
|
{
|
|
|
unsigned i;
|
|
|
unsigned long region_index = 0;
|
|
@@ -380,6 +380,51 @@ static int process_set_region_mappings(struct switch_ctx *sctx,
|
|
|
unsigned long path_nr;
|
|
|
const char *string = argv[i];
|
|
|
|
|
|
+ if ((*string & 0xdf) == 'R') {
|
|
|
+ unsigned long cycle_length, num_write;
|
|
|
+
|
|
|
+ string++;
|
|
|
+ if (unlikely(*string == ',')) {
|
|
|
+ DMWARN("invalid set_region_mappings argument: '%s'", argv[i]);
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+ cycle_length = parse_hex(&string);
|
|
|
+ if (unlikely(*string != ',')) {
|
|
|
+ DMWARN("invalid set_region_mappings argument: '%s'", argv[i]);
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+ string++;
|
|
|
+ if (unlikely(!*string)) {
|
|
|
+ DMWARN("invalid set_region_mappings argument: '%s'", argv[i]);
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+ num_write = parse_hex(&string);
|
|
|
+ if (unlikely(*string)) {
|
|
|
+ DMWARN("invalid set_region_mappings argument: '%s'", argv[i]);
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (unlikely(!cycle_length) || unlikely(cycle_length - 1 > region_index)) {
|
|
|
+ DMWARN("invalid set_region_mappings cycle length: %lu > %lu",
|
|
|
+ cycle_length - 1, region_index);
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+ if (unlikely(region_index + num_write < region_index) ||
|
|
|
+ unlikely(region_index + num_write >= sctx->nr_regions)) {
|
|
|
+ DMWARN("invalid set_region_mappings region number: %lu + %lu >= %lu",
|
|
|
+ region_index, num_write, sctx->nr_regions);
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ while (num_write--) {
|
|
|
+ region_index++;
|
|
|
+ path_nr = switch_region_table_read(sctx, region_index - cycle_length);
|
|
|
+ switch_region_table_write(sctx, region_index, path_nr);
|
|
|
+ }
|
|
|
+
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
if (*string == ':')
|
|
|
region_index++;
|
|
|
else {
|
|
@@ -508,7 +553,7 @@ static int switch_iterate_devices(struct dm_target *ti,
|
|
|
|
|
|
static struct target_type switch_target = {
|
|
|
.name = "switch",
|
|
|
- .version = {1, 0, 0},
|
|
|
+ .version = {1, 1, 0},
|
|
|
.module = THIS_MODULE,
|
|
|
.ctr = switch_ctr,
|
|
|
.dtr = switch_dtr,
|