aiclib.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. /*
  2. * Implementation of Utility functions for all SCSI device types.
  3. *
  4. * Copyright (c) 1997, 1998, 1999 Justin T. Gibbs.
  5. * Copyright (c) 1997, 1998 Kenneth D. Merry.
  6. * All rights reserved.
  7. *
  8. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted provided that the following conditions
  10. * are met:
  11. * 1. Redistributions of source code must retain the above copyright
  12. * notice, this list of conditions, and the following disclaimer,
  13. * without modification, immediately at the beginning of the file.
  14. * 2. The name of the author may not be used to endorse or promote products
  15. * derived from this software without specific prior written permission.
  16. *
  17. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  18. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  19. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  20. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
  21. * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  22. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  23. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  24. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  25. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  26. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  27. * SUCH DAMAGE.
  28. *
  29. * $FreeBSD: src/sys/cam/scsi/scsi_all.c,v 1.38 2002/09/23 04:56:35 mjacob Exp $
  30. * $Id$
  31. */
  32. #include "aiclib.h"
  33. /*
  34. * Table of syncrates that don't follow the "divisible by 4"
  35. * rule. This table will be expanded in future SCSI specs.
  36. */
  37. static struct {
  38. u_int period_factor;
  39. u_int period; /* in 100ths of ns */
  40. } scsi_syncrates[] = {
  41. { 0x08, 625 }, /* FAST-160 */
  42. { 0x09, 1250 }, /* FAST-80 */
  43. { 0x0a, 2500 }, /* FAST-40 40MHz */
  44. { 0x0b, 3030 }, /* FAST-40 33MHz */
  45. { 0x0c, 5000 } /* FAST-20 */
  46. };
  47. /*
  48. * Return the frequency in kHz corresponding to the given
  49. * sync period factor.
  50. */
  51. u_int
  52. aic_calc_syncsrate(u_int period_factor)
  53. {
  54. int i;
  55. int num_syncrates;
  56. num_syncrates = sizeof(scsi_syncrates) / sizeof(scsi_syncrates[0]);
  57. /* See if the period is in the "exception" table */
  58. for (i = 0; i < num_syncrates; i++) {
  59. if (period_factor == scsi_syncrates[i].period_factor) {
  60. /* Period in kHz */
  61. return (100000000 / scsi_syncrates[i].period);
  62. }
  63. }
  64. /*
  65. * Wasn't in the table, so use the standard
  66. * 4 times conversion.
  67. */
  68. return (10000000 / (period_factor * 4 * 10));
  69. }
  70. char *
  71. aic_parse_brace_option(char *opt_name, char *opt_arg, char *end, int depth,
  72. aic_option_callback_t *callback, u_long callback_arg)
  73. {
  74. char *tok_end;
  75. char *tok_end2;
  76. int i;
  77. int instance;
  78. int targ;
  79. int done;
  80. char tok_list[] = {'.', ',', '{', '}', '\0'};
  81. /* All options use a ':' name/arg separator */
  82. if (*opt_arg != ':')
  83. return (opt_arg);
  84. opt_arg++;
  85. instance = -1;
  86. targ = -1;
  87. done = FALSE;
  88. /*
  89. * Restore separator that may be in
  90. * the middle of our option argument.
  91. */
  92. tok_end = strchr(opt_arg, '\0');
  93. if (tok_end < end)
  94. *tok_end = ',';
  95. while (!done) {
  96. switch (*opt_arg) {
  97. case '{':
  98. if (instance == -1) {
  99. instance = 0;
  100. } else {
  101. if (depth > 1) {
  102. if (targ == -1)
  103. targ = 0;
  104. } else {
  105. printf("Malformed Option %s\n",
  106. opt_name);
  107. done = TRUE;
  108. }
  109. }
  110. opt_arg++;
  111. break;
  112. case '}':
  113. if (targ != -1)
  114. targ = -1;
  115. else if (instance != -1)
  116. instance = -1;
  117. opt_arg++;
  118. break;
  119. case ',':
  120. case '.':
  121. if (instance == -1)
  122. done = TRUE;
  123. else if (targ >= 0)
  124. targ++;
  125. else if (instance >= 0)
  126. instance++;
  127. opt_arg++;
  128. break;
  129. case '\0':
  130. done = TRUE;
  131. break;
  132. default:
  133. tok_end = end;
  134. for (i = 0; tok_list[i]; i++) {
  135. tok_end2 = strchr(opt_arg, tok_list[i]);
  136. if ((tok_end2) && (tok_end2 < tok_end))
  137. tok_end = tok_end2;
  138. }
  139. callback(callback_arg, instance, targ,
  140. simple_strtol(opt_arg, NULL, 0));
  141. opt_arg = tok_end;
  142. break;
  143. }
  144. }
  145. return (opt_arg);
  146. }