Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /* gdth_proc.c 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * $Id: gdth_proc.c,v 1.43 2006/01/11 16:15:00 achim Exp $
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) #include <linux/completion.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) int gdth_set_info(struct Scsi_Host *host, char *buffer, int length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)     gdth_ha_str *ha = shost_priv(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)     int ret_val = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)     TRACE2(("gdth_set_info() ha %d\n",ha->hanum,));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16)     if (length >= 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17)         if (strncmp(buffer,"gdth",4) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18)             buffer += 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19)             length -= 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20)             ret_val = gdth_set_asc_info(host, buffer, length, ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24)     return ret_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26)          
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) static int gdth_set_asc_info(struct Scsi_Host *host, char *buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28)                         int length, gdth_ha_str *ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30)     int orig_length, drive, wb_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31)     int i, found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32)     gdth_cmd_str    gdtcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33)     gdth_cpar_str   *pcpar;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35)     char            cmnd[MAX_COMMAND_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36)     memset(cmnd, 0xff, 12);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37)     memset(&gdtcmd, 0, sizeof(gdth_cmd_str));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39)     TRACE2(("gdth_set_asc_info() ha %d\n",ha->hanum));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40)     orig_length = length + 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41)     drive = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42)     wb_mode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43)     found = FALSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45)     if (length >= 5 && strncmp(buffer,"flush",5)==0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46)         buffer += 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47)         length -= 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48)         if (length && *buffer>='0' && *buffer<='9') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49)             drive = (int)(*buffer-'0');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50)             ++buffer; --length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51)             if (length && *buffer>='0' && *buffer<='9') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52)                 drive = drive*10 + (int)(*buffer-'0');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53)                 ++buffer; --length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54)             }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55)             printk("GDT: Flushing host drive %d .. ",drive);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56)         } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57)             printk("GDT: Flushing all host drives .. ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59)         for (i = 0; i < MAX_HDRIVES; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60)             if (ha->hdr[i].present) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61)                 if (drive != -1 && i != drive)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62)                     continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63)                 found = TRUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64)                 gdtcmd.Service = CACHESERVICE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65)                 gdtcmd.OpCode = GDT_FLUSH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66)                 if (ha->cache_feat & GDT_64BIT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67)                     gdtcmd.u.cache64.DeviceNo = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68)                     gdtcmd.u.cache64.BlockNo = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69)                 } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70)                     gdtcmd.u.cache.DeviceNo = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71)                     gdtcmd.u.cache.BlockNo = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72)                 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74)                 gdth_execute(host, &gdtcmd, cmnd, 30, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75)             }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77)         if (!found)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78)             printk("\nNo host drive found !\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79)         else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80)             printk("Done.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81)         return(orig_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84)     if (length >= 7 && strncmp(buffer,"wbp_off",7)==0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85)         buffer += 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86)         length -= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87)         printk("GDT: Disabling write back permanently .. ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88)         wb_mode = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89)     } else if (length >= 6 && strncmp(buffer,"wbp_on",6)==0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90)         buffer += 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91)         length -= 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92)         printk("GDT: Enabling write back permanently .. ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93)         wb_mode = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94)     } else if (length >= 6 && strncmp(buffer,"wb_off",6)==0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95)         buffer += 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96)         length -= 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97)         printk("GDT: Disabling write back commands .. ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98)         if (ha->cache_feat & GDT_WR_THROUGH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99)             gdth_write_through = TRUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)             printk("Done.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)         } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)             printk("Not supported !\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)         return(orig_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)     } else if (length >= 5 && strncmp(buffer,"wb_on",5)==0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)         buffer += 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)         length -= 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)         printk("GDT: Enabling write back commands .. ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)         gdth_write_through = FALSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)         printk("Done.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)         return(orig_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)     if (wb_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	BUILD_BUG_ON(sizeof(gdth_cpar_str) > GDTH_SCRATCH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	spin_lock_irqsave(&ha->smp_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	if (ha->scratch_busy) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	    spin_unlock_irqrestore(&ha->smp_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)             return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	ha->scratch_busy = TRUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	spin_unlock_irqrestore(&ha->smp_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)         pcpar = (gdth_cpar_str *)ha->pscratch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)         memcpy( pcpar, &ha->cpar, sizeof(gdth_cpar_str) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)         gdtcmd.Service = CACHESERVICE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)         gdtcmd.OpCode = GDT_IOCTL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)         gdtcmd.u.ioctl.p_param = ha->scratch_phys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)         gdtcmd.u.ioctl.param_size = sizeof(gdth_cpar_str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)         gdtcmd.u.ioctl.subfunc = CACHE_CONFIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)         gdtcmd.u.ioctl.channel = INVALID_CHANNEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)         pcpar->write_back = wb_mode==1 ? 0:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)         gdth_execute(host, &gdtcmd, cmnd, 30, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	spin_lock_irqsave(&ha->smp_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	ha->scratch_busy = FALSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	spin_unlock_irqrestore(&ha->smp_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)         printk("Done.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)         return(orig_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)     printk("GDT: Unknown command: %s  Length: %d\n",buffer,length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)     return(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) int gdth_show_info(struct seq_file *m, struct Scsi_Host *host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)     gdth_ha_str *ha = shost_priv(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)     int hlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)     int id, i, j, k, sec, flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)     int no_mdrv = 0, drv_no, is_mirr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)     u32 cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)     dma_addr_t paddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)     int rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)     gdth_cmd_str *gdtcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)     gdth_evt_str *estr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)     char hrec[277];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)     char *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)     gdth_dskstat_str *pds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)     gdth_diskinfo_str *pdi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)     gdth_arrayinf_str *pai;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)     gdth_defcnt_str *pdef;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)     gdth_cdrinfo_str *pcdi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)     gdth_hget_str *phg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)     char cmnd[MAX_COMMAND_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)     gdtcmd = kmalloc(sizeof(*gdtcmd), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)     estr = kmalloc(sizeof(*estr), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)     if (!gdtcmd || !estr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)         goto free_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)     memset(cmnd, 0xff, 12);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)     memset(gdtcmd, 0, sizeof(gdth_cmd_str));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)     TRACE2(("gdth_get_info() ha %d\n",ha->hanum));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)     
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)     /* request is i.e. "cat /proc/scsi/gdth/0" */ 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)     /* format: %-15s\t%-10s\t%-15s\t%s */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)     /* driver parameters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)     seq_puts(m, "Driver Parameters:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)     if (reserve_list[0] == 0xff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)         strcpy(hrec, "--");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)     else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)         hlen = sprintf(hrec, "%d", reserve_list[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)         for (i = 1;  i < MAX_RES_ARGS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)             if (reserve_list[i] == 0xff) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)                 break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	    hlen += scnprintf(hrec + hlen, 161 - hlen, ",%d", reserve_list[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)     seq_printf(m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)                    " reserve_mode: \t%d         \treserve_list:  \t%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)                    reserve_mode, hrec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)     seq_printf(m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)                    " max_ids:      \t%-3d       \thdr_channel:   \t%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)                    max_ids, hdr_channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)     /* controller information */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)     seq_puts(m, "\nDisk Array Controller Information:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)     seq_printf(m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)                    " Number:       \t%d         \tName:          \t%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)                    ha->hanum, ha->binfo.type_string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)     seq_printf(m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)                    " Driver Ver.:  \t%-10s\tFirmware Ver.: \t",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)                    GDTH_VERSION_STR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)     if (ha->more_proc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)         seq_printf(m, "%d.%02d.%02d-%c%03X\n", 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)                 (u8)(ha->binfo.upd_fw_ver>>24),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)                 (u8)(ha->binfo.upd_fw_ver>>16),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)                 (u8)(ha->binfo.upd_fw_ver),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)                 ha->bfeat.raid ? 'R':'N',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)                 ha->binfo.upd_revision);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)     else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)         seq_printf(m, "%d.%02d\n", (u8)(ha->cpar.version>>8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)                 (u8)(ha->cpar.version));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)  
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)     if (ha->more_proc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)         /* more information: 1. about controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)         seq_printf(m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)                        " Serial No.:   \t0x%8X\tCache RAM size:\t%d KB\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)                        ha->binfo.ser_no, ha->binfo.memsize / 1024);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)     if (ha->more_proc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)         size_t size = max_t(size_t, GDTH_SCRATCH, sizeof(gdth_hget_str));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)         /* more information: 2. about physical devices */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)         seq_puts(m, "\nPhysical Devices:");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)         flag = FALSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)             
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)         buf = dma_alloc_coherent(&ha->pdev->dev, size, &paddr, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)         if (!buf) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)             goto stop_output;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)         for (i = 0; i < ha->bus_cnt; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)             /* 2.a statistics (and retries/reassigns) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)             TRACE2(("pdr_statistics() chn %d\n",i));                
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)             pds = (gdth_dskstat_str *)(buf + GDTH_SCRATCH/4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)             gdtcmd->Service = CACHESERVICE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)             gdtcmd->OpCode = GDT_IOCTL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)             gdtcmd->u.ioctl.p_param = paddr + GDTH_SCRATCH/4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)             gdtcmd->u.ioctl.param_size = 3*GDTH_SCRATCH/4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)             gdtcmd->u.ioctl.subfunc = DSK_STATISTICS | L_CTRL_PATTERN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)             gdtcmd->u.ioctl.channel = ha->raw[i].address | INVALID_CHANNEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)             pds->bid = ha->raw[i].local_no;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)             pds->first = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)             pds->entries = ha->raw[i].pdev_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)             cnt = (3*GDTH_SCRATCH/4 - 5 * sizeof(u32)) /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)                 sizeof(pds->list[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)             if (pds->entries > cnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)                 pds->entries = cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)             if (gdth_execute(host, gdtcmd, cmnd, 30, NULL) != S_OK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)                 pds->count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)             /* other IOCTLs must fit into area GDTH_SCRATCH/4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)             for (j = 0; j < ha->raw[i].pdev_cnt; ++j) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)                 /* 2.b drive info */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)                 TRACE2(("scsi_drv_info() chn %d dev %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)                     i, ha->raw[i].id_list[j]));             
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)                 pdi = (gdth_diskinfo_str *)buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)                 gdtcmd->Service = CACHESERVICE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)                 gdtcmd->OpCode = GDT_IOCTL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)                 gdtcmd->u.ioctl.p_param = paddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)                 gdtcmd->u.ioctl.param_size = sizeof(gdth_diskinfo_str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)                 gdtcmd->u.ioctl.subfunc = SCSI_DR_INFO | L_CTRL_PATTERN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)                 gdtcmd->u.ioctl.channel = 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)                     ha->raw[i].address | ha->raw[i].id_list[j];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)                 if (gdth_execute(host, gdtcmd, cmnd, 30, NULL) == S_OK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)                     strncpy(hrec,pdi->vendor,8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)                     strncpy(hrec+8,pdi->product,16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)                     strncpy(hrec+24,pdi->revision,4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)                     hrec[28] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)                     seq_printf(m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)                                    "\n Chn/ID/LUN:   \t%c/%02d/%d    \tName:          \t%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)                                    'A'+i,pdi->target_id,pdi->lun,hrec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)                     flag = TRUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)                     pdi->no_ldrive &= 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)                     if (pdi->no_ldrive == 0xffff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)                         strcpy(hrec,"--");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)                     else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)                         sprintf(hrec,"%d",pdi->no_ldrive);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)                     seq_printf(m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)                                    " Capacity [MB]:\t%-6d    \tTo Log. Drive: \t%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)                                    pdi->blkcnt/(1024*1024/pdi->blksize),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)                                    hrec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)                 } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)                     pdi->devtype = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)                 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)                     
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)                 if (pdi->devtype == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)                     /* search retries/reassigns */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)                     for (k = 0; k < pds->count; ++k) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)                         if (pds->list[k].tid == pdi->target_id &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)                             pds->list[k].lun == pdi->lun) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)                             seq_printf(m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)                                            " Retries:      \t%-6d    \tReassigns:     \t%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)                                            pds->list[k].retries,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)                                            pds->list[k].reassigns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)                             break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)                         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)                     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)                     /* 2.c grown defects */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)                     TRACE2(("scsi_drv_defcnt() chn %d dev %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)                             i, ha->raw[i].id_list[j]));             
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)                     pdef = (gdth_defcnt_str *)buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)                     gdtcmd->Service = CACHESERVICE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)                     gdtcmd->OpCode = GDT_IOCTL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)                     gdtcmd->u.ioctl.p_param = paddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)                     gdtcmd->u.ioctl.param_size = sizeof(gdth_defcnt_str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)                     gdtcmd->u.ioctl.subfunc = SCSI_DEF_CNT | L_CTRL_PATTERN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)                     gdtcmd->u.ioctl.channel = 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)                         ha->raw[i].address | ha->raw[i].id_list[j];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)                     pdef->sddc_type = 0x08;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)                     if (gdth_execute(host, gdtcmd, cmnd, 30, NULL) == S_OK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)                         seq_printf(m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)                                        " Grown Defects:\t%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)                                        pdef->sddc_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)                     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)                 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)             }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)         if (!flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)             seq_puts(m, "\n --\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)         /* 3. about logical drives */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)         seq_puts(m, "\nLogical Drives:");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)         flag = FALSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)         for (i = 0; i < MAX_LDRIVES; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)             if (!ha->hdr[i].is_logdrv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)                 continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)             drv_no = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)             j = k = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)             is_mirr = FALSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)             do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)                 /* 3.a log. drive info */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)                 TRACE2(("cache_drv_info() drive no %d\n",drv_no));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)                 pcdi = (gdth_cdrinfo_str *)buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)                 gdtcmd->Service = CACHESERVICE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)                 gdtcmd->OpCode = GDT_IOCTL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)                 gdtcmd->u.ioctl.p_param = paddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)                 gdtcmd->u.ioctl.param_size = sizeof(gdth_cdrinfo_str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)                 gdtcmd->u.ioctl.subfunc = CACHE_DRV_INFO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)                 gdtcmd->u.ioctl.channel = drv_no;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)                 if (gdth_execute(host, gdtcmd, cmnd, 30, NULL) != S_OK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)                     break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)                 pcdi->ld_dtype >>= 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)                 j++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)                 if (pcdi->ld_dtype > 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)                     strcpy(hrec, "missing");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)                 } else if (pcdi->ld_error & 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)                     strcpy(hrec, "fault");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)                 } else if (pcdi->ld_error & 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)                     strcpy(hrec, "invalid");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)                     k++; j--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)                 } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)                     strcpy(hrec, "ok");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)                 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)                     
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)                 if (drv_no == i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)                     seq_printf(m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)                                    "\n Number:       \t%-2d        \tStatus:        \t%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)                                    drv_no, hrec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)                     flag = TRUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)                     no_mdrv = pcdi->cd_ldcnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)                     if (no_mdrv > 1 || pcdi->ld_slave != -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)                         is_mirr = TRUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)                         strcpy(hrec, "RAID-1");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)                     } else if (pcdi->ld_dtype == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)                         strcpy(hrec, "Disk");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)                     } else if (pcdi->ld_dtype == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)                         strcpy(hrec, "RAID-0");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)                     } else if (pcdi->ld_dtype == 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)                         strcpy(hrec, "Chain");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)                     } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)                         strcpy(hrec, "???");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)                     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)                     seq_printf(m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)                                    " Capacity [MB]:\t%-6d    \tType:          \t%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)                                    pcdi->ld_blkcnt/(1024*1024/pcdi->ld_blksize),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)                                    hrec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)                 } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)                     seq_printf(m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)                                    " Slave Number: \t%-2d        \tStatus:        \t%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)                                    drv_no & 0x7fff, hrec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)                 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)                 drv_no = pcdi->ld_slave;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)             } while (drv_no != -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)              
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)             if (is_mirr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)                 seq_printf(m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)                                " Missing Drv.: \t%-2d        \tInvalid Drv.:  \t%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)                                no_mdrv - j - k, k);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)             if (!ha->hdr[i].is_arraydrv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)                 strcpy(hrec, "--");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)             else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)                 sprintf(hrec, "%d", ha->hdr[i].master_no);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)             seq_printf(m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)                            " To Array Drv.:\t%s\n", hrec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)         }       
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)         if (!flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)             seq_puts(m, "\n --\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)         /* 4. about array drives */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)         seq_puts(m, "\nArray Drives:");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)         flag = FALSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)         for (i = 0; i < MAX_LDRIVES; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)             if (!(ha->hdr[i].is_arraydrv && ha->hdr[i].is_master))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)                 continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)             /* 4.a array drive info */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)             TRACE2(("array_info() drive no %d\n",i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)             pai = (gdth_arrayinf_str *)buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)             gdtcmd->Service = CACHESERVICE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)             gdtcmd->OpCode = GDT_IOCTL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)             gdtcmd->u.ioctl.p_param = paddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)             gdtcmd->u.ioctl.param_size = sizeof(gdth_arrayinf_str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)             gdtcmd->u.ioctl.subfunc = ARRAY_INFO | LA_CTRL_PATTERN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)             gdtcmd->u.ioctl.channel = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)             if (gdth_execute(host, gdtcmd, cmnd, 30, NULL) == S_OK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)                 if (pai->ai_state == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)                     strcpy(hrec, "idle");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)                 else if (pai->ai_state == 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)                     strcpy(hrec, "build");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)                 else if (pai->ai_state == 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)                     strcpy(hrec, "ready");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)                 else if (pai->ai_state == 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)                     strcpy(hrec, "fail");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)                 else if (pai->ai_state == 8 || pai->ai_state == 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)                     strcpy(hrec, "rebuild");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)                 else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)                     strcpy(hrec, "error");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)                 if (pai->ai_ext_state & 0x10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)                     strcat(hrec, "/expand");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)                 else if (pai->ai_ext_state & 0x1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)                     strcat(hrec, "/patch");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)                 seq_printf(m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)                                "\n Number:       \t%-2d        \tStatus:        \t%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)                                i,hrec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)                 flag = TRUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)                 if (pai->ai_type == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)                     strcpy(hrec, "RAID-0");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)                 else if (pai->ai_type == 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)                     strcpy(hrec, "RAID-4");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)                 else if (pai->ai_type == 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)                     strcpy(hrec, "RAID-5");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)                 else 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)                     strcpy(hrec, "RAID-10");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)                 seq_printf(m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)                                " Capacity [MB]:\t%-6d    \tType:          \t%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)                                pai->ai_size/(1024*1024/pai->ai_secsize),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)                                hrec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)             }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)         if (!flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)             seq_puts(m, "\n --\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)         /* 5. about host drives */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)         seq_puts(m, "\nHost Drives:");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)         flag = FALSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)         for (i = 0; i < MAX_LDRIVES; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)             if (!ha->hdr[i].is_logdrv || 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)                 (ha->hdr[i].is_arraydrv && !ha->hdr[i].is_master))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)                 continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)             /* 5.a get host drive list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)             TRACE2(("host_get() drv_no %d\n",i));           
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)             phg = (gdth_hget_str *)buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)             gdtcmd->Service = CACHESERVICE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)             gdtcmd->OpCode = GDT_IOCTL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)             gdtcmd->u.ioctl.p_param = paddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)             gdtcmd->u.ioctl.param_size = sizeof(gdth_hget_str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)             gdtcmd->u.ioctl.subfunc = HOST_GET | LA_CTRL_PATTERN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)             gdtcmd->u.ioctl.channel = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)             phg->entries = MAX_HDRIVES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)             phg->offset = GDTOFFSOF(gdth_hget_str, entry[0]); 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)             if (gdth_execute(host, gdtcmd, cmnd, 30, NULL) == S_OK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)                 ha->hdr[i].ldr_no = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)                 ha->hdr[i].rw_attribs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)                 ha->hdr[i].start_sec = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)             } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)                 for (j = 0; j < phg->entries; ++j) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)                     k = phg->entry[j].host_drive;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499)                     if (k >= MAX_LDRIVES)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)                         continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501)                     ha->hdr[k].ldr_no = phg->entry[j].log_drive;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)                     ha->hdr[k].rw_attribs = phg->entry[j].rw_attribs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)                     ha->hdr[k].start_sec = phg->entry[j].start_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)                 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)             }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 	dma_free_coherent(&ha->pdev->dev, size, buf, paddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)         for (i = 0; i < MAX_HDRIVES; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)             if (!(ha->hdr[i].present))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)                 continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)               
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)             seq_printf(m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)                            "\n Number:       \t%-2d        \tArr/Log. Drive:\t%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)                            i, ha->hdr[i].ldr_no);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)             flag = TRUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)             seq_printf(m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)                            " Capacity [MB]:\t%-6d    \tStart Sector:  \t%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)                            (u32)(ha->hdr[i].size/2048), ha->hdr[i].start_sec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)         
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)         if (!flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524)             seq_puts(m, "\n --\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)     /* controller events */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528)     seq_puts(m, "\nController Events:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)     for (id = -1;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)         id = gdth_read_event(ha, id, estr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)         if (estr->event_source == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)             break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)         if (estr->event_data.eu.driver.ionode == ha->hanum &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)             estr->event_source == ES_ASYNC) { 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)             gdth_log_event(&estr->event_data, hrec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 	    /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 	     * Elapsed seconds subtraction with unsigned operands is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 	     * safe from wrap around in year 2106.  Executes as:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 	     * operand a + (2's complement operand b) + 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 	     */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 	    sec = (int)((u32)ktime_get_real_seconds() - estr->first_stamp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545)             if (sec < 0) sec = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)             seq_printf(m," date- %02d:%02d:%02d\t%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)                            sec/3600, sec%3600/60, sec%60, hrec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)         if (id == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550)             break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) stop_output:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)     rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) free_fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)     kfree(gdtcmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)     kfree(estr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)     return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) static void gdth_wait_completion(gdth_ha_str *ha, int busnum, int id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)     unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)     int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)     struct scsi_cmnd *scp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)     struct gdth_cmndinfo *cmndinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)     u8 b, t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)     spin_lock_irqsave(&ha->smp_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)     for (i = 0; i < GDTH_MAXCMDS; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)         scp = ha->cmd_tab[i].cmnd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572)         cmndinfo = gdth_cmnd_priv(scp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)         b = scp->device->channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)         t = scp->device->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576)         if (!SPECIAL_SCP(scp) && t == (u8)id && 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)             b == (u8)busnum) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)             cmndinfo->wait_for_completion = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579)             spin_unlock_irqrestore(&ha->smp_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)             while (!cmndinfo->wait_for_completion)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)                 barrier();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)             spin_lock_irqsave(&ha->smp_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)     spin_unlock_irqrestore(&ha->smp_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) }