diff options
Diffstat (limited to 'drivers/scsi/aic7xxx/aic79xx_proc.c')
-rw-r--r-- | drivers/scsi/aic7xxx/aic79xx_proc.c | 88 |
1 files changed, 57 insertions, 31 deletions
diff --git a/drivers/scsi/aic7xxx/aic79xx_proc.c b/drivers/scsi/aic7xxx/aic79xx_proc.c index e01cd6175e34..39a27840fce6 100644 --- a/drivers/scsi/aic7xxx/aic79xx_proc.c +++ b/drivers/scsi/aic7xxx/aic79xx_proc.c | |||
@@ -49,10 +49,53 @@ static void ahd_dump_target_state(struct ahd_softc *ahd, | |||
49 | u_int our_id, char channel, | 49 | u_int our_id, char channel, |
50 | u_int target_id, u_int target_offset); | 50 | u_int target_id, u_int target_offset); |
51 | static void ahd_dump_device_state(struct info_str *info, | 51 | static void ahd_dump_device_state(struct info_str *info, |
52 | struct ahd_linux_device *dev); | 52 | struct scsi_device *sdev); |
53 | static int ahd_proc_write_seeprom(struct ahd_softc *ahd, | 53 | static int ahd_proc_write_seeprom(struct ahd_softc *ahd, |
54 | char *buffer, int length); | 54 | char *buffer, int length); |
55 | 55 | ||
56 | /* | ||
57 | * Table of syncrates that don't follow the "divisible by 4" | ||
58 | * rule. This table will be expanded in future SCSI specs. | ||
59 | */ | ||
60 | static struct { | ||
61 | u_int period_factor; | ||
62 | u_int period; /* in 100ths of ns */ | ||
63 | } scsi_syncrates[] = { | ||
64 | { 0x08, 625 }, /* FAST-160 */ | ||
65 | { 0x09, 1250 }, /* FAST-80 */ | ||
66 | { 0x0a, 2500 }, /* FAST-40 40MHz */ | ||
67 | { 0x0b, 3030 }, /* FAST-40 33MHz */ | ||
68 | { 0x0c, 5000 } /* FAST-20 */ | ||
69 | }; | ||
70 | |||
71 | /* | ||
72 | * Return the frequency in kHz corresponding to the given | ||
73 | * sync period factor. | ||
74 | */ | ||
75 | static u_int | ||
76 | ahd_calc_syncsrate(u_int period_factor) | ||
77 | { | ||
78 | int i; | ||
79 | int num_syncrates; | ||
80 | |||
81 | num_syncrates = sizeof(scsi_syncrates) / sizeof(scsi_syncrates[0]); | ||
82 | /* See if the period is in the "exception" table */ | ||
83 | for (i = 0; i < num_syncrates; i++) { | ||
84 | |||
85 | if (period_factor == scsi_syncrates[i].period_factor) { | ||
86 | /* Period in kHz */ | ||
87 | return (100000000 / scsi_syncrates[i].period); | ||
88 | } | ||
89 | } | ||
90 | |||
91 | /* | ||
92 | * Wasn't in the table, so use the standard | ||
93 | * 4 times conversion. | ||
94 | */ | ||
95 | return (10000000 / (period_factor * 4 * 10)); | ||
96 | } | ||
97 | |||
98 | |||
56 | static void | 99 | static void |
57 | copy_mem_info(struct info_str *info, char *data, int len) | 100 | copy_mem_info(struct info_str *info, char *data, int len) |
58 | { | 101 | { |
@@ -109,7 +152,7 @@ ahd_format_transinfo(struct info_str *info, struct ahd_transinfo *tinfo) | |||
109 | speed = 3300; | 152 | speed = 3300; |
110 | freq = 0; | 153 | freq = 0; |
111 | if (tinfo->offset != 0) { | 154 | if (tinfo->offset != 0) { |
112 | freq = aic_calc_syncsrate(tinfo->period); | 155 | freq = ahd_calc_syncsrate(tinfo->period); |
113 | speed = freq; | 156 | speed = freq; |
114 | } | 157 | } |
115 | speed *= (0x01 << tinfo->width); | 158 | speed *= (0x01 << tinfo->width); |
@@ -167,6 +210,7 @@ ahd_dump_target_state(struct ahd_softc *ahd, struct info_str *info, | |||
167 | u_int target_offset) | 210 | u_int target_offset) |
168 | { | 211 | { |
169 | struct ahd_linux_target *targ; | 212 | struct ahd_linux_target *targ; |
213 | struct scsi_target *starget; | ||
170 | struct ahd_initiator_tinfo *tinfo; | 214 | struct ahd_initiator_tinfo *tinfo; |
171 | struct ahd_tmode_tstate *tstate; | 215 | struct ahd_tmode_tstate *tstate; |
172 | int lun; | 216 | int lun; |
@@ -176,20 +220,20 @@ ahd_dump_target_state(struct ahd_softc *ahd, struct info_str *info, | |||
176 | copy_info(info, "Target %d Negotiation Settings\n", target_id); | 220 | copy_info(info, "Target %d Negotiation Settings\n", target_id); |
177 | copy_info(info, "\tUser: "); | 221 | copy_info(info, "\tUser: "); |
178 | ahd_format_transinfo(info, &tinfo->user); | 222 | ahd_format_transinfo(info, &tinfo->user); |
179 | targ = ahd->platform_data->targets[target_offset]; | 223 | starget = ahd->platform_data->starget[target_offset]; |
180 | if (targ == NULL) | 224 | if (starget == NULL) |
181 | return; | 225 | return; |
226 | targ = scsi_transport_target_data(starget); | ||
182 | 227 | ||
183 | copy_info(info, "\tGoal: "); | 228 | copy_info(info, "\tGoal: "); |
184 | ahd_format_transinfo(info, &tinfo->goal); | 229 | ahd_format_transinfo(info, &tinfo->goal); |
185 | copy_info(info, "\tCurr: "); | 230 | copy_info(info, "\tCurr: "); |
186 | ahd_format_transinfo(info, &tinfo->curr); | 231 | ahd_format_transinfo(info, &tinfo->curr); |
187 | copy_info(info, "\tTransmission Errors %ld\n", targ->errors_detected); | ||
188 | 232 | ||
189 | for (lun = 0; lun < AHD_NUM_LUNS; lun++) { | 233 | for (lun = 0; lun < AHD_NUM_LUNS; lun++) { |
190 | struct ahd_linux_device *dev; | 234 | struct scsi_device *dev; |
191 | 235 | ||
192 | dev = targ->devices[lun]; | 236 | dev = targ->sdev[lun]; |
193 | 237 | ||
194 | if (dev == NULL) | 238 | if (dev == NULL) |
195 | continue; | 239 | continue; |
@@ -199,10 +243,13 @@ ahd_dump_target_state(struct ahd_softc *ahd, struct info_str *info, | |||
199 | } | 243 | } |
200 | 244 | ||
201 | static void | 245 | static void |
202 | ahd_dump_device_state(struct info_str *info, struct ahd_linux_device *dev) | 246 | ahd_dump_device_state(struct info_str *info, struct scsi_device *sdev) |
203 | { | 247 | { |
248 | struct ahd_linux_device *dev = scsi_transport_device_data(sdev); | ||
249 | |||
204 | copy_info(info, "\tChannel %c Target %d Lun %d Settings\n", | 250 | copy_info(info, "\tChannel %c Target %d Lun %d Settings\n", |
205 | dev->target->channel + 'A', dev->target->target, dev->lun); | 251 | sdev->sdev_target->channel + 'A', |
252 | sdev->sdev_target->id, sdev->lun); | ||
206 | 253 | ||
207 | copy_info(info, "\t\tCommands Queued %ld\n", dev->commands_issued); | 254 | copy_info(info, "\t\tCommands Queued %ld\n", dev->commands_issued); |
208 | copy_info(info, "\t\tCommands Active %d\n", dev->active); | 255 | copy_info(info, "\t\tCommands Active %d\n", dev->active); |
@@ -278,36 +325,16 @@ done: | |||
278 | * Return information to handle /proc support for the driver. | 325 | * Return information to handle /proc support for the driver. |
279 | */ | 326 | */ |
280 | int | 327 | int |
281 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) | ||
282 | ahd_linux_proc_info(char *buffer, char **start, off_t offset, | ||
283 | int length, int hostno, int inout) | ||
284 | #else | ||
285 | ahd_linux_proc_info(struct Scsi_Host *shost, char *buffer, char **start, | 328 | ahd_linux_proc_info(struct Scsi_Host *shost, char *buffer, char **start, |
286 | off_t offset, int length, int inout) | 329 | off_t offset, int length, int inout) |
287 | #endif | ||
288 | { | 330 | { |
289 | struct ahd_softc *ahd; | 331 | struct ahd_softc *ahd = *(struct ahd_softc **)shost->hostdata; |
290 | struct info_str info; | 332 | struct info_str info; |
291 | char ahd_info[256]; | 333 | char ahd_info[256]; |
292 | u_long l; | ||
293 | u_int max_targ; | 334 | u_int max_targ; |
294 | u_int i; | 335 | u_int i; |
295 | int retval; | 336 | int retval; |
296 | 337 | ||
297 | retval = -EINVAL; | ||
298 | ahd_list_lock(&l); | ||
299 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) | ||
300 | TAILQ_FOREACH(ahd, &ahd_tailq, links) { | ||
301 | if (ahd->platform_data->host->host_no == hostno) | ||
302 | break; | ||
303 | } | ||
304 | #else | ||
305 | ahd = ahd_find_softc(*(struct ahd_softc **)shost->hostdata); | ||
306 | #endif | ||
307 | |||
308 | if (ahd == NULL) | ||
309 | goto done; | ||
310 | |||
311 | /* Has data been written to the file? */ | 338 | /* Has data been written to the file? */ |
312 | if (inout == TRUE) { | 339 | if (inout == TRUE) { |
313 | retval = ahd_proc_write_seeprom(ahd, buffer, length); | 340 | retval = ahd_proc_write_seeprom(ahd, buffer, length); |
@@ -357,6 +384,5 @@ ahd_linux_proc_info(struct Scsi_Host *shost, char *buffer, char **start, | |||
357 | } | 384 | } |
358 | retval = info.pos > info.offset ? info.pos - info.offset : 0; | 385 | retval = info.pos > info.offset ? info.pos - info.offset : 0; |
359 | done: | 386 | done: |
360 | ahd_list_unlock(&l); | ||
361 | return (retval); | 387 | return (retval); |
362 | } | 388 | } |