767 {
768 struct heci_me_client *clients;
769 struct heci_me_client *client;
770 uint8_t num, i, j;
771 int err;
772
773 if (dev->num_heci_me_clients == 0)
774 return (0);
775
776 mutex_enter(&dev->device_lock);
777 if (dev->me_clients) {
778 kmem_free(dev->me_clients, dev->num_heci_me_clients*
779 sizeof (struct heci_me_client));
780 dev->me_clients = NULL;
781 }
782 mutex_exit(&dev->device_lock);
783
784 /* allocate storage for ME clients representation */
785 clients = kmem_zalloc(dev->num_heci_me_clients*
786 sizeof (struct heci_me_client), KM_SLEEP);
787 if (!clients) {
788 DBG("memory allocation for ME clients failed.\n");
789 return (-ENOMEM);
790 }
791
792 mutex_enter(&dev->device_lock);
793 dev->me_clients = clients;
794 mutex_exit(&dev->device_lock);
795
796 num = 0;
797 for (i = 0; i < sizeof (dev->heci_me_clients); i++) {
798 for (j = 0; j < 8; j++) {
799 if ((dev->heci_me_clients[i] & (1 << j)) != 0) {
800 client = &dev->me_clients[num];
801 client->client_id = (i * 8) + j;
802 client->flow_ctrl_creds = 0;
803 err = host_client_properties(dev, client);
804 if (err != 0) {
805 mutex_enter(&dev->device_lock);
806 kmem_free(dev->me_clients,
807 dev->num_heci_me_clients*
808 sizeof (struct heci_me_client));
809 dev->me_clients = NULL;
810 mutex_exit(&dev->device_lock);
1034
1035 if (heci_connect_me_client(dev, &dev->iamthif_file_ext, 15) == 1) {
1036 DBG("connected to iamthif client.\n");
1037 dev->iamthif_state = HECI_IAMTHIF_IDLE;
1038 }
1039 mutex_exit(&dev->device_lock);
1040 }
1041
1042 /*
1043 * heci_alloc_file_private - allocates a private file structure and set it up.
1044 * @file: the file structure
1045 *
1046 * @return The allocated file or NULL on failure
1047 */
1048 struct heci_file_private *
1049 heci_alloc_file_private(struct heci_file *file)
1050 {
1051 struct heci_file_private *priv;
1052
1053 priv = kmem_zalloc(sizeof (struct heci_file_private), KM_SLEEP);
1054 if (!priv)
1055 return (NULL);
1056
1057 heci_init_file_private(priv, file);
1058
1059 return (priv);
1060 }
1061
1062 /*
1063 * heci_free_file_private - free a private file structure that were previously
1064 * allocated by heci_alloc_file_private
1065 */
1066 void
1067 heci_free_file_private(struct heci_file_private *priv)
1068 {
1069 mutex_destroy(&priv->file_lock);
1070 mutex_destroy(&priv->read_io_lock);
1071 mutex_destroy(&priv->write_io_lock);
1072 cv_destroy(&priv->rx_wait);
1073 kmem_free(priv, sizeof (struct heci_file_private));
1074
1075 }
1082 * @file_ext: private data of the file object
1083 *
1084 * @return 0 on success, <0 on failure.
1085 */
1086 int
1087 heci_disconnect_host_client(struct iamt_heci_device *dev,
1088 struct heci_file_private *file_ext)
1089 {
1090 int rets, err;
1091 long timeout = 15; /* 15 seconds */
1092 struct heci_cb_private *priv_cb;
1093 clock_t delta = (clock_t)(timeout * HZ);
1094
1095 if ((!dev) || (!file_ext))
1096 return (-ENODEV);
1097
1098 if (file_ext->state != HECI_FILE_DISCONNECTING)
1099 return (0);
1100
1101 priv_cb = kmem_zalloc(sizeof (struct heci_cb_private), KM_SLEEP);
1102 if (!priv_cb)
1103 return (-ENOMEM);
1104
1105 LIST_INIT_HEAD(&priv_cb->cb_list);
1106 priv_cb->file_private = file_ext;
1107 priv_cb->major_file_operations = HECI_CLOSE;
1108 mutex_enter(&dev->device_lock);
1109 if (dev->host_buffer_is_empty) {
1110 dev->host_buffer_is_empty = 0;
1111 if (heci_disconnect(dev, file_ext)) {
1112 list_add_tail(&priv_cb->cb_list,
1113 &dev->ctrl_rd_list.heci_cb.cb_list);
1114 } else {
1115 mutex_exit(&dev->device_lock);
1116 rets = -ENODEV;
1117 DBG("failed to call heci_disconnect.\n");
1118 goto free;
1119 }
1120 } else {
1121 DBG("add disconnect cb to control write list\n");
1122 list_add_tail(&priv_cb->cb_list,
1123 &dev->ctrl_wr_list.heci_cb.cb_list);
|
767 {
768 struct heci_me_client *clients;
769 struct heci_me_client *client;
770 uint8_t num, i, j;
771 int err;
772
773 if (dev->num_heci_me_clients == 0)
774 return (0);
775
776 mutex_enter(&dev->device_lock);
777 if (dev->me_clients) {
778 kmem_free(dev->me_clients, dev->num_heci_me_clients*
779 sizeof (struct heci_me_client));
780 dev->me_clients = NULL;
781 }
782 mutex_exit(&dev->device_lock);
783
784 /* allocate storage for ME clients representation */
785 clients = kmem_zalloc(dev->num_heci_me_clients*
786 sizeof (struct heci_me_client), KM_SLEEP);
787
788 mutex_enter(&dev->device_lock);
789 dev->me_clients = clients;
790 mutex_exit(&dev->device_lock);
791
792 num = 0;
793 for (i = 0; i < sizeof (dev->heci_me_clients); i++) {
794 for (j = 0; j < 8; j++) {
795 if ((dev->heci_me_clients[i] & (1 << j)) != 0) {
796 client = &dev->me_clients[num];
797 client->client_id = (i * 8) + j;
798 client->flow_ctrl_creds = 0;
799 err = host_client_properties(dev, client);
800 if (err != 0) {
801 mutex_enter(&dev->device_lock);
802 kmem_free(dev->me_clients,
803 dev->num_heci_me_clients*
804 sizeof (struct heci_me_client));
805 dev->me_clients = NULL;
806 mutex_exit(&dev->device_lock);
1030
1031 if (heci_connect_me_client(dev, &dev->iamthif_file_ext, 15) == 1) {
1032 DBG("connected to iamthif client.\n");
1033 dev->iamthif_state = HECI_IAMTHIF_IDLE;
1034 }
1035 mutex_exit(&dev->device_lock);
1036 }
1037
1038 /*
1039 * heci_alloc_file_private - allocates a private file structure and set it up.
1040 * @file: the file structure
1041 *
1042 * @return The allocated file or NULL on failure
1043 */
1044 struct heci_file_private *
1045 heci_alloc_file_private(struct heci_file *file)
1046 {
1047 struct heci_file_private *priv;
1048
1049 priv = kmem_zalloc(sizeof (struct heci_file_private), KM_SLEEP);
1050
1051 heci_init_file_private(priv, file);
1052
1053 return (priv);
1054 }
1055
1056 /*
1057 * heci_free_file_private - free a private file structure that were previously
1058 * allocated by heci_alloc_file_private
1059 */
1060 void
1061 heci_free_file_private(struct heci_file_private *priv)
1062 {
1063 mutex_destroy(&priv->file_lock);
1064 mutex_destroy(&priv->read_io_lock);
1065 mutex_destroy(&priv->write_io_lock);
1066 cv_destroy(&priv->rx_wait);
1067 kmem_free(priv, sizeof (struct heci_file_private));
1068
1069 }
1076 * @file_ext: private data of the file object
1077 *
1078 * @return 0 on success, <0 on failure.
1079 */
1080 int
1081 heci_disconnect_host_client(struct iamt_heci_device *dev,
1082 struct heci_file_private *file_ext)
1083 {
1084 int rets, err;
1085 long timeout = 15; /* 15 seconds */
1086 struct heci_cb_private *priv_cb;
1087 clock_t delta = (clock_t)(timeout * HZ);
1088
1089 if ((!dev) || (!file_ext))
1090 return (-ENODEV);
1091
1092 if (file_ext->state != HECI_FILE_DISCONNECTING)
1093 return (0);
1094
1095 priv_cb = kmem_zalloc(sizeof (struct heci_cb_private), KM_SLEEP);
1096
1097 LIST_INIT_HEAD(&priv_cb->cb_list);
1098 priv_cb->file_private = file_ext;
1099 priv_cb->major_file_operations = HECI_CLOSE;
1100 mutex_enter(&dev->device_lock);
1101 if (dev->host_buffer_is_empty) {
1102 dev->host_buffer_is_empty = 0;
1103 if (heci_disconnect(dev, file_ext)) {
1104 list_add_tail(&priv_cb->cb_list,
1105 &dev->ctrl_rd_list.heci_cb.cb_list);
1106 } else {
1107 mutex_exit(&dev->device_lock);
1108 rets = -ENODEV;
1109 DBG("failed to call heci_disconnect.\n");
1110 goto free;
1111 }
1112 } else {
1113 DBG("add disconnect cb to control write list\n");
1114 list_add_tail(&priv_cb->cb_list,
1115 &dev->ctrl_wr_list.heci_cb.cb_list);
|