|
@@ -141,6 +141,43 @@ struct visornic_devdata {
|
|
|
struct uiscmdrsp cmdrsp[SIZEOF_CMDRSP];
|
|
|
};
|
|
|
|
|
|
+/* Returns next non-zero index on success or 0 on failure (i.e. out of room). */
|
|
|
+static inline u16
|
|
|
+add_physinfo_entries(u64 inp_pfn, u16 inp_off, u32 inp_len, u16 index,
|
|
|
+ u16 max_pi_arr_entries, struct phys_info pi_arr[])
|
|
|
+{
|
|
|
+ u32 len;
|
|
|
+ u16 i, firstlen;
|
|
|
+
|
|
|
+ firstlen = PI_PAGE_SIZE - inp_off;
|
|
|
+ if (inp_len <= firstlen) {
|
|
|
+ /* The input entry spans only one page - add as is. */
|
|
|
+ if (index >= max_pi_arr_entries)
|
|
|
+ return 0;
|
|
|
+ pi_arr[index].pi_pfn = inp_pfn;
|
|
|
+ pi_arr[index].pi_off = (u16)inp_off;
|
|
|
+ pi_arr[index].pi_len = (u16)inp_len;
|
|
|
+ return index + 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* This entry spans multiple pages. */
|
|
|
+ for (len = inp_len, i = 0; len;
|
|
|
+ len -= pi_arr[index + i].pi_len, i++) {
|
|
|
+ if (index + i >= max_pi_arr_entries)
|
|
|
+ return 0;
|
|
|
+ pi_arr[index + i].pi_pfn = inp_pfn + i;
|
|
|
+ if (i == 0) {
|
|
|
+ pi_arr[index].pi_off = inp_off;
|
|
|
+ pi_arr[index].pi_len = firstlen;
|
|
|
+ } else {
|
|
|
+ pi_arr[index + i].pi_off = 0;
|
|
|
+ pi_arr[index + i].pi_len =
|
|
|
+ (u16)MINNUM(len, (u32)PI_PAGE_SIZE);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return index + i;
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* visor_copy_fragsinfo_from_skb(
|
|
|
* @skb_in: skbuff that we are pulling the frags from
|