6 #include <linux/slab.h>
13 TRACE2((
"gdth_proc_info() length %d offs %d inout %d\n",
14 length,(
int)offset,inout));
17 return(gdth_set_info(buffer,length,host,ha));
19 return(gdth_get_info(buffer,start,offset,length,host,ha));
30 if (
strncmp(buffer,
"gdth",4) == 0) {
33 ret_val = gdth_set_asc_info(host, buffer, length, ha);
40 static int gdth_set_asc_info(
struct Scsi_Host *host,
char *buffer,
43 int orig_length, drive, wb_mode;
51 memset(&gdtcmd, 0,
sizeof(gdth_cmd_str));
54 orig_length = length + 5;
59 if (length >= 5 &&
strncmp(buffer,
"flush",5)==0) {
62 if (length && *buffer>=
'0' && *buffer<=
'9') {
63 drive = (
int)(*buffer-
'0');
65 if (length && *buffer>=
'0' && *buffer<=
'9') {
66 drive = drive*10 + (
int)(*buffer-
'0');
69 printk(
"GDT: Flushing host drive %d .. ",drive);
71 printk(
"GDT: Flushing all host drives .. ");
74 if (ha->
hdr[i].present) {
75 if (drive != -1 && i != drive)
81 gdtcmd.u.cache64.DeviceNo =
i;
82 gdtcmd.u.cache64.BlockNo = 1;
84 gdtcmd.u.cache.DeviceNo =
i;
85 gdtcmd.u.cache.BlockNo = 1;
92 printk(
"\nNo host drive found !\n");
98 if (length >= 7 &&
strncmp(buffer,
"wbp_off",7)==0) {
101 printk(
"GDT: Disabling write back permanently .. ");
103 }
else if (length >= 6 &&
strncmp(buffer,
"wbp_on",6)==0) {
106 printk(
"GDT: Enabling write back permanently .. ");
108 }
else if (length >= 6 &&
strncmp(buffer,
"wb_off",6)==0) {
111 printk(
"GDT: Disabling write back commands .. ");
113 gdth_write_through =
TRUE;
116 printk(
"Not supported !\n");
119 }
else if (length >= 5 &&
strncmp(buffer,
"wb_on",5)==0) {
122 printk(
"GDT: Enabling write back commands .. ");
123 gdth_write_through =
FALSE;
129 if (!gdth_ioctl_alloc(ha,
sizeof(gdth_cpar_str),
TRUE, &paddr))
131 pcpar = (gdth_cpar_str *)ha->
pscratch;
132 memcpy( pcpar, &ha->
cpar,
sizeof(gdth_cpar_str) );
135 gdtcmd.u.ioctl.p_param =
paddr;
136 gdtcmd.u.ioctl.param_size =
sizeof(gdth_cpar_str);
139 pcpar->write_back = wb_mode==1 ? 0:1;
148 printk(
"GDT: Unknown command: %s Length: %d\n",buffer,length);
159 int no_mdrv = 0, drv_no, is_mirr;
164 gdth_cmd_str *gdtcmd;
170 gdth_dskstat_str *pds;
171 gdth_diskinfo_str *
pdi;
172 gdth_arrayinf_str *pai;
173 gdth_defcnt_str *pdef;
174 gdth_cdrinfo_str *pcdi;
180 if (!gdtcmd || !estr)
184 memset(gdtcmd, 0,
sizeof(gdth_cmd_str));
192 size =
sprintf(buffer+len,
"Driver Parameters:\n");
194 if (reserve_list[0] == 0xff)
197 hlen =
sprintf(hrec,
"%d", reserve_list[0]);
199 if (reserve_list[i] == 0xff)
201 hlen +=
snprintf(hrec + hlen , 161 - hlen,
",%d", reserve_list[i]);
205 " reserve_mode: \t%d \treserve_list: \t%s\n",
207 len +=
size;
pos = begin + len;
209 " max_ids: \t%-3d \thdr_channel: \t%d\n",
210 max_ids, hdr_channel);
211 len +=
size;
pos = begin + len;
214 size =
sprintf(buffer+len,
"\nDisk Array Controller Information:\n");
215 len +=
size;
pos = begin + len;
218 " Number: \t%d \tName: \t%s\n",
220 len +=
size;
pos = begin + len;
223 sprintf(hrec,
"%d.%02d.%02d-%c%03X",
224 (
u8)(ha->
binfo.upd_fw_ver>>24),
225 (
u8)(ha->
binfo.upd_fw_ver>>16),
227 ha->
bfeat.raid ?
'R':
'N',
228 ha->
binfo.upd_revision);
234 " Driver Ver.: \t%-10s\tFirmware Ver.: \t%s\n",
236 len +=
size;
pos = begin + len;
241 " Serial No.: \t0x%8X\tCache RAM size:\t%d KB\n",
243 len +=
size;
pos = begin + len;
246 #ifdef GDTH_DMA_STATISTICS
248 size =
sprintf(buffer+len,
"\nController Statistics:\n");
249 len +=
size;
pos = begin + len;
251 " 32-bit DMA buffer:\t%lu\t64-bit DMA buffer:\t%lu\n",
252 ha->dma32_cnt, ha->dma64_cnt);
253 len +=
size;
pos = begin + len;
260 if (
pos > offset + length)
265 size =
sprintf(buffer+len,
"\nPhysical Devices:");
266 len +=
size;
pos = begin + len;
274 TRACE2((
"pdr_statistics() chn %d\n",i));
282 pds->bid = ha->
raw[
i].local_no;
284 pds->entries = ha->
raw[
i].pdev_cnt;
286 sizeof(pds->list[0]);
287 if (pds->entries > cnt)
294 for (j = 0; j < ha->
raw[
i].pdev_cnt; ++
j) {
296 TRACE2((
"scsi_drv_info() chn %d dev %d\n",
297 i, ha->
raw[i].id_list[j]));
298 pdi = (gdth_diskinfo_str *)buf;
301 gdtcmd->u.ioctl.p_param =
paddr;
302 gdtcmd->u.ioctl.param_size =
sizeof(gdth_diskinfo_str);
304 gdtcmd->u.ioctl.channel =
305 ha->
raw[
i].address | ha->
raw[
i].id_list[
j];
309 strncpy(hrec+8,pdi->product,16);
310 strncpy(hrec+24,pdi->revision,4);
313 "\n Chn/ID/LUN: \t%c/%02d/%d \tName: \t%s\n",
314 'A'+i,pdi->target_id,pdi->lun,hrec);
315 len +=
size;
pos = begin + len;
317 pdi->no_ldrive &= 0xffff;
318 if (pdi->no_ldrive == 0xffff)
321 sprintf(hrec,
"%d",pdi->no_ldrive);
323 " Capacity [MB]:\t%-6d \tTo Log. Drive: \t%s\n",
324 pdi->blkcnt/(1024*1024/pdi->blksize),
326 len +=
size;
pos = begin + len;
331 if (pdi->devtype == 0) {
333 for (k = 0; k < pds->count; ++
k) {
334 if (pds->list[k].tid == pdi->target_id &&
335 pds->list[k].lun == pdi->lun) {
337 " Retries: \t%-6d \tReassigns: \t%d\n",
338 pds->list[k].retries,
339 pds->list[k].reassigns);
340 len +=
size;
pos = begin + len;
345 TRACE2((
"scsi_drv_defcnt() chn %d dev %d\n",
346 i, ha->
raw[i].id_list[j]));
347 pdef = (gdth_defcnt_str *)buf;
350 gdtcmd->u.ioctl.p_param =
paddr;
351 gdtcmd->u.ioctl.param_size =
sizeof(gdth_defcnt_str);
353 gdtcmd->u.ioctl.channel =
354 ha->
raw[
i].address | ha->
raw[
i].id_list[
j];
355 pdef->sddc_type = 0x08;
359 " Grown Defects:\t%d\n",
361 len +=
size;
pos = begin + len;
368 if (
pos > offset + length) {
377 size =
sprintf(buffer+len,
"\n --\n");
378 len +=
size;
pos = begin + len;
382 size =
sprintf(buffer+len,
"\nLogical Drives:");
383 len +=
size;
pos = begin + len;
390 if (!ha->
hdr[i].is_logdrv)
397 TRACE2((
"cache_drv_info() drive no %d\n",drv_no));
398 pcdi = (gdth_cdrinfo_str *)buf;
401 gdtcmd->u.ioctl.p_param =
paddr;
402 gdtcmd->u.ioctl.param_size =
sizeof(gdth_cdrinfo_str);
404 gdtcmd->u.ioctl.channel = drv_no;
407 pcdi->ld_dtype >>= 16;
409 if (pcdi->ld_dtype > 2) {
411 }
else if (pcdi->ld_error & 1) {
413 }
else if (pcdi->ld_error & 2) {
422 "\n Number: \t%-2d \tStatus: \t%s\n",
424 len +=
size;
pos = begin + len;
426 no_mdrv = pcdi->cd_ldcnt;
427 if (no_mdrv > 1 || pcdi->ld_slave != -1) {
430 }
else if (pcdi->ld_dtype == 0) {
432 }
else if (pcdi->ld_dtype == 1) {
434 }
else if (pcdi->ld_dtype == 2) {
440 " Capacity [MB]:\t%-6d \tType: \t%s\n",
441 pcdi->ld_blkcnt/(1024*1024/pcdi->ld_blksize),
443 len +=
size;
pos = begin + len;
446 " Slave Number: \t%-2d \tStatus: \t%s\n",
447 drv_no & 0x7fff, hrec);
448 len +=
size;
pos = begin + len;
450 drv_no = pcdi->ld_slave;
455 if (
pos > offset + length) {
459 }
while (drv_no != -1);
463 " Missing Drv.: \t%-2d \tInvalid Drv.: \t%d\n",
465 len +=
size;
pos = begin + len;
468 if (!ha->
hdr[i].is_arraydrv)
473 " To Array Drv.:\t%s\n", hrec);
474 len +=
size;
pos = begin + len;
479 if (
pos > offset + length) {
487 size =
sprintf(buffer+len,
"\n --\n");
488 len +=
size;
pos = begin + len;
492 size =
sprintf(buffer+len,
"\nArray Drives:");
493 len +=
size;
pos = begin + len;
500 if (!(ha->
hdr[i].is_arraydrv && ha->
hdr[i].is_master))
503 TRACE2((
"array_info() drive no %d\n",i));
504 pai = (gdth_arrayinf_str *)buf;
507 gdtcmd->u.ioctl.p_param =
paddr;
508 gdtcmd->u.ioctl.param_size =
sizeof(gdth_arrayinf_str);
510 gdtcmd->u.ioctl.channel =
i;
512 if (pai->ai_state == 0)
514 else if (pai->ai_state == 2)
516 else if (pai->ai_state == 4)
518 else if (pai->ai_state == 6)
520 else if (pai->ai_state == 8 || pai->ai_state == 10)
524 if (pai->ai_ext_state & 0x10)
526 else if (pai->ai_ext_state & 0x1)
529 "\n Number: \t%-2d \tStatus: \t%s\n",
531 len +=
size;
pos = begin + len;
534 if (pai->ai_type == 0)
536 else if (pai->ai_type == 4)
538 else if (pai->ai_type == 5)
543 " Capacity [MB]:\t%-6d \tType: \t%s\n",
544 pai->ai_size/(1024*1024/pai->ai_secsize),
546 len +=
size;
pos = begin + len;
551 if (
pos > offset + length) {
560 size =
sprintf(buffer+len,
"\n --\n");
561 len +=
size;
pos = begin + len;
565 size =
sprintf(buffer+len,
"\nHost Drives:");
566 len +=
size;
pos = begin + len;
569 buf = gdth_ioctl_alloc(ha,
sizeof(gdth_hget_str),
FALSE, &paddr);
573 if (!ha->
hdr[i].is_logdrv ||
574 (ha->
hdr[i].is_arraydrv && !ha->
hdr[i].is_master))
577 TRACE2((
"host_get() drv_no %d\n",i));
578 phg = (gdth_hget_str *)buf;
581 gdtcmd->u.ioctl.p_param =
paddr;
582 gdtcmd->u.ioctl.param_size =
sizeof(gdth_hget_str);
584 gdtcmd->u.ioctl.channel =
i;
588 ha->
hdr[
i].ldr_no =
i;
589 ha->
hdr[
i].rw_attribs = 0;
590 ha->
hdr[
i].start_sec = 0;
592 for (j = 0; j < phg->entries; ++
j) {
593 k = phg->entry[
j].host_drive;
594 if (k >= MAX_LDRIVES)
596 ha->
hdr[
k].ldr_no = phg->entry[
j].log_drive;
597 ha->
hdr[
k].rw_attribs = phg->entry[
j].rw_attribs;
598 ha->
hdr[
k].start_sec = phg->entry[
j].start_sec;
602 gdth_ioctl_free(ha,
sizeof(gdth_hget_str), buf, paddr);
605 if (!(ha->
hdr[i].present))
609 "\n Number: \t%-2d \tArr/Log. Drive:\t%d\n",
610 i, ha->
hdr[i].ldr_no);
611 len +=
size;
pos = begin + len;
615 " Capacity [MB]:\t%-6d \tStart Sector: \t%d\n",
616 (
u32)(ha->
hdr[i].size/2048), ha->
hdr[i].start_sec);
617 len +=
size;
pos = begin + len;
622 if (
pos > offset + length)
627 size =
sprintf(buffer+len,
"\n --\n");
628 len +=
size;
pos = begin + len;
633 size =
sprintf(buffer+len,
"\nController Events:\n");
634 len +=
size;
pos = begin + len;
637 id = gdth_read_event(ha,
id, estr);
638 if (estr->event_source == 0)
640 if (estr->event_data.eu.driver.ionode == ha->
hanum &&
642 gdth_log_event(&estr->event_data, hrec);
644 sec = (
int)(tv.tv_sec - estr->first_stamp);
645 if (sec < 0) sec = 0;
646 size =
sprintf(buffer+len,
" date- %02d:%02d:%02d\t%s\n",
647 sec/3600, sec%3600/60, sec%60, hrec);
648 len +=
size;
pos = begin + len;
653 if (
pos > offset + length)
661 *start = buffer +(offset-begin);
662 len -= (offset-begin);
665 TRACE2((
"get_info() len %d pos %d begin %d offset %d length %d size %d\n",
666 len,(
int)
pos,(
int)begin,(
int)offset,length,size));
690 }
else if (scratch) {
699 spin_unlock_irqrestore(&ha->
smp_lock, flags);
703 static void gdth_ioctl_free(
gdth_ha_str *ha,
int size,
char *buf,
u64 paddr)
710 spin_unlock_irqrestore(&ha->
smp_lock, flags);
716 #ifdef GDTH_IOCTL_PROC
726 if (((gdth_iord_str *)ha->
pscratch)->size == (
u32)size)
729 spin_unlock_irqrestore(&ha->
smp_lock, flags);
739 struct gdth_cmndinfo *cmndinfo;
746 cmndinfo = gdth_cmnd_priv(scp);
752 cmndinfo->wait_for_completion = 0;
753 spin_unlock_irqrestore(&ha->
smp_lock, flags);
754 while (!cmndinfo->wait_for_completion)
759 spin_unlock_irqrestore(&ha->
smp_lock, flags);