USB: mos7720: always disable uart on close
[cascardo/linux.git] / drivers / target / target_core_rd.c
index 0457de3..e0b3c37 100644 (file)
@@ -256,10 +256,12 @@ static void rd_free_device(struct se_device *dev)
 
 static struct rd_dev_sg_table *rd_get_sg_table(struct rd_dev *rd_dev, u32 page)
 {
-       u32 i;
        struct rd_dev_sg_table *sg_table;
+       u32 i, sg_per_table = (RD_MAX_ALLOCATION_SIZE /
+                               sizeof(struct scatterlist));
 
-       for (i = 0; i < rd_dev->sg_table_count; i++) {
+       i = page / sg_per_table;
+       if (i < rd_dev->sg_table_count) {
                sg_table = &rd_dev->sg_table_array[i];
                if ((sg_table->page_start_offset <= page) &&
                    (sg_table->page_end_offset >= page))
@@ -314,7 +316,19 @@ rd_execute_rw(struct se_cmd *cmd)
                void *rd_addr;
 
                sg_miter_next(&m);
+               if (!(u32)m.length) {
+                       pr_debug("RD[%u]: invalid sgl %p len %zu\n",
+                                dev->rd_dev_id, m.addr, m.length);
+                       sg_miter_stop(&m);
+                       return TCM_INCORRECT_AMOUNT_OF_DATA;
+               }
                len = min((u32)m.length, src_len);
+               if (len > rd_size) {
+                       pr_debug("RD[%u]: size underrun page %d offset %d "
+                                "size %d\n", dev->rd_dev_id,
+                                rd_page, rd_offset, rd_size);
+                       len = rd_size;
+               }
                m.consumed = len;
 
                rd_addr = sg_virt(rd_sg) + rd_offset;