11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* gdth_proc.c 2cbd5f69b98bb5d7a0d207230bcf8fa51fca3f3cfLeubner, Achim * $Id: gdth_proc.c,v 1.43 2006/01/11 16:15:00 achim Exp $ 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/completion.h> 65a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h> 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint gdth_proc_info(struct Scsi_Host *host, char *buffer,char **start,off_t offset,int length, 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int inout) 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1145f1a41b2b2e02e91d29bde66a8da4d050959f65Boaz Harrosh gdth_ha_str *ha = shost_priv(host); 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds TRACE2(("gdth_proc_info() length %d offs %d inout %d\n", 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds length,(int)offset,inout)); 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (inout) 1745f1a41b2b2e02e91d29bde66a8da4d050959f65Boaz Harrosh return(gdth_set_info(buffer,length,host,ha)); 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 1945f1a41b2b2e02e91d29bde66a8da4d050959f65Boaz Harrosh return(gdth_get_info(buffer,start,offset,length,host,ha)); 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int gdth_set_info(char *buffer,int length,struct Scsi_Host *host, 2345f1a41b2b2e02e91d29bde66a8da4d050959f65Boaz Harrosh gdth_ha_str *ha) 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 25cbd5f69b98bb5d7a0d207230bcf8fa51fca3f3cfLeubner, Achim int ret_val = -EINVAL; 261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2745f1a41b2b2e02e91d29bde66a8da4d050959f65Boaz Harrosh TRACE2(("gdth_set_info() ha %d\n",ha->hanum,)); 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (length >= 4) { 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (strncmp(buffer,"gdth",4) == 0) { 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buffer += 5; 321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds length -= 5; 3345f1a41b2b2e02e91d29bde66a8da4d050959f65Boaz Harrosh ret_val = gdth_set_asc_info(host, buffer, length, ha); 341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 36cbd5f69b98bb5d7a0d207230bcf8fa51fca3f3cfLeubner, Achim 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret_val; 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 40cbd5f69b98bb5d7a0d207230bcf8fa51fca3f3cfLeubner, Achimstatic int gdth_set_asc_info(struct Scsi_Host *host, char *buffer, 4145f1a41b2b2e02e91d29bde66a8da4d050959f65Boaz Harrosh int length, gdth_ha_str *ha) 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 43cbd5f69b98bb5d7a0d207230bcf8fa51fca3f3cfLeubner, Achim int orig_length, drive, wb_mode; 44cbd5f69b98bb5d7a0d207230bcf8fa51fca3f3cfLeubner, Achim int i, found; 451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds gdth_cmd_str gdtcmd; 461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds gdth_cpar_str *pcpar; 471fe6dbf4d0afba52ad0249f398e6296a1433a004Dave Jones u64 paddr; 481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char cmnd[MAX_COMMAND_SIZE]; 501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memset(cmnd, 0xff, 12); 511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memset(&gdtcmd, 0, sizeof(gdth_cmd_str)); 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5345f1a41b2b2e02e91d29bde66a8da4d050959f65Boaz Harrosh TRACE2(("gdth_set_asc_info() ha %d\n",ha->hanum)); 541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds orig_length = length + 5; 551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds drive = -1; 561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds wb_mode = 0; 571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds found = FALSE; 581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (length >= 5 && strncmp(buffer,"flush",5)==0) { 601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buffer += 6; 611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds length -= 6; 621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (length && *buffer>='0' && *buffer<='9') { 631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds drive = (int)(*buffer-'0'); 641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ++buffer; --length; 651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (length && *buffer>='0' && *buffer<='9') { 661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds drive = drive*10 + (int)(*buffer-'0'); 671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ++buffer; --length; 681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("GDT: Flushing host drive %d .. ",drive); 701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("GDT: Flushing all host drives .. "); 721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < MAX_HDRIVES; ++i) { 741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ha->hdr[i].present) { 751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (drive != -1 && i != drive) 761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds continue; 771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds found = TRUE; 781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds gdtcmd.Service = CACHESERVICE; 791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds gdtcmd.OpCode = GDT_FLUSH; 801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ha->cache_feat & GDT_64BIT) { 811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds gdtcmd.u.cache64.DeviceNo = i; 821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds gdtcmd.u.cache64.BlockNo = 1; 831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds gdtcmd.u.cache.DeviceNo = i; 851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds gdtcmd.u.cache.BlockNo = 1; 861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 87cbd5f69b98bb5d7a0d207230bcf8fa51fca3f3cfLeubner, Achim 88cbd5f69b98bb5d7a0d207230bcf8fa51fca3f3cfLeubner, Achim gdth_execute(host, &gdtcmd, cmnd, 30, NULL); 891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!found) 921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("\nNo host drive found !\n"); 931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("Done.\n"); 951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return(orig_length); 961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (length >= 7 && strncmp(buffer,"wbp_off",7)==0) { 991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buffer += 8; 1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds length -= 8; 1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("GDT: Disabling write back permanently .. "); 1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds wb_mode = 1; 1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if (length >= 6 && strncmp(buffer,"wbp_on",6)==0) { 1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buffer += 7; 1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds length -= 7; 1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("GDT: Enabling write back permanently .. "); 1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds wb_mode = 2; 1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if (length >= 6 && strncmp(buffer,"wb_off",6)==0) { 1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buffer += 7; 1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds length -= 7; 1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("GDT: Disabling write back commands .. "); 1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ha->cache_feat & GDT_WR_THROUGH) { 1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds gdth_write_through = TRUE; 1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("Done.\n"); 1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("Not supported !\n"); 1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return(orig_length); 1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if (length >= 5 && strncmp(buffer,"wb_on",5)==0) { 1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buffer += 6; 1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds length -= 6; 1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("GDT: Enabling write back commands .. "); 1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds gdth_write_through = FALSE; 1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("Done.\n"); 1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return(orig_length); 1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (wb_mode) { 12945f1a41b2b2e02e91d29bde66a8da4d050959f65Boaz Harrosh if (!gdth_ioctl_alloc(ha, sizeof(gdth_cpar_str), TRUE, &paddr)) 1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return(-EBUSY); 1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pcpar = (gdth_cpar_str *)ha->pscratch; 1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy( pcpar, &ha->cpar, sizeof(gdth_cpar_str) ); 1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds gdtcmd.Service = CACHESERVICE; 1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds gdtcmd.OpCode = GDT_IOCTL; 1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds gdtcmd.u.ioctl.p_param = paddr; 1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds gdtcmd.u.ioctl.param_size = sizeof(gdth_cpar_str); 1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds gdtcmd.u.ioctl.subfunc = CACHE_CONFIG; 1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds gdtcmd.u.ioctl.channel = INVALID_CHANNEL; 1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pcpar->write_back = wb_mode==1 ? 0:1; 140cbd5f69b98bb5d7a0d207230bcf8fa51fca3f3cfLeubner, Achim 141cbd5f69b98bb5d7a0d207230bcf8fa51fca3f3cfLeubner, Achim gdth_execute(host, &gdtcmd, cmnd, 30, NULL); 142cbd5f69b98bb5d7a0d207230bcf8fa51fca3f3cfLeubner, Achim 14345f1a41b2b2e02e91d29bde66a8da4d050959f65Boaz Harrosh gdth_ioctl_free(ha, GDTH_SCRATCH, ha->pscratch, paddr); 1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("Done.\n"); 1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return(orig_length); 1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("GDT: Unknown command: %s Length: %d\n",buffer,length); 1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return(-EINVAL); 1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int gdth_get_info(char *buffer,char **start,off_t offset,int length, 15345f1a41b2b2e02e91d29bde66a8da4d050959f65Boaz Harrosh struct Scsi_Host *host, gdth_ha_str *ha) 1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int size = 0,len = 0; 156238ddbb98c327a7392ced5ae65216c55969749eaAlan Cox int hlen; 1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds off_t begin = 0,pos = 0; 1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int id, i, j, k, sec, flag; 1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int no_mdrv = 0, drv_no, is_mirr; 1601fe6dbf4d0afba52ad0249f398e6296a1433a004Dave Jones u32 cnt; 1611fe6dbf4d0afba52ad0249f398e6296a1433a004Dave Jones u64 paddr; 1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int rc = -ENOMEM; 1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds gdth_cmd_str *gdtcmd; 1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds gdth_evt_str *estr; 1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char hrec[161]; 1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct timeval tv; 1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char *buf; 1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds gdth_dskstat_str *pds; 1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds gdth_diskinfo_str *pdi; 1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds gdth_arrayinf_str *pai; 1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds gdth_defcnt_str *pdef; 1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds gdth_cdrinfo_str *pcdi; 1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds gdth_hget_str *phg; 1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char cmnd[MAX_COMMAND_SIZE]; 1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds gdtcmd = kmalloc(sizeof(*gdtcmd), GFP_KERNEL); 1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds estr = kmalloc(sizeof(*estr), GFP_KERNEL); 1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!gdtcmd || !estr) 181cbd5f69b98bb5d7a0d207230bcf8fa51fca3f3cfLeubner, Achim goto free_fail; 1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memset(cmnd, 0xff, 12); 1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memset(gdtcmd, 0, sizeof(gdth_cmd_str)); 1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 18645f1a41b2b2e02e91d29bde66a8da4d050959f65Boaz Harrosh TRACE2(("gdth_get_info() ha %d\n",ha->hanum)); 1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* request is i.e. "cat /proc/scsi/gdth/0" */ 1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* format: %-15s\t%-10s\t%-15s\t%s */ 1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* driver parameters */ 1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size = sprintf(buffer+len,"Driver Parameters:\n"); 1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len += size; pos = begin + len; 1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (reserve_list[0] == 0xff) 1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds strcpy(hrec, "--"); 1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else { 197238ddbb98c327a7392ced5ae65216c55969749eaAlan Cox hlen = sprintf(hrec, "%d", reserve_list[0]); 1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 1; i < MAX_RES_ARGS; i++) { 1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (reserve_list[i] == 0xff) 2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 201238ddbb98c327a7392ced5ae65216c55969749eaAlan Cox hlen += snprintf(hrec + hlen , 161 - hlen, ",%d", reserve_list[i]); 2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size = sprintf(buffer+len, 2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds " reserve_mode: \t%d \treserve_list: \t%s\n", 2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds reserve_mode, hrec); 2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len += size; pos = begin + len; 2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size = sprintf(buffer+len, 2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds " max_ids: \t%-3d \thdr_channel: \t%d\n", 2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds max_ids, hdr_channel); 2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len += size; pos = begin + len; 2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* controller information */ 2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size = sprintf(buffer+len,"\nDisk Array Controller Information:\n"); 2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len += size; pos = begin + len; 21652759e6abc88fe007a080772ee01ef1154f96f30Christoph Hellwig strcpy(hrec, ha->binfo.type_string); 2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size = sprintf(buffer+len, 2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds " Number: \t%d \tName: \t%s\n", 21945f1a41b2b2e02e91d29bde66a8da4d050959f65Boaz Harrosh ha->hanum, hrec); 2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len += size; pos = begin + len; 2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ha->more_proc) 2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sprintf(hrec, "%d.%02d.%02d-%c%03X", 2241fe6dbf4d0afba52ad0249f398e6296a1433a004Dave Jones (u8)(ha->binfo.upd_fw_ver>>24), 2251fe6dbf4d0afba52ad0249f398e6296a1433a004Dave Jones (u8)(ha->binfo.upd_fw_ver>>16), 2261fe6dbf4d0afba52ad0249f398e6296a1433a004Dave Jones (u8)(ha->binfo.upd_fw_ver), 2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ha->bfeat.raid ? 'R':'N', 2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ha->binfo.upd_revision); 2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 2301fe6dbf4d0afba52ad0249f398e6296a1433a004Dave Jones sprintf(hrec, "%d.%02d", (u8)(ha->cpar.version>>8), 2311fe6dbf4d0afba52ad0249f398e6296a1433a004Dave Jones (u8)(ha->cpar.version)); 2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size = sprintf(buffer+len, 2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds " Driver Ver.: \t%-10s\tFirmware Ver.: \t%s\n", 2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds GDTH_VERSION_STR, hrec); 2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len += size; pos = begin + len; 2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ha->more_proc) { 2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* more information: 1. about controller */ 2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size = sprintf(buffer+len, 2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds " Serial No.: \t0x%8X\tCache RAM size:\t%d KB\n", 2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ha->binfo.ser_no, ha->binfo.memsize / 1024); 2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len += size; pos = begin + len; 2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef GDTH_DMA_STATISTICS 2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* controller statistics */ 2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size = sprintf(buffer+len,"\nController Statistics:\n"); 2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len += size; pos = begin + len; 2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size = sprintf(buffer+len, 2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds " 32-bit DMA buffer:\t%lu\t64-bit DMA buffer:\t%lu\n", 2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ha->dma32_cnt, ha->dma64_cnt); 2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len += size; pos = begin + len; 2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (pos < offset) { 2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len = 0; 2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds begin = pos; 2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (pos > offset + length) 2611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto stop_output; 2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ha->more_proc) { 2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* more information: 2. about physical devices */ 2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size = sprintf(buffer+len,"\nPhysical Devices:"); 2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len += size; pos = begin + len; 2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds flag = FALSE; 2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 26945f1a41b2b2e02e91d29bde66a8da4d050959f65Boaz Harrosh buf = gdth_ioctl_alloc(ha, GDTH_SCRATCH, FALSE, &paddr); 2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!buf) 2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto stop_output; 2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < ha->bus_cnt; ++i) { 2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 2.a statistics (and retries/reassigns) */ 2741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds TRACE2(("pdr_statistics() chn %d\n",i)); 2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pds = (gdth_dskstat_str *)(buf + GDTH_SCRATCH/4); 2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds gdtcmd->Service = CACHESERVICE; 2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds gdtcmd->OpCode = GDT_IOCTL; 2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds gdtcmd->u.ioctl.p_param = paddr + GDTH_SCRATCH/4; 2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds gdtcmd->u.ioctl.param_size = 3*GDTH_SCRATCH/4; 2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds gdtcmd->u.ioctl.subfunc = DSK_STATISTICS | L_CTRL_PATTERN; 2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds gdtcmd->u.ioctl.channel = ha->raw[i].address | INVALID_CHANNEL; 2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pds->bid = ha->raw[i].local_no; 2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pds->first = 0; 2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pds->entries = ha->raw[i].pdev_cnt; 2851fe6dbf4d0afba52ad0249f398e6296a1433a004Dave Jones cnt = (3*GDTH_SCRATCH/4 - 5 * sizeof(u32)) / 2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sizeof(pds->list[0]); 2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (pds->entries > cnt) 2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pds->entries = cnt; 289cbd5f69b98bb5d7a0d207230bcf8fa51fca3f3cfLeubner, Achim 290cbd5f69b98bb5d7a0d207230bcf8fa51fca3f3cfLeubner, Achim if (gdth_execute(host, gdtcmd, cmnd, 30, NULL) != S_OK) 2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pds->count = 0; 2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* other IOCTLs must fit into area GDTH_SCRATCH/4 */ 2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (j = 0; j < ha->raw[i].pdev_cnt; ++j) { 2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 2.b drive info */ 2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds TRACE2(("scsi_drv_info() chn %d dev %d\n", 2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds i, ha->raw[i].id_list[j])); 2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pdi = (gdth_diskinfo_str *)buf; 2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds gdtcmd->Service = CACHESERVICE; 3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds gdtcmd->OpCode = GDT_IOCTL; 3011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds gdtcmd->u.ioctl.p_param = paddr; 3021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds gdtcmd->u.ioctl.param_size = sizeof(gdth_diskinfo_str); 3031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds gdtcmd->u.ioctl.subfunc = SCSI_DR_INFO | L_CTRL_PATTERN; 3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds gdtcmd->u.ioctl.channel = 3051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ha->raw[i].address | ha->raw[i].id_list[j]; 306cbd5f69b98bb5d7a0d207230bcf8fa51fca3f3cfLeubner, Achim 307cbd5f69b98bb5d7a0d207230bcf8fa51fca3f3cfLeubner, Achim if (gdth_execute(host, gdtcmd, cmnd, 30, NULL) == S_OK) { 3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds strncpy(hrec,pdi->vendor,8); 3091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds strncpy(hrec+8,pdi->product,16); 3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds strncpy(hrec+24,pdi->revision,4); 3111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hrec[28] = 0; 3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size = sprintf(buffer+len, 3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "\n Chn/ID/LUN: \t%c/%02d/%d \tName: \t%s\n", 3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 'A'+i,pdi->target_id,pdi->lun,hrec); 3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len += size; pos = begin + len; 3161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds flag = TRUE; 3171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pdi->no_ldrive &= 0xffff; 3181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (pdi->no_ldrive == 0xffff) 3191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds strcpy(hrec,"--"); 3201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 3211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sprintf(hrec,"%d",pdi->no_ldrive); 3221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size = sprintf(buffer+len, 3231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds " Capacity [MB]:\t%-6d \tTo Log. Drive: \t%s\n", 3241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pdi->blkcnt/(1024*1024/pdi->blksize), 3251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hrec); 3261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len += size; pos = begin + len; 3271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 3281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pdi->devtype = 0xff; 3291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (pdi->devtype == 0) { 3321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* search retries/reassigns */ 3331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (k = 0; k < pds->count; ++k) { 3341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (pds->list[k].tid == pdi->target_id && 3351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pds->list[k].lun == pdi->lun) { 3361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size = sprintf(buffer+len, 3371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds " Retries: \t%-6d \tReassigns: \t%d\n", 3381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pds->list[k].retries, 3391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pds->list[k].reassigns); 3401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len += size; pos = begin + len; 3411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 3421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 2.c grown defects */ 3451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds TRACE2(("scsi_drv_defcnt() chn %d dev %d\n", 3461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds i, ha->raw[i].id_list[j])); 3471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pdef = (gdth_defcnt_str *)buf; 3481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds gdtcmd->Service = CACHESERVICE; 3491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds gdtcmd->OpCode = GDT_IOCTL; 3501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds gdtcmd->u.ioctl.p_param = paddr; 3511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds gdtcmd->u.ioctl.param_size = sizeof(gdth_defcnt_str); 3521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds gdtcmd->u.ioctl.subfunc = SCSI_DEF_CNT | L_CTRL_PATTERN; 3531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds gdtcmd->u.ioctl.channel = 3541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ha->raw[i].address | ha->raw[i].id_list[j]; 3551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pdef->sddc_type = 0x08; 356cbd5f69b98bb5d7a0d207230bcf8fa51fca3f3cfLeubner, Achim 357cbd5f69b98bb5d7a0d207230bcf8fa51fca3f3cfLeubner, Achim if (gdth_execute(host, gdtcmd, cmnd, 30, NULL) == S_OK) { 3581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size = sprintf(buffer+len, 3591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds " Grown Defects:\t%d\n", 3601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pdef->sddc_cnt); 3611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len += size; pos = begin + len; 3621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (pos < offset) { 3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len = 0; 3661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds begin = pos; 3671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3685c10007560589a2335a77cbc92347b1474518296Julia Lawall if (pos > offset + length) { 3695c10007560589a2335a77cbc92347b1474518296Julia Lawall gdth_ioctl_free(ha, GDTH_SCRATCH, buf, paddr); 3701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto stop_output; 3715c10007560589a2335a77cbc92347b1474518296Julia Lawall } 3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 37445f1a41b2b2e02e91d29bde66a8da4d050959f65Boaz Harrosh gdth_ioctl_free(ha, GDTH_SCRATCH, buf, paddr); 3751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!flag) { 3771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size = sprintf(buffer+len, "\n --\n"); 3781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len += size; pos = begin + len; 3791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 3. about logical drives */ 3821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size = sprintf(buffer+len,"\nLogical Drives:"); 3831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len += size; pos = begin + len; 3841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds flag = FALSE; 3851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 38645f1a41b2b2e02e91d29bde66a8da4d050959f65Boaz Harrosh buf = gdth_ioctl_alloc(ha, GDTH_SCRATCH, FALSE, &paddr); 3871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!buf) 3881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto stop_output; 3891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < MAX_LDRIVES; ++i) { 3901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!ha->hdr[i].is_logdrv) 3911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds continue; 3921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds drv_no = i; 3931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds j = k = 0; 3941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds is_mirr = FALSE; 3951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds do { 3961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 3.a log. drive info */ 3971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds TRACE2(("cache_drv_info() drive no %d\n",drv_no)); 3981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pcdi = (gdth_cdrinfo_str *)buf; 3991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds gdtcmd->Service = CACHESERVICE; 4001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds gdtcmd->OpCode = GDT_IOCTL; 4011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds gdtcmd->u.ioctl.p_param = paddr; 4021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds gdtcmd->u.ioctl.param_size = sizeof(gdth_cdrinfo_str); 4031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds gdtcmd->u.ioctl.subfunc = CACHE_DRV_INFO; 4041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds gdtcmd->u.ioctl.channel = drv_no; 405cbd5f69b98bb5d7a0d207230bcf8fa51fca3f3cfLeubner, Achim if (gdth_execute(host, gdtcmd, cmnd, 30, NULL) != S_OK) 4061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 4071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pcdi->ld_dtype >>= 16; 4081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds j++; 4091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (pcdi->ld_dtype > 2) { 4101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds strcpy(hrec, "missing"); 4111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if (pcdi->ld_error & 1) { 4121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds strcpy(hrec, "fault"); 4131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if (pcdi->ld_error & 2) { 4141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds strcpy(hrec, "invalid"); 4151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds k++; j--; 4161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 4171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds strcpy(hrec, "ok"); 4181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (drv_no == i) { 4211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size = sprintf(buffer+len, 4221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "\n Number: \t%-2d \tStatus: \t%s\n", 4231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds drv_no, hrec); 4241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len += size; pos = begin + len; 4251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds flag = TRUE; 4261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds no_mdrv = pcdi->cd_ldcnt; 4271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (no_mdrv > 1 || pcdi->ld_slave != -1) { 4281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds is_mirr = TRUE; 4291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds strcpy(hrec, "RAID-1"); 4301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if (pcdi->ld_dtype == 0) { 4311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds strcpy(hrec, "Disk"); 4321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if (pcdi->ld_dtype == 1) { 4331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds strcpy(hrec, "RAID-0"); 4341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if (pcdi->ld_dtype == 2) { 4351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds strcpy(hrec, "Chain"); 4361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 4371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds strcpy(hrec, "???"); 4381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size = sprintf(buffer+len, 4401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds " Capacity [MB]:\t%-6d \tType: \t%s\n", 4411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pcdi->ld_blkcnt/(1024*1024/pcdi->ld_blksize), 4421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hrec); 4431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len += size; pos = begin + len; 4441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 4451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size = sprintf(buffer+len, 4461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds " Slave Number: \t%-2d \tStatus: \t%s\n", 4471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds drv_no & 0x7fff, hrec); 4481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len += size; pos = begin + len; 4491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds drv_no = pcdi->ld_slave; 4511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (pos < offset) { 4521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len = 0; 4531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds begin = pos; 4541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4555c10007560589a2335a77cbc92347b1474518296Julia Lawall if (pos > offset + length) { 4565c10007560589a2335a77cbc92347b1474518296Julia Lawall gdth_ioctl_free(ha, GDTH_SCRATCH, buf, paddr); 4571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto stop_output; 4585c10007560589a2335a77cbc92347b1474518296Julia Lawall } 4591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } while (drv_no != -1); 4601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (is_mirr) { 4621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size = sprintf(buffer+len, 4631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds " Missing Drv.: \t%-2d \tInvalid Drv.: \t%d\n", 4641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds no_mdrv - j - k, k); 4651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len += size; pos = begin + len; 4661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!ha->hdr[i].is_arraydrv) 4691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds strcpy(hrec, "--"); 4701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 4711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sprintf(hrec, "%d", ha->hdr[i].master_no); 4721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size = sprintf(buffer+len, 4731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds " To Array Drv.:\t%s\n", hrec); 4741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len += size; pos = begin + len; 4751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (pos < offset) { 4761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len = 0; 4771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds begin = pos; 4781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4795c10007560589a2335a77cbc92347b1474518296Julia Lawall if (pos > offset + length) { 4805c10007560589a2335a77cbc92347b1474518296Julia Lawall gdth_ioctl_free(ha, GDTH_SCRATCH, buf, paddr); 4811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto stop_output; 4825c10007560589a2335a77cbc92347b1474518296Julia Lawall } 4831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 48445f1a41b2b2e02e91d29bde66a8da4d050959f65Boaz Harrosh gdth_ioctl_free(ha, GDTH_SCRATCH, buf, paddr); 4851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!flag) { 4871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size = sprintf(buffer+len, "\n --\n"); 4881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len += size; pos = begin + len; 4891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 4. about array drives */ 4921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size = sprintf(buffer+len,"\nArray Drives:"); 4931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len += size; pos = begin + len; 4941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds flag = FALSE; 4951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 49645f1a41b2b2e02e91d29bde66a8da4d050959f65Boaz Harrosh buf = gdth_ioctl_alloc(ha, GDTH_SCRATCH, FALSE, &paddr); 4971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!buf) 4981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto stop_output; 4991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < MAX_LDRIVES; ++i) { 5001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(ha->hdr[i].is_arraydrv && ha->hdr[i].is_master)) 5011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds continue; 5021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 4.a array drive info */ 5031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds TRACE2(("array_info() drive no %d\n",i)); 5041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pai = (gdth_arrayinf_str *)buf; 5051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds gdtcmd->Service = CACHESERVICE; 5061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds gdtcmd->OpCode = GDT_IOCTL; 5071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds gdtcmd->u.ioctl.p_param = paddr; 5081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds gdtcmd->u.ioctl.param_size = sizeof(gdth_arrayinf_str); 5091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds gdtcmd->u.ioctl.subfunc = ARRAY_INFO | LA_CTRL_PATTERN; 5101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds gdtcmd->u.ioctl.channel = i; 511cbd5f69b98bb5d7a0d207230bcf8fa51fca3f3cfLeubner, Achim if (gdth_execute(host, gdtcmd, cmnd, 30, NULL) == S_OK) { 5121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (pai->ai_state == 0) 5131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds strcpy(hrec, "idle"); 5141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else if (pai->ai_state == 2) 5151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds strcpy(hrec, "build"); 5161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else if (pai->ai_state == 4) 5171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds strcpy(hrec, "ready"); 5181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else if (pai->ai_state == 6) 5191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds strcpy(hrec, "fail"); 5201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else if (pai->ai_state == 8 || pai->ai_state == 10) 5211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds strcpy(hrec, "rebuild"); 5221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 5231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds strcpy(hrec, "error"); 5241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (pai->ai_ext_state & 0x10) 5251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds strcat(hrec, "/expand"); 5261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else if (pai->ai_ext_state & 0x1) 5271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds strcat(hrec, "/patch"); 5281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size = sprintf(buffer+len, 5291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "\n Number: \t%-2d \tStatus: \t%s\n", 5301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds i,hrec); 5311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len += size; pos = begin + len; 5321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds flag = TRUE; 5331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (pai->ai_type == 0) 5351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds strcpy(hrec, "RAID-0"); 5361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else if (pai->ai_type == 4) 5371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds strcpy(hrec, "RAID-4"); 5381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else if (pai->ai_type == 5) 5391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds strcpy(hrec, "RAID-5"); 5401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 5411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds strcpy(hrec, "RAID-10"); 5421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size = sprintf(buffer+len, 5431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds " Capacity [MB]:\t%-6d \tType: \t%s\n", 5441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pai->ai_size/(1024*1024/pai->ai_secsize), 5451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hrec); 5461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len += size; pos = begin + len; 5471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (pos < offset) { 5481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len = 0; 5491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds begin = pos; 5501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5515c10007560589a2335a77cbc92347b1474518296Julia Lawall if (pos > offset + length) { 5525c10007560589a2335a77cbc92347b1474518296Julia Lawall gdth_ioctl_free(ha, GDTH_SCRATCH, buf, paddr); 5531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto stop_output; 5545c10007560589a2335a77cbc92347b1474518296Julia Lawall } 5551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 55745f1a41b2b2e02e91d29bde66a8da4d050959f65Boaz Harrosh gdth_ioctl_free(ha, GDTH_SCRATCH, buf, paddr); 5581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!flag) { 5601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size = sprintf(buffer+len, "\n --\n"); 5611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len += size; pos = begin + len; 5621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 5. about host drives */ 5651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size = sprintf(buffer+len,"\nHost Drives:"); 5661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len += size; pos = begin + len; 5671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds flag = FALSE; 5681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 56945f1a41b2b2e02e91d29bde66a8da4d050959f65Boaz Harrosh buf = gdth_ioctl_alloc(ha, sizeof(gdth_hget_str), FALSE, &paddr); 5701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!buf) 5711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto stop_output; 5721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < MAX_LDRIVES; ++i) { 5731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!ha->hdr[i].is_logdrv || 5741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (ha->hdr[i].is_arraydrv && !ha->hdr[i].is_master)) 5751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds continue; 5761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 5.a get host drive list */ 5771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds TRACE2(("host_get() drv_no %d\n",i)); 5781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds phg = (gdth_hget_str *)buf; 5791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds gdtcmd->Service = CACHESERVICE; 5801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds gdtcmd->OpCode = GDT_IOCTL; 5811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds gdtcmd->u.ioctl.p_param = paddr; 5821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds gdtcmd->u.ioctl.param_size = sizeof(gdth_hget_str); 5831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds gdtcmd->u.ioctl.subfunc = HOST_GET | LA_CTRL_PATTERN; 5841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds gdtcmd->u.ioctl.channel = i; 5851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds phg->entries = MAX_HDRIVES; 5861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds phg->offset = GDTOFFSOF(gdth_hget_str, entry[0]); 587cbd5f69b98bb5d7a0d207230bcf8fa51fca3f3cfLeubner, Achim if (gdth_execute(host, gdtcmd, cmnd, 30, NULL) == S_OK) { 5881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ha->hdr[i].ldr_no = i; 5891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ha->hdr[i].rw_attribs = 0; 5901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ha->hdr[i].start_sec = 0; 5911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 5921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (j = 0; j < phg->entries; ++j) { 5931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds k = phg->entry[j].host_drive; 5941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (k >= MAX_LDRIVES) 5951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds continue; 5961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ha->hdr[k].ldr_no = phg->entry[j].log_drive; 5971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ha->hdr[k].rw_attribs = phg->entry[j].rw_attribs; 5981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ha->hdr[k].start_sec = phg->entry[j].start_sec; 5991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 60245f1a41b2b2e02e91d29bde66a8da4d050959f65Boaz Harrosh gdth_ioctl_free(ha, sizeof(gdth_hget_str), buf, paddr); 6031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < MAX_HDRIVES; ++i) { 6051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(ha->hdr[i].present)) 6061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds continue; 6071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size = sprintf(buffer+len, 6091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "\n Number: \t%-2d \tArr/Log. Drive:\t%d\n", 6101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds i, ha->hdr[i].ldr_no); 6111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len += size; pos = begin + len; 6121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds flag = TRUE; 6131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size = sprintf(buffer+len, 6151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds " Capacity [MB]:\t%-6d \tStart Sector: \t%d\n", 6161fe6dbf4d0afba52ad0249f398e6296a1433a004Dave Jones (u32)(ha->hdr[i].size/2048), ha->hdr[i].start_sec); 6171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len += size; pos = begin + len; 6181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (pos < offset) { 6191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len = 0; 6201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds begin = pos; 6211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (pos > offset + length) 6231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto stop_output; 6241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!flag) { 6271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size = sprintf(buffer+len, "\n --\n"); 6281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len += size; pos = begin + len; 6291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* controller events */ 6331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size = sprintf(buffer+len,"\nController Events:\n"); 6341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len += size; pos = begin + len; 6351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (id = -1;;) { 6371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds id = gdth_read_event(ha, id, estr); 6381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (estr->event_source == 0) 6391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 64045f1a41b2b2e02e91d29bde66a8da4d050959f65Boaz Harrosh if (estr->event_data.eu.driver.ionode == ha->hanum && 6411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds estr->event_source == ES_ASYNC) { 6421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds gdth_log_event(&estr->event_data, hrec); 6431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds do_gettimeofday(&tv); 6441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sec = (int)(tv.tv_sec - estr->first_stamp); 6451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (sec < 0) sec = 0; 6461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size = sprintf(buffer+len," date- %02d:%02d:%02d\t%s\n", 6471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sec/3600, sec%3600/60, sec%60, hrec); 6481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len += size; pos = begin + len; 6491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (pos < offset) { 6501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len = 0; 6511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds begin = pos; 6521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (pos > offset + length) 6541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto stop_output; 6551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (id == -1) 6571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 6581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstop_output: 6611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *start = buffer +(offset-begin); 6621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len -= (offset-begin); 6631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (len > length) 6641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len = length; 6651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds TRACE2(("get_info() len %d pos %d begin %d offset %d length %d size %d\n", 6661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len,(int)pos,(int)begin,(int)offset,length,size)); 6671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rc = len; 6681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsfree_fail: 6701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds kfree(gdtcmd); 6711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds kfree(estr); 6721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return rc; 6731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 67545f1a41b2b2e02e91d29bde66a8da4d050959f65Boaz Harroshstatic char *gdth_ioctl_alloc(gdth_ha_str *ha, int size, int scratch, 6761fe6dbf4d0afba52ad0249f398e6296a1433a004Dave Jones u64 *paddr) 6771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6781fe6dbf4d0afba52ad0249f398e6296a1433a004Dave Jones unsigned long flags; 6791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char *ret_val; 6801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (size == 0) 6821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return NULL; 6831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_lock_irqsave(&ha->smp_lock, flags); 6851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!ha->scratch_busy && size <= GDTH_SCRATCH) { 6871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ha->scratch_busy = TRUE; 6881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret_val = ha->pscratch; 6891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *paddr = ha->scratch_phys; 6901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if (scratch) { 6911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret_val = NULL; 6921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 6931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dma_addr_t dma_addr; 6941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret_val = pci_alloc_consistent(ha->pdev, size, &dma_addr); 6961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *paddr = dma_addr; 6971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_unlock_irqrestore(&ha->smp_lock, flags); 7001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret_val; 7011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7031fe6dbf4d0afba52ad0249f398e6296a1433a004Dave Jonesstatic void gdth_ioctl_free(gdth_ha_str *ha, int size, char *buf, u64 paddr) 7041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7051fe6dbf4d0afba52ad0249f398e6296a1433a004Dave Jones unsigned long flags; 7061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (buf == ha->pscratch) { 708ff83efacf2b77a1fe8942db6613825a4b80ee5e2James Bottomley spin_lock_irqsave(&ha->smp_lock, flags); 7091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ha->scratch_busy = FALSE; 710ff83efacf2b77a1fe8942db6613825a4b80ee5e2James Bottomley spin_unlock_irqrestore(&ha->smp_lock, flags); 7111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 7121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_free_consistent(ha->pdev, size, buf, paddr); 7131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef GDTH_IOCTL_PROC 7171fe6dbf4d0afba52ad0249f398e6296a1433a004Dave Jonesstatic int gdth_ioctl_check_bin(gdth_ha_str *ha, u16 size) 7181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7191fe6dbf4d0afba52ad0249f398e6296a1433a004Dave Jones unsigned long flags; 7201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ret_val; 7211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_lock_irqsave(&ha->smp_lock, flags); 7231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret_val = FALSE; 7251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ha->scratch_busy) { 7261fe6dbf4d0afba52ad0249f398e6296a1433a004Dave Jones if (((gdth_iord_str *)ha->pscratch)->size == (u32)size) 7271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret_val = TRUE; 7281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_unlock_irqrestore(&ha->smp_lock, flags); 7301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret_val; 7311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 7331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 73445f1a41b2b2e02e91d29bde66a8da4d050959f65Boaz Harroshstatic void gdth_wait_completion(gdth_ha_str *ha, int busnum, int id) 7351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7361fe6dbf4d0afba52ad0249f398e6296a1433a004Dave Jones unsigned long flags; 7371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 7381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Scsi_Cmnd *scp; 739f842b64e0ffbcc9ce48a3bf799d0b005094107c1Boaz Harrosh struct gdth_cmndinfo *cmndinfo; 7401fe6dbf4d0afba52ad0249f398e6296a1433a004Dave Jones u8 b, t; 7411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_lock_irqsave(&ha->smp_lock, flags); 7431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < GDTH_MAXCMDS; ++i) { 7451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds scp = ha->cmd_tab[i].cmnd; 746f842b64e0ffbcc9ce48a3bf799d0b005094107c1Boaz Harrosh cmndinfo = gdth_cmnd_priv(scp); 7471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 74852759e6abc88fe007a080772ee01ef1154f96f30Christoph Hellwig b = scp->device->channel; 7491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds t = scp->device->id; 7501fe6dbf4d0afba52ad0249f398e6296a1433a004Dave Jones if (!SPECIAL_SCP(scp) && t == (u8)id && 7511fe6dbf4d0afba52ad0249f398e6296a1433a004Dave Jones b == (u8)busnum) { 752f842b64e0ffbcc9ce48a3bf799d0b005094107c1Boaz Harrosh cmndinfo->wait_for_completion = 0; 7531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_unlock_irqrestore(&ha->smp_lock, flags); 754f842b64e0ffbcc9ce48a3bf799d0b005094107c1Boaz Harrosh while (!cmndinfo->wait_for_completion) 7551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds barrier(); 7561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_lock_irqsave(&ha->smp_lock, flags); 7571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_unlock_irqrestore(&ha->smp_lock, flags); 7601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 761