diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-04-29 11:18:34 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-04-29 11:18:34 -0700 |
commit | 4f567cbc957a7cffd1a428a000d93bd903f42349 (patch) | |
tree | e648bfed3732a23031a32811b20975827dad62d2 /drivers/misc/mei/hbm.c | |
parent | 92ddcf4a011a95dac98d3bbb0211a2fa42f13dc1 (diff) | |
parent | 0e27263926699fcbbd574cff4dd6920007a50e8a (diff) |
Merge tag 'char-misc-3.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc
Pull char/misc driver update from Greg Kroah-Hartman:
"Here's the big char / misc driver update for 3.10-rc1
A number of various driver updates, the majority being new
functionality in the MEI driver subsystem (it's now a subsystem, it
started out just a single driver), extcon updates, memory updates,
hyper-v updates, and a bunch of other small stuff that doesn't fit in
any other tree.
All of these have been in linux-next for a while"
* tag 'char-misc-3.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (148 commits)
Tools: hv: Fix a checkpatch warning
tools: hv: skip iso9660 mounts in hv_vss_daemon
tools: hv: use FIFREEZE/FITHAW in hv_vss_daemon
tools: hv: use getmntent in hv_vss_daemon
Tools: hv: Fix a checkpatch warning
tools: hv: fix checks for origin of netlink message in hv_vss_daemon
Tools: hv: fix warnings in hv_vss_daemon
misc: mark spear13xx-pcie-gadget as broken
mei: fix krealloc() misuse in in mei_cl_irq_read_msg()
mei: reduce flow control only for completed messages
mei: reseting -> resetting
mei: fix reading large reposnes
mei: revamp mei_irq_read_client_message function
mei: revamp mei_amthif_irq_read_message
mei: revamp hbm state machine
Revert "drivers/scsi: use module_pcmcia_driver() in pcmcia drivers"
Revert "scsi: pcmcia: nsp_cs: remove module init/exit function prototypes"
scsi: pcmcia: nsp_cs: remove module init/exit function prototypes
mei: wd: fix line over 80 characters
misc: tsl2550: Use dev_pm_ops
...
Diffstat (limited to 'drivers/misc/mei/hbm.c')
-rw-r--r-- | drivers/misc/mei/hbm.c | 82 |
1 files changed, 53 insertions, 29 deletions
diff --git a/drivers/misc/mei/hbm.c b/drivers/misc/mei/hbm.c index fb9e63ba3bb..db605f5cf18 100644 --- a/drivers/misc/mei/hbm.c +++ b/drivers/misc/mei/hbm.c @@ -52,7 +52,7 @@ static void mei_hbm_me_cl_allocate(struct mei_device *dev) sizeof(struct mei_me_client), GFP_KERNEL); if (!clients) { dev_err(&dev->pdev->dev, "memory allocation for ME clients failed.\n"); - dev->dev_state = MEI_DEV_RESETING; + dev->dev_state = MEI_DEV_RESETTING; mei_reset(dev, 1); return; } @@ -123,12 +123,33 @@ static bool is_treat_specially_client(struct mei_cl *cl, return false; } +int mei_hbm_start_wait(struct mei_device *dev) +{ + int ret; + if (dev->hbm_state > MEI_HBM_START) + return 0; + + mutex_unlock(&dev->device_lock); + ret = wait_event_interruptible_timeout(dev->wait_recvd_msg, + dev->hbm_state == MEI_HBM_IDLE || + dev->hbm_state > MEI_HBM_START, + mei_secs_to_jiffies(MEI_INTEROP_TIMEOUT)); + mutex_lock(&dev->device_lock); + + if (ret <= 0 && (dev->hbm_state <= MEI_HBM_START)) { + dev->hbm_state = MEI_HBM_IDLE; + dev_err(&dev->pdev->dev, "wating for mei start failed\n"); + return -ETIMEDOUT; + } + return 0; +} + /** * mei_hbm_start_req - sends start request message. * * @dev: the device structure */ -void mei_hbm_start_req(struct mei_device *dev) +int mei_hbm_start_req(struct mei_device *dev) { struct mei_msg_hdr *mei_hdr = &dev->wr_msg.hdr; struct hbm_host_version_request *start_req; @@ -143,18 +164,19 @@ void mei_hbm_start_req(struct mei_device *dev) start_req->host_version.major_version = HBM_MAJOR_VERSION; start_req->host_version.minor_version = HBM_MINOR_VERSION; - dev->recvd_msg = false; + dev->hbm_state = MEI_HBM_IDLE; if (mei_write_message(dev, mei_hdr, dev->wr_msg.data)) { - dev_dbg(&dev->pdev->dev, "write send version message to FW fail.\n"); - dev->dev_state = MEI_DEV_RESETING; + dev_err(&dev->pdev->dev, "version message writet failed\n"); + dev->dev_state = MEI_DEV_RESETTING; mei_reset(dev, 1); + return -ENODEV; } - dev->init_clients_state = MEI_START_MESSAGE; + dev->hbm_state = MEI_HBM_START; dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT; - return ; + return 0; } -/** +/* * mei_hbm_enum_clients_req - sends enumeration client request message. * * @dev: the device structure @@ -174,11 +196,11 @@ static void mei_hbm_enum_clients_req(struct mei_device *dev) enum_req->hbm_cmd = HOST_ENUM_REQ_CMD; if (mei_write_message(dev, mei_hdr, dev->wr_msg.data)) { - dev->dev_state = MEI_DEV_RESETING; - dev_dbg(&dev->pdev->dev, "write send enumeration request message to FW fail.\n"); + dev->dev_state = MEI_DEV_RESETTING; + dev_err(&dev->pdev->dev, "enumeration request write failed.\n"); mei_reset(dev, 1); } - dev->init_clients_state = MEI_ENUM_CLIENTS_MESSAGE; + dev->hbm_state = MEI_HBM_ENUM_CLIENTS; dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT; return; } @@ -208,6 +230,7 @@ static int mei_hbm_prop_req(struct mei_device *dev) /* We got all client properties */ if (next_client_index == MEI_CLIENTS_MAX) { + dev->hbm_state = MEI_HBM_STARTED; schedule_work(&dev->init_work); return 0; @@ -226,8 +249,8 @@ static int mei_hbm_prop_req(struct mei_device *dev) prop_req->address = next_client_index; if (mei_write_message(dev, mei_hdr, dev->wr_msg.data)) { - dev->dev_state = MEI_DEV_RESETING; - dev_err(&dev->pdev->dev, "Properties request command failed\n"); + dev->dev_state = MEI_DEV_RESETTING; + dev_err(&dev->pdev->dev, "properties request write failed\n"); mei_reset(dev, 1); return -EIO; @@ -542,27 +565,28 @@ void mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr) dev->version = version_res->me_max_version; dev_dbg(&dev->pdev->dev, "version mismatch.\n"); + dev->hbm_state = MEI_HBM_STOP; mei_hbm_stop_req_prepare(dev, &dev->wr_msg.hdr, dev->wr_msg.data); mei_write_message(dev, &dev->wr_msg.hdr, dev->wr_msg.data); + return; } dev->version.major_version = HBM_MAJOR_VERSION; dev->version.minor_version = HBM_MINOR_VERSION; if (dev->dev_state == MEI_DEV_INIT_CLIENTS && - dev->init_clients_state == MEI_START_MESSAGE) { + dev->hbm_state == MEI_HBM_START) { dev->init_clients_timer = 0; mei_hbm_enum_clients_req(dev); } else { - dev->recvd_msg = false; - dev_dbg(&dev->pdev->dev, "reset due to received hbm: host start\n"); + dev_err(&dev->pdev->dev, "reset: wrong host start response\n"); mei_reset(dev, 1); return; } - dev->recvd_msg = true; + wake_up_interruptible(&dev->wait_recvd_msg); dev_dbg(&dev->pdev->dev, "host start response message received.\n"); break; @@ -591,23 +615,20 @@ void mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr) me_client = &dev->me_clients[dev->me_client_presentation_num]; if (props_res->status || !dev->me_clients) { - dev_dbg(&dev->pdev->dev, "reset due to received host client properties response bus message wrong status.\n"); + dev_err(&dev->pdev->dev, "reset: properties response hbm wrong status.\n"); mei_reset(dev, 1); return; } if (me_client->client_id != props_res->address) { - dev_err(&dev->pdev->dev, - "Host client properties reply mismatch\n"); + dev_err(&dev->pdev->dev, "reset: host properties response address mismatch\n"); mei_reset(dev, 1); - return; } if (dev->dev_state != MEI_DEV_INIT_CLIENTS || - dev->init_clients_state != MEI_CLIENT_PROPERTIES_MESSAGE) { - dev_err(&dev->pdev->dev, - "Unexpected client properties reply\n"); + dev->hbm_state != MEI_HBM_CLIENT_PROPERTIES) { + dev_err(&dev->pdev->dev, "reset: unexpected properties response\n"); mei_reset(dev, 1); return; @@ -626,26 +647,28 @@ void mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr) enum_res = (struct hbm_host_enum_response *) mei_msg; memcpy(dev->me_clients_map, enum_res->valid_addresses, 32); if (dev->dev_state == MEI_DEV_INIT_CLIENTS && - dev->init_clients_state == MEI_ENUM_CLIENTS_MESSAGE) { + dev->hbm_state == MEI_HBM_ENUM_CLIENTS) { dev->init_clients_timer = 0; dev->me_client_presentation_num = 0; dev->me_client_index = 0; mei_hbm_me_cl_allocate(dev); - dev->init_clients_state = - MEI_CLIENT_PROPERTIES_MESSAGE; + dev->hbm_state = MEI_HBM_CLIENT_PROPERTIES; /* first property reqeust */ mei_hbm_prop_req(dev); } else { - dev_dbg(&dev->pdev->dev, "reset due to received host enumeration clients response bus message.\n"); + dev_err(&dev->pdev->dev, "reset: unexpected enumeration response hbm.\n"); mei_reset(dev, 1); return; } break; case HOST_STOP_RES_CMD: + + if (dev->hbm_state != MEI_HBM_STOP) + dev_err(&dev->pdev->dev, "unexpected stop response hbm.\n"); dev->dev_state = MEI_DEV_DISABLED; - dev_dbg(&dev->pdev->dev, "resetting because of FW stop response.\n"); + dev_info(&dev->pdev->dev, "reset: FW stop response.\n"); mei_reset(dev, 1); break; @@ -657,6 +680,7 @@ void mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr) case ME_STOP_REQ_CMD: + dev->hbm_state = MEI_HBM_STOP; mei_hbm_stop_req_prepare(dev, &dev->wr_ext_msg.hdr, dev->wr_ext_msg.data); break; |