jm199354 | 911106d | 2007-11-08 16:09:20 -0800 | [diff] [blame] | 1 | /* |
| 2 | * CDDL HEADER START |
| 3 | * |
| 4 | * The contents of this file are subject to the terms of the |
| 5 | * Common Development and Distribution License (the "License"). |
| 6 | * You may not use this file except in compliance with the License. |
| 7 | * |
| 8 | * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE |
| 9 | * or http://www.opensolaris.org/os/licensing. |
| 10 | * See the License for the specific language governing permissions |
| 11 | * and limitations under the License. |
| 12 | * |
| 13 | * When distributing Covered Code, include this CDDL HEADER in each |
| 14 | * file and include the License file at usr/src/OPENSOLARIS.LICENSE. |
| 15 | * If applicable, add the following below this CDDL HEADER, with the |
| 16 | * fields enclosed by brackets "[]" replaced with your own identifying |
| 17 | * information: Portions Copyright [yyyy] [name of copyright owner] |
| 18 | * |
| 19 | * CDDL HEADER END |
| 20 | */ |
| 21 | |
| 22 | /* |
Rafael Vanoni | d3d5073 | 2009-11-13 01:32:32 -0800 | [diff] [blame] | 23 | * Copyright 2009 Sun Microsystems, Inc. All rights reserved. |
jm199354 | 911106d | 2007-11-08 16:09:20 -0800 | [diff] [blame] | 24 | * Use is subject to license terms. |
| 25 | */ |
| 26 | |
jm199354 | 911106d | 2007-11-08 16:09:20 -0800 | [diff] [blame] | 27 | #include <sys/types.h> |
Alan Wright | 1843d05 | 2008-10-25 14:44:56 -0700 | [diff] [blame] | 28 | #include <sys/errno.h> |
jm199354 | 911106d | 2007-11-08 16:09:20 -0800 | [diff] [blame] | 29 | #include <sys/kmem.h> |
| 30 | #include <sys/vnode.h> |
| 31 | #include <sys/pathname.h> |
| 32 | #include <sys/door.h> |
| 33 | #include <sys/cmn_err.h> |
| 34 | #include <sys/sunddi.h> /* for string functions */ |
| 35 | #include <sys/vscan.h> |
| 36 | |
Alan Wright | 1843d05 | 2008-10-25 14:44:56 -0700 | [diff] [blame] | 37 | #define VS_DOOR_RETRIES 3 |
jm199354 | 911106d | 2007-11-08 16:09:20 -0800 | [diff] [blame] | 38 | |
jm199354 | bfc848c | 2008-04-10 17:45:54 -0700 | [diff] [blame] | 39 | /* max time (secs) to wait for door calls to complete during door_close */ |
| 40 | #define VS_DOOR_CLOSE_TIMEOUT_DEFAULT 30 |
| 41 | uint32_t vs_door_close_timeout = VS_DOOR_CLOSE_TIMEOUT_DEFAULT; |
| 42 | |
jm199354 | 911106d | 2007-11-08 16:09:20 -0800 | [diff] [blame] | 43 | static door_handle_t vscan_door_handle = NULL; |
| 44 | static kmutex_t vscan_door_mutex; |
| 45 | static kcondvar_t vscan_door_cv; |
| 46 | static int vscan_door_call_count = 0; |
| 47 | |
| 48 | |
| 49 | /* |
| 50 | * vscan_door_init |
| 51 | */ |
| 52 | int |
| 53 | vscan_door_init(void) |
| 54 | { |
| 55 | mutex_init(&vscan_door_mutex, NULL, MUTEX_DEFAULT, NULL); |
| 56 | cv_init(&vscan_door_cv, NULL, CV_DEFAULT, NULL); |
| 57 | return (0); |
| 58 | } |
| 59 | |
| 60 | |
| 61 | /* |
| 62 | * vscan_door_fini |
| 63 | */ |
| 64 | void |
| 65 | vscan_door_fini(void) |
| 66 | { |
| 67 | mutex_destroy(&vscan_door_mutex); |
| 68 | cv_destroy(&vscan_door_cv); |
| 69 | } |
| 70 | |
| 71 | |
| 72 | /* |
| 73 | * vscan_door_open |
| 74 | */ |
| 75 | int |
| 76 | vscan_door_open(int door_id) |
| 77 | { |
| 78 | mutex_enter(&vscan_door_mutex); |
| 79 | |
jm199354 | bfc848c | 2008-04-10 17:45:54 -0700 | [diff] [blame] | 80 | if (vscan_door_handle == NULL) |
jm199354 | 911106d | 2007-11-08 16:09:20 -0800 | [diff] [blame] | 81 | vscan_door_handle = door_ki_lookup(door_id); |
jm199354 | 911106d | 2007-11-08 16:09:20 -0800 | [diff] [blame] | 82 | |
| 83 | if (vscan_door_handle == NULL) { |
| 84 | cmn_err(CE_WARN, "Internal communication error " |
| 85 | "- failed to access vscan service daemon."); |
jm199354 | bfc848c | 2008-04-10 17:45:54 -0700 | [diff] [blame] | 86 | mutex_exit(&vscan_door_mutex); |
jm199354 | 911106d | 2007-11-08 16:09:20 -0800 | [diff] [blame] | 87 | return (-1); |
| 88 | } |
| 89 | |
jm199354 | bfc848c | 2008-04-10 17:45:54 -0700 | [diff] [blame] | 90 | mutex_exit(&vscan_door_mutex); |
jm199354 | 911106d | 2007-11-08 16:09:20 -0800 | [diff] [blame] | 91 | return (0); |
| 92 | } |
| 93 | |
| 94 | |
| 95 | /* |
| 96 | * vscan_door_close |
| 97 | */ |
| 98 | void |
| 99 | vscan_door_close(void) |
| 100 | { |
jm199354 | bfc848c | 2008-04-10 17:45:54 -0700 | [diff] [blame] | 101 | clock_t timeout, time_left; |
| 102 | |
jm199354 | 911106d | 2007-11-08 16:09:20 -0800 | [diff] [blame] | 103 | mutex_enter(&vscan_door_mutex); |
| 104 | |
| 105 | /* wait for any in-progress requests to complete */ |
jm199354 | bfc848c | 2008-04-10 17:45:54 -0700 | [diff] [blame] | 106 | time_left = SEC_TO_TICK(vs_door_close_timeout); |
| 107 | while ((vscan_door_call_count > 0) && (time_left > 0)) { |
Rafael Vanoni | d3d5073 | 2009-11-13 01:32:32 -0800 | [diff] [blame] | 108 | timeout = time_left; |
| 109 | time_left = cv_reltimedwait(&vscan_door_cv, &vscan_door_mutex, |
| 110 | timeout, TR_CLOCK_TICK); |
jm199354 | 911106d | 2007-11-08 16:09:20 -0800 | [diff] [blame] | 111 | } |
| 112 | |
jm199354 | bfc848c | 2008-04-10 17:45:54 -0700 | [diff] [blame] | 113 | if (time_left == -1) |
| 114 | cmn_err(CE_WARN, "Timeout waiting for door calls to complete"); |
| 115 | |
jm199354 | 911106d | 2007-11-08 16:09:20 -0800 | [diff] [blame] | 116 | if (vscan_door_handle) { |
| 117 | door_ki_rele(vscan_door_handle); |
| 118 | vscan_door_handle = NULL; |
| 119 | } |
| 120 | |
| 121 | mutex_exit(&vscan_door_mutex); |
| 122 | } |
| 123 | |
| 124 | |
| 125 | /* |
| 126 | * vscan_door_scan_file |
jm199354 | bfc848c | 2008-04-10 17:45:54 -0700 | [diff] [blame] | 127 | * |
| 128 | * Returns: result returned in door response or VS_STATUS_ERROR |
jm199354 | 911106d | 2007-11-08 16:09:20 -0800 | [diff] [blame] | 129 | */ |
| 130 | int |
| 131 | vscan_door_scan_file(vs_scan_req_t *scan_req) |
| 132 | { |
jm199354 | bfc848c | 2008-04-10 17:45:54 -0700 | [diff] [blame] | 133 | int err; |
Alan Wright | 1843d05 | 2008-10-25 14:44:56 -0700 | [diff] [blame] | 134 | int i; |
jm199354 | 911106d | 2007-11-08 16:09:20 -0800 | [diff] [blame] | 135 | door_arg_t arg; |
jm199354 | bfc848c | 2008-04-10 17:45:54 -0700 | [diff] [blame] | 136 | uint32_t result = 0; |
jm199354 | 911106d | 2007-11-08 16:09:20 -0800 | [diff] [blame] | 137 | |
jm199354 | bfc848c | 2008-04-10 17:45:54 -0700 | [diff] [blame] | 138 | if (!vscan_door_handle) |
| 139 | return (VS_STATUS_ERROR); |
jm199354 | 911106d | 2007-11-08 16:09:20 -0800 | [diff] [blame] | 140 | |
| 141 | mutex_enter(&vscan_door_mutex); |
| 142 | vscan_door_call_count++; |
| 143 | mutex_exit(&vscan_door_mutex); |
| 144 | |
| 145 | arg.data_ptr = (char *)scan_req; |
| 146 | arg.data_size = sizeof (vs_scan_req_t); |
| 147 | arg.desc_ptr = NULL; |
| 148 | arg.desc_num = 0; |
jm199354 | bfc848c | 2008-04-10 17:45:54 -0700 | [diff] [blame] | 149 | arg.rbuf = (char *)&result; |
| 150 | arg.rsize = sizeof (uint32_t); |
jm199354 | 911106d | 2007-11-08 16:09:20 -0800 | [diff] [blame] | 151 | |
Alan Wright | 1843d05 | 2008-10-25 14:44:56 -0700 | [diff] [blame] | 152 | for (i = 0; i < VS_DOOR_RETRIES; ++i) { |
| 153 | if ((err = door_ki_upcall_limited(vscan_door_handle, &arg, |
| 154 | NULL, SIZE_MAX, 0)) == 0) |
| 155 | break; |
| 156 | |
| 157 | if (err != EAGAIN && err != EINTR) |
| 158 | break; |
| 159 | } |
| 160 | |
| 161 | if (err != 0) { |
jm199354 | 911106d | 2007-11-08 16:09:20 -0800 | [diff] [blame] | 162 | cmn_err(CE_WARN, "Internal communication error (%d)" |
| 163 | "- failed to send scan request to vscand", err); |
jm199354 | bfc848c | 2008-04-10 17:45:54 -0700 | [diff] [blame] | 164 | result = VS_STATUS_ERROR; |
jm199354 | 911106d | 2007-11-08 16:09:20 -0800 | [diff] [blame] | 165 | } |
| 166 | |
| 167 | mutex_enter(&vscan_door_mutex); |
| 168 | vscan_door_call_count--; |
| 169 | cv_signal(&vscan_door_cv); |
| 170 | mutex_exit(&vscan_door_mutex); |
| 171 | |
jm199354 | bfc848c | 2008-04-10 17:45:54 -0700 | [diff] [blame] | 172 | return (result); |
jm199354 | 911106d | 2007-11-08 16:09:20 -0800 | [diff] [blame] | 173 | } |