ubiformat includes command, data, command periods,
it breaks utp protocol for PUT commands. So we add two operations to fix it.
One is sending busy to host before the data periods begins.
The second is adding a new command to waiting ubiformat's command period.
Signed-off-by: Li Xingyu <b02754@freescale.com>
Signed-off-by: Peter Chen <peter.chen@freescale.com>
printk(KERN_WARNING "%s: exit with status %d\n",
__func__, uud->data.status);
UTP_SS_EXIT(fsg, uud->data.status);
printk(KERN_WARNING "%s: exit with status %d\n",
__func__, uud->data.status);
UTP_SS_EXIT(fsg, uud->data.status);
+ } else if (uud->data.flags & UTP_FLAG_REPORT_BUSY) {
+ UTP_SS_BUSY(fsg, --ctx->counter);
- pr_debug("%s: pass\n", __func__);
+ printk("%s: pass returned.\n", __func__);
UTP_SS_PASS(fsg);
}
utp_user_data_free(uud);
} else {
UTP_SS_PASS(fsg);
}
utp_user_data_free(uud);
} else {
- pr_debug("%s: still busy...\n", __func__);
+ if (utp_context.cur_state & UTP_FLAG_DATA) {
+ if (count_list(&ctx->read) < 7) {
+ pr_debug("%s: pass returned in POLL stage. \n", __func__);
+ UTP_SS_PASS(fsg);
+ utp_context.cur_state = 0;
+ return;
+ }
+ }
UTP_SS_BUSY(fsg, --ctx->counter);
}
}
UTP_SS_BUSY(fsg, --ctx->counter);
}
}
struct utp_user_data *uud = NULL, *uud2r;
struct utp_context *ctx = UTP_CTX(fsg);
struct utp_user_data *uud = NULL, *uud2r;
struct utp_context *ctx = UTP_CTX(fsg);
uud2r = utp_user_data_alloc(cmdsize + 1);
uud2r->data.flags = UTP_FLAG_COMMAND;
uud2r->data.payload = payload;
uud2r = utp_user_data_alloc(cmdsize + 1);
uud2r->data.flags = UTP_FLAG_COMMAND;
uud2r->data.payload = payload;
memcpy(ctx->buffer, uud->data.data, uud->data.bufsize);
UTP_SS_SIZE(fsg, uud->data.bufsize);
} else if (uud->data.flags & UTP_FLAG_REPORT_BUSY) {
memcpy(ctx->buffer, uud->data.data, uud->data.bufsize);
UTP_SS_SIZE(fsg, uud->data.bufsize);
} else if (uud->data.flags & UTP_FLAG_REPORT_BUSY) {
UTP_SS_BUSY(fsg, ctx->counter);
} else if (uud->data.flags & UTP_FLAG_STATUS) {
printk(KERN_WARNING "%s: exit with status %d\n", __func__,
uud->data.status);
UTP_SS_EXIT(fsg, uud->data.status);
} else {
UTP_SS_BUSY(fsg, ctx->counter);
} else if (uud->data.flags & UTP_FLAG_STATUS) {
printk(KERN_WARNING "%s: exit with status %d\n", __func__,
uud->data.status);
UTP_SS_EXIT(fsg, uud->data.status);
} else {
- pr_debug("%s: pass\n", __func__);
+ pr_debug("%s: pass returned in EXEC stage. \n", __func__);
UTP_SS_PASS(fsg);
}
utp_user_data_free(uud);
UTP_SS_PASS(fsg);
}
utp_user_data_free(uud);
fsg->common->data_size);
UTP_SS_PASS(fsg);
break;
fsg->common->data_size);
UTP_SS_PASS(fsg);
break;
- case UTP_PUT: /* data from host to device */
- pr_debug("%s: PUT, %d bytes\n", __func__,
- fsg->common->data_size);
+ case UTP_PUT:
+ utp_context.cur_state = UTP_FLAG_DATA;
+ pr_debug("%s: PUT, Received %d bytes\n", __func__, fsg->common->data_size);/* data from host to device */
uud2r = utp_user_data_alloc(fsg->common->data_size);
uud2r = utp_user_data_alloc(fsg->common->data_size);
+ if (!uud2r)
+ return -ENOMEM;
uud2r->data.bufsize = fsg->common->data_size;
uud2r->data.flags = UTP_FLAG_DATA;
utp_do_write(fsg, uud2r->data.data, fsg->common->data_size);
uud2r->data.bufsize = fsg->common->data_size;
uud2r->data.flags = UTP_FLAG_DATA;
utp_do_write(fsg, uud2r->data.data, fsg->common->data_size);
UTP_SS_PASS(fsg);
}
#endif
UTP_SS_PASS(fsg);
}
#endif
+ if (count_list(&UTP_CTX(fsg)->read) < 7) {
+ utp_context.cur_state = 0;
+ UTP_SS_PASS(fsg);
+ } else
+ UTP_SS_BUSY(fsg, UTP_CTX(fsg)->counter);
- wait_event_interruptible(UTP_CTX(fsg)->list_full_wq,
- count_list(&UTP_CTX(fsg)->read) < 7);
u8 *buffer;
u32 counter;
u64 utp_version;
u8 *buffer;
u32 counter;
u64 utp_version;
} utp_context;
static const struct file_operations utp_fops = {
} utp_context;
static const struct file_operations utp_fops = {