* Return a new driver id. Registers a driver with the system so that * it can be probed by subsequent sessions. */
| 987 | * it can be probed by subsequent sessions. |
| 988 | */ |
| 989 | int32_t |
| 990 | crypto_get_driverid(device_t dev, size_t sessionsize, int flags) |
| 991 | { |
| 992 | struct cryptocap *cap, **newdrv; |
| 993 | int i; |
| 994 | |
| 995 | if ((flags & (CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE)) == 0) { |
| 996 | device_printf(dev, |
| 997 | "no flags specified when registering driver\n"); |
| 998 | return -1; |
| 999 | } |
| 1000 | |
| 1001 | cap = malloc(sizeof(*cap), M_CRYPTO_DATA, M_WAITOK | M_ZERO); |
| 1002 | cap->cc_dev = dev; |
| 1003 | cap->cc_session_size = sessionsize; |
| 1004 | cap->cc_flags = flags; |
| 1005 | refcount_init(&cap->cc_refs, 1); |
| 1006 | |
| 1007 | CRYPTO_DRIVER_LOCK(); |
| 1008 | for (;;) { |
| 1009 | for (i = 0; i < crypto_drivers_size; i++) { |
| 1010 | if (crypto_drivers[i] == NULL) |
| 1011 | break; |
| 1012 | } |
| 1013 | |
| 1014 | if (i < crypto_drivers_size) |
| 1015 | break; |
| 1016 | |
| 1017 | /* Out of entries, allocate some more. */ |
| 1018 | |
| 1019 | if (2 * crypto_drivers_size <= crypto_drivers_size) { |
| 1020 | CRYPTO_DRIVER_UNLOCK(); |
| 1021 | printf("crypto: driver count wraparound!\n"); |
| 1022 | cap_rele(cap); |
| 1023 | return (-1); |
| 1024 | } |
| 1025 | CRYPTO_DRIVER_UNLOCK(); |
| 1026 | |
| 1027 | newdrv = malloc(2 * crypto_drivers_size * |
| 1028 | sizeof(*crypto_drivers), M_CRYPTO_DATA, M_WAITOK | M_ZERO); |
| 1029 | |
| 1030 | CRYPTO_DRIVER_LOCK(); |
| 1031 | memcpy(newdrv, crypto_drivers, |
| 1032 | crypto_drivers_size * sizeof(*crypto_drivers)); |
| 1033 | |
| 1034 | crypto_drivers_size *= 2; |
| 1035 | |
| 1036 | free(crypto_drivers, M_CRYPTO_DATA); |
| 1037 | crypto_drivers = newdrv; |
| 1038 | } |
| 1039 | |
| 1040 | cap->cc_hid = i; |
| 1041 | crypto_drivers[i] = cap; |
| 1042 | CRYPTO_DRIVER_UNLOCK(); |
| 1043 | |
| 1044 | if (bootverbose) |
| 1045 | printf("crypto: assign %s driver id %u, flags 0x%x\n", |
| 1046 | device_get_nameunit(dev), i, flags); |
no test coverage detected