Commit 883b97ea authored by Petr Vandrovec's avatar Petr Vandrovec Committed by Stefan Richter

ieee1394: raw1394: Fix write() for 32bit userland on 64bit kernel

* write(fd, buf, 52) from 32bit app was returning 56.  Most of callers did not
  care, but some (arm registration) did, and anyway it looks bad if request for
  writing 52 bytes returns 56.  And returning sizeof anything in 'int' is not
  good as well.  So all functions now return '0' instead of
  sizeof(struct raw1394_request) on success, and write() itself provides correct
  return value (it just returns value it was asked to write on success as raw1394
  does not do any partial writes at all).

* Related to this was problem that write() could have returned 0 when kernel
  state would become corrupted and moved to different state than
  opened/initialized/connected.  Now it returns -EBADFD which seemed appropriate.
Signed-off-by: default avatarPetr Vandrovec <petr@vandrovec.name>
Acked-by: default avatarDan Dennedy <dan@dennedy.org>
Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de> (split into 3 patches)
parent ee9be425
...@@ -587,7 +587,7 @@ static int state_opened(struct file_info *fi, struct pending_request *req) ...@@ -587,7 +587,7 @@ static int state_opened(struct file_info *fi, struct pending_request *req)
req->req.length = 0; req->req.length = 0;
queue_complete_req(req); queue_complete_req(req);
return sizeof(struct raw1394_request); return 0;
} }
static int state_initialized(struct file_info *fi, struct pending_request *req) static int state_initialized(struct file_info *fi, struct pending_request *req)
...@@ -601,7 +601,7 @@ static int state_initialized(struct file_info *fi, struct pending_request *req) ...@@ -601,7 +601,7 @@ static int state_initialized(struct file_info *fi, struct pending_request *req)
req->req.generation = atomic_read(&internal_generation); req->req.generation = atomic_read(&internal_generation);
req->req.length = 0; req->req.length = 0;
queue_complete_req(req); queue_complete_req(req);
return sizeof(struct raw1394_request); return 0;
} }
switch (req->req.type) { switch (req->req.type) {
...@@ -673,7 +673,7 @@ out_set_card: ...@@ -673,7 +673,7 @@ out_set_card:
} }
queue_complete_req(req); queue_complete_req(req);
return sizeof(struct raw1394_request); return 0;
} }
static void handle_iso_listen(struct file_info *fi, struct pending_request *req) static void handle_iso_listen(struct file_info *fi, struct pending_request *req)
...@@ -865,7 +865,7 @@ static int handle_async_request(struct file_info *fi, ...@@ -865,7 +865,7 @@ static int handle_async_request(struct file_info *fi,
if (req->req.error) { if (req->req.error) {
req->req.length = 0; req->req.length = 0;
queue_complete_req(req); queue_complete_req(req);
return sizeof(struct raw1394_request); return 0;
} }
hpsb_set_packet_complete_task(packet, hpsb_set_packet_complete_task(packet,
...@@ -883,7 +883,7 @@ static int handle_async_request(struct file_info *fi, ...@@ -883,7 +883,7 @@ static int handle_async_request(struct file_info *fi,
hpsb_free_tlabel(packet); hpsb_free_tlabel(packet);
queue_complete_req(req); queue_complete_req(req);
} }
return sizeof(struct raw1394_request); return 0;
} }
static int handle_iso_send(struct file_info *fi, struct pending_request *req, static int handle_iso_send(struct file_info *fi, struct pending_request *req,
...@@ -907,7 +907,7 @@ static int handle_iso_send(struct file_info *fi, struct pending_request *req, ...@@ -907,7 +907,7 @@ static int handle_iso_send(struct file_info *fi, struct pending_request *req,
req->req.error = RAW1394_ERROR_MEMFAULT; req->req.error = RAW1394_ERROR_MEMFAULT;
req->req.length = 0; req->req.length = 0;
queue_complete_req(req); queue_complete_req(req);
return sizeof(struct raw1394_request); return 0;
} }
req->req.length = 0; req->req.length = 0;
...@@ -927,7 +927,7 @@ static int handle_iso_send(struct file_info *fi, struct pending_request *req, ...@@ -927,7 +927,7 @@ static int handle_iso_send(struct file_info *fi, struct pending_request *req,
queue_complete_req(req); queue_complete_req(req);
} }
return sizeof(struct raw1394_request); return 0;
} }
static int handle_async_send(struct file_info *fi, struct pending_request *req) static int handle_async_send(struct file_info *fi, struct pending_request *req)
...@@ -943,7 +943,7 @@ static int handle_async_send(struct file_info *fi, struct pending_request *req) ...@@ -943,7 +943,7 @@ static int handle_async_send(struct file_info *fi, struct pending_request *req)
req->req.error = RAW1394_ERROR_INVALID_ARG; req->req.error = RAW1394_ERROR_INVALID_ARG;
req->req.length = 0; req->req.length = 0;
queue_complete_req(req); queue_complete_req(req);
return sizeof(struct raw1394_request); return 0;
} }
data_size = req->req.length - header_length; data_size = req->req.length - header_length;
...@@ -957,7 +957,7 @@ static int handle_async_send(struct file_info *fi, struct pending_request *req) ...@@ -957,7 +957,7 @@ static int handle_async_send(struct file_info *fi, struct pending_request *req)
req->req.error = RAW1394_ERROR_MEMFAULT; req->req.error = RAW1394_ERROR_MEMFAULT;
req->req.length = 0; req->req.length = 0;
queue_complete_req(req); queue_complete_req(req);
return sizeof(struct raw1394_request); return 0;
} }
if (copy_from_user if (copy_from_user
...@@ -966,7 +966,7 @@ static int handle_async_send(struct file_info *fi, struct pending_request *req) ...@@ -966,7 +966,7 @@ static int handle_async_send(struct file_info *fi, struct pending_request *req)
req->req.error = RAW1394_ERROR_MEMFAULT; req->req.error = RAW1394_ERROR_MEMFAULT;
req->req.length = 0; req->req.length = 0;
queue_complete_req(req); queue_complete_req(req);
return sizeof(struct raw1394_request); return 0;
} }
packet->type = hpsb_async; packet->type = hpsb_async;
...@@ -994,7 +994,7 @@ static int handle_async_send(struct file_info *fi, struct pending_request *req) ...@@ -994,7 +994,7 @@ static int handle_async_send(struct file_info *fi, struct pending_request *req)
queue_complete_req(req); queue_complete_req(req);
} }
return sizeof(struct raw1394_request); return 0;
} }
static int arm_read(struct hpsb_host *host, int nodeid, quadlet_t * buffer, static int arm_read(struct hpsb_host *host, int nodeid, quadlet_t * buffer,
...@@ -1869,7 +1869,7 @@ static int arm_register(struct file_info *fi, struct pending_request *req) ...@@ -1869,7 +1869,7 @@ static int arm_register(struct file_info *fi, struct pending_request *req)
spin_lock_irqsave(&host_info_lock, flags); spin_lock_irqsave(&host_info_lock, flags);
list_add_tail(&addr->addr_list, &fi->addr_list); list_add_tail(&addr->addr_list, &fi->addr_list);
spin_unlock_irqrestore(&host_info_lock, flags); spin_unlock_irqrestore(&host_info_lock, flags);
return sizeof(struct raw1394_request); return 0;
} }
retval = retval =
hpsb_register_addrspace(&raw1394_highlevel, fi->host, &arm_ops, hpsb_register_addrspace(&raw1394_highlevel, fi->host, &arm_ops,
...@@ -1887,7 +1887,7 @@ static int arm_register(struct file_info *fi, struct pending_request *req) ...@@ -1887,7 +1887,7 @@ static int arm_register(struct file_info *fi, struct pending_request *req)
return (-EALREADY); return (-EALREADY);
} }
free_pending_request(req); /* immediate success or fail */ free_pending_request(req); /* immediate success or fail */
return sizeof(struct raw1394_request); return 0;
} }
static int arm_unregister(struct file_info *fi, struct pending_request *req) static int arm_unregister(struct file_info *fi, struct pending_request *req)
...@@ -1955,7 +1955,7 @@ static int arm_unregister(struct file_info *fi, struct pending_request *req) ...@@ -1955,7 +1955,7 @@ static int arm_unregister(struct file_info *fi, struct pending_request *req)
vfree(addr->addr_space_buffer); vfree(addr->addr_space_buffer);
kfree(addr); kfree(addr);
free_pending_request(req); /* immediate success or fail */ free_pending_request(req); /* immediate success or fail */
return sizeof(struct raw1394_request); return 0;
} }
retval = retval =
hpsb_unregister_addrspace(&raw1394_highlevel, fi->host, hpsb_unregister_addrspace(&raw1394_highlevel, fi->host,
...@@ -1971,7 +1971,7 @@ static int arm_unregister(struct file_info *fi, struct pending_request *req) ...@@ -1971,7 +1971,7 @@ static int arm_unregister(struct file_info *fi, struct pending_request *req)
vfree(addr->addr_space_buffer); vfree(addr->addr_space_buffer);
kfree(addr); kfree(addr);
free_pending_request(req); /* immediate success or fail */ free_pending_request(req); /* immediate success or fail */
return sizeof(struct raw1394_request); return 0;
} }
/* Copy data from ARM buffer(s) to user buffer. */ /* Copy data from ARM buffer(s) to user buffer. */
...@@ -2013,7 +2013,7 @@ static int arm_get_buf(struct file_info *fi, struct pending_request *req) ...@@ -2013,7 +2013,7 @@ static int arm_get_buf(struct file_info *fi, struct pending_request *req)
* queue no response, and therefore nobody * queue no response, and therefore nobody
* will free it. */ * will free it. */
free_pending_request(req); free_pending_request(req);
return sizeof(struct raw1394_request); return 0;
} else { } else {
DBGMSG("arm_get_buf request exceeded mapping"); DBGMSG("arm_get_buf request exceeded mapping");
spin_unlock_irqrestore(&host_info_lock, flags); spin_unlock_irqrestore(&host_info_lock, flags);
...@@ -2065,7 +2065,7 @@ static int arm_set_buf(struct file_info *fi, struct pending_request *req) ...@@ -2065,7 +2065,7 @@ static int arm_set_buf(struct file_info *fi, struct pending_request *req)
* queue no response, and therefore nobody * queue no response, and therefore nobody
* will free it. */ * will free it. */
free_pending_request(req); free_pending_request(req);
return sizeof(struct raw1394_request); return 0;
} else { } else {
DBGMSG("arm_set_buf request exceeded mapping"); DBGMSG("arm_set_buf request exceeded mapping");
spin_unlock_irqrestore(&host_info_lock, flags); spin_unlock_irqrestore(&host_info_lock, flags);
...@@ -2086,7 +2086,7 @@ static int reset_notification(struct file_info *fi, struct pending_request *req) ...@@ -2086,7 +2086,7 @@ static int reset_notification(struct file_info *fi, struct pending_request *req)
(req->req.misc == RAW1394_NOTIFY_ON)) { (req->req.misc == RAW1394_NOTIFY_ON)) {
fi->notification = (u8) req->req.misc; fi->notification = (u8) req->req.misc;
free_pending_request(req); /* we have to free the request, because we queue no response, and therefore nobody will free it */ free_pending_request(req); /* we have to free the request, because we queue no response, and therefore nobody will free it */
return sizeof(struct raw1394_request); return 0;
} }
/* error EINVAL (22) invalid argument */ /* error EINVAL (22) invalid argument */
return (-EINVAL); return (-EINVAL);
...@@ -2119,12 +2119,12 @@ static int write_phypacket(struct file_info *fi, struct pending_request *req) ...@@ -2119,12 +2119,12 @@ static int write_phypacket(struct file_info *fi, struct pending_request *req)
req->req.length = 0; req->req.length = 0;
queue_complete_req(req); queue_complete_req(req);
} }
return sizeof(struct raw1394_request); return 0;
} }
static int get_config_rom(struct file_info *fi, struct pending_request *req) static int get_config_rom(struct file_info *fi, struct pending_request *req)
{ {
int ret = sizeof(struct raw1394_request); int ret = 0;
quadlet_t *data = kmalloc(req->req.length, GFP_KERNEL); quadlet_t *data = kmalloc(req->req.length, GFP_KERNEL);
int status; int status;
...@@ -2154,7 +2154,7 @@ static int get_config_rom(struct file_info *fi, struct pending_request *req) ...@@ -2154,7 +2154,7 @@ static int get_config_rom(struct file_info *fi, struct pending_request *req)
static int update_config_rom(struct file_info *fi, struct pending_request *req) static int update_config_rom(struct file_info *fi, struct pending_request *req)
{ {
int ret = sizeof(struct raw1394_request); int ret = 0;
quadlet_t *data = kmalloc(req->req.length, GFP_KERNEL); quadlet_t *data = kmalloc(req->req.length, GFP_KERNEL);
if (!data) if (!data)
return -ENOMEM; return -ENOMEM;
...@@ -2221,7 +2221,7 @@ static int modify_config_rom(struct file_info *fi, struct pending_request *req) ...@@ -2221,7 +2221,7 @@ static int modify_config_rom(struct file_info *fi, struct pending_request *req)
hpsb_update_config_rom_image(fi->host); hpsb_update_config_rom_image(fi->host);
free_pending_request(req); free_pending_request(req);
return sizeof(struct raw1394_request); return 0;
} }
} }
...@@ -2286,7 +2286,7 @@ static int modify_config_rom(struct file_info *fi, struct pending_request *req) ...@@ -2286,7 +2286,7 @@ static int modify_config_rom(struct file_info *fi, struct pending_request *req)
/* we have to free the request, because we queue no response, /* we have to free the request, because we queue no response,
* and therefore nobody will free it */ * and therefore nobody will free it */
free_pending_request(req); free_pending_request(req);
return sizeof(struct raw1394_request); return 0;
} else { } else {
for (dentry = for (dentry =
fi->csr1212_dirs[dr]->value.directory.dentries_head; fi->csr1212_dirs[dr]->value.directory.dentries_head;
...@@ -2311,7 +2311,7 @@ static int state_connected(struct file_info *fi, struct pending_request *req) ...@@ -2311,7 +2311,7 @@ static int state_connected(struct file_info *fi, struct pending_request *req)
case RAW1394_REQ_ECHO: case RAW1394_REQ_ECHO:
queue_complete_req(req); queue_complete_req(req);
return sizeof(struct raw1394_request); return 0;
case RAW1394_REQ_ISO_SEND: case RAW1394_REQ_ISO_SEND:
print_old_iso_deprecation(); print_old_iso_deprecation();
...@@ -2335,24 +2335,24 @@ static int state_connected(struct file_info *fi, struct pending_request *req) ...@@ -2335,24 +2335,24 @@ static int state_connected(struct file_info *fi, struct pending_request *req)
case RAW1394_REQ_ISO_LISTEN: case RAW1394_REQ_ISO_LISTEN:
print_old_iso_deprecation(); print_old_iso_deprecation();
handle_iso_listen(fi, req); handle_iso_listen(fi, req);
return sizeof(struct raw1394_request); return 0;
case RAW1394_REQ_FCP_LISTEN: case RAW1394_REQ_FCP_LISTEN:
handle_fcp_listen(fi, req); handle_fcp_listen(fi, req);
return sizeof(struct raw1394_request); return 0;
case RAW1394_REQ_RESET_BUS: case RAW1394_REQ_RESET_BUS:
if (req->req.misc == RAW1394_LONG_RESET) { if (req->req.misc == RAW1394_LONG_RESET) {
DBGMSG("busreset called (type: LONG)"); DBGMSG("busreset called (type: LONG)");
hpsb_reset_bus(fi->host, LONG_RESET); hpsb_reset_bus(fi->host, LONG_RESET);
free_pending_request(req); /* we have to free the request, because we queue no response, and therefore nobody will free it */ free_pending_request(req); /* we have to free the request, because we queue no response, and therefore nobody will free it */
return sizeof(struct raw1394_request); return 0;
} }
if (req->req.misc == RAW1394_SHORT_RESET) { if (req->req.misc == RAW1394_SHORT_RESET) {
DBGMSG("busreset called (type: SHORT)"); DBGMSG("busreset called (type: SHORT)");
hpsb_reset_bus(fi->host, SHORT_RESET); hpsb_reset_bus(fi->host, SHORT_RESET);
free_pending_request(req); /* we have to free the request, because we queue no response, and therefore nobody will free it */ free_pending_request(req); /* we have to free the request, because we queue no response, and therefore nobody will free it */
return sizeof(struct raw1394_request); return 0;
} }
/* error EINVAL (22) invalid argument */ /* error EINVAL (22) invalid argument */
return (-EINVAL); return (-EINVAL);
...@@ -2371,7 +2371,7 @@ static int state_connected(struct file_info *fi, struct pending_request *req) ...@@ -2371,7 +2371,7 @@ static int state_connected(struct file_info *fi, struct pending_request *req)
req->req.generation = get_hpsb_generation(fi->host); req->req.generation = get_hpsb_generation(fi->host);
req->req.length = 0; req->req.length = 0;
queue_complete_req(req); queue_complete_req(req);
return sizeof(struct raw1394_request); return 0;
} }
switch (req->req.type) { switch (req->req.type) {
...@@ -2384,7 +2384,7 @@ static int state_connected(struct file_info *fi, struct pending_request *req) ...@@ -2384,7 +2384,7 @@ static int state_connected(struct file_info *fi, struct pending_request *req)
if (req->req.length == 0) { if (req->req.length == 0) {
req->req.error = RAW1394_ERROR_INVALID_ARG; req->req.error = RAW1394_ERROR_INVALID_ARG;
queue_complete_req(req); queue_complete_req(req);
return sizeof(struct raw1394_request); return 0;
} }
return handle_async_request(fi, req, node); return handle_async_request(fi, req, node);
...@@ -2395,7 +2395,7 @@ static ssize_t raw1394_write(struct file *file, const char __user * buffer, ...@@ -2395,7 +2395,7 @@ static ssize_t raw1394_write(struct file *file, const char __user * buffer,
{ {
struct file_info *fi = (struct file_info *)file->private_data; struct file_info *fi = (struct file_info *)file->private_data;
struct pending_request *req; struct pending_request *req;
ssize_t retval = 0; ssize_t retval = -EBADFD;
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT
if (count == sizeof(struct compat_raw1394_req) && if (count == sizeof(struct compat_raw1394_req) &&
...@@ -2437,6 +2437,9 @@ static ssize_t raw1394_write(struct file *file, const char __user * buffer, ...@@ -2437,6 +2437,9 @@ static ssize_t raw1394_write(struct file *file, const char __user * buffer,
if (retval < 0) { if (retval < 0) {
free_pending_request(req); free_pending_request(req);
} else {
BUG_ON(retval);
retval = count;
} }
return retval; return retval;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment