Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
56660d5e
Commit
56660d5e
authored
Jan 19, 2004
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Plain Diff
Merge
bk://linux-scsi.bkbits.net/scsi-for-linus-2.6
into home.osdl.org:/home/torvalds/v2.5/linux
parents
dfb754ee
6c4b9b99
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
134 additions
and
79 deletions
+134
-79
drivers/message/fusion/mptbase.h
drivers/message/fusion/mptbase.h
+2
-2
drivers/message/fusion/mptscsih.c
drivers/message/fusion/mptscsih.c
+3
-1
drivers/scsi/aha152x.c
drivers/scsi/aha152x.c
+2
-0
drivers/scsi/qla1280.c
drivers/scsi/qla1280.c
+89
-44
drivers/scsi/qla1280.h
drivers/scsi/qla1280.h
+13
-10
drivers/scsi/qla2xxx/qla_def.h
drivers/scsi/qla2xxx/qla_def.h
+3
-3
drivers/scsi/qla2xxx/qla_init.c
drivers/scsi/qla2xxx/qla_init.c
+2
-0
drivers/scsi/scsi_error.c
drivers/scsi/scsi_error.c
+13
-15
drivers/scsi/scsi_sysfs.c
drivers/scsi/scsi_sysfs.c
+7
-4
No files found.
drivers/message/fusion/mptbase.h
View file @
56660d5e
...
...
@@ -80,8 +80,8 @@
#define COPYRIGHT "Copyright (c) 1999-2003 " MODULEAUTHOR
#endif
#define MPT_LINUX_VERSION_COMMON "2.05.00.0
5
"
#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-2.05.00.0
5
"
#define MPT_LINUX_VERSION_COMMON "2.05.00.0
6
"
#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-2.05.00.0
6
"
#define WHAT_MAGIC_STRING "@" "(" "#" ")"
#define show_mptmod_ver(s,ver) \
...
...
drivers/message/fusion/mptscsih.c
View file @
56660d5e
...
...
@@ -1231,7 +1231,9 @@ mptscsih_initChainBuffers (MPT_SCSI_HOST *hd, int init)
}
else
{
mem
=
(
u8
*
)
hd
->
ReqToChain
;
}
memset
(
mem
,
0xFF
,
sz
);
/* memset(mem, 0xFF, sz); */
for
(
ii
=
0
;
ii
<
hd
->
ioc
->
req_depth
;
ii
++
)
hd
->
ReqToChain
[
ii
]
=
MPT_HOST_NO_CHAIN
;
/* ChainToChain size must equal the total number
...
...
drivers/scsi/aha152x.c
View file @
56660d5e
...
...
@@ -3914,5 +3914,7 @@ static Scsi_Host_Template aha152x_driver_template = {
.
use_clustering
=
DISABLE_CLUSTERING
,
};
#ifndef PCMCIA
module_init
(
aha152x_init
);
module_exit
(
aha152x_exit
);
#endif
drivers/scsi/qla1280.c
View file @
56660d5e
...
...
@@ -17,9 +17,16 @@
* General Public License for more details.
*
******************************************************************************/
#define QLA1280_VERSION "3.24.
1
"
#define QLA1280_VERSION "3.24.
3
"
/*****************************************************************************
Revision History:
Rev 3.24.3 January 19, 2004, Jes Sorensen
- Handle PCI DMA mask settings correctly
- Correct order of error handling in probe_one, free_irq should not
be called if request_irq failed
Rev 3.24.2 January 19, 2004, James Bottomley & Andrew Vasquez
- Big endian fixes (James)
- Remove bogus IOCB content on zero data transfer commands (Andrew)
Rev 3.24.1 January 5, 2004, Jes Sorensen
- Initialize completion queue to avoid OOPS on probe
- Handle interrupts during mailbox testing
...
...
@@ -507,8 +514,11 @@ static int qla1280_device_reset(struct scsi_qla_host *, int, int);
static
int
qla1280_abort_device
(
struct
scsi_qla_host
*
,
int
,
int
,
int
);
static
int
qla1280_abort_command
(
struct
scsi_qla_host
*
,
struct
srb
*
,
int
);
static
int
qla1280_abort_isp
(
struct
scsi_qla_host
*
);
#ifdef QLA_64BIT_PTR
static
int
qla1280_64bit_start_scsi
(
struct
scsi_qla_host
*
,
struct
srb
*
);
#else
static
int
qla1280_32bit_start_scsi
(
struct
scsi_qla_host
*
,
struct
srb
*
);
#endif
static
void
qla1280_nv_write
(
struct
scsi_qla_host
*
,
uint16_t
);
static
void
qla1280_poll
(
struct
scsi_qla_host
*
);
static
void
qla1280_reset_adapter
(
struct
scsi_qla_host
*
);
...
...
@@ -765,7 +775,7 @@ static int qla1280_read_nvram(struct scsi_qla_host *ha)
{
uint16_t
*
wptr
;
uint8_t
chksum
;
int
cnt
;
int
cnt
,
i
;
struct
nvram
*
nv
;
ENTER
(
"qla1280_read_nvram"
);
...
...
@@ -812,6 +822,28 @@ static int qla1280_read_nvram(struct scsi_qla_host *ha)
}
else
ha
->
nvram_valid
=
1
;
/* The firmware interface is, um, interesting, in that the
* actual firmware image on the chip is little endian, thus,
* the process of taking that image to the CPU would end up
* little endian. However, the firmare interface requires it
* to be read a word (two bytes) at a time.
*
* The net result of this would be that the word (and
* doubleword) quantites in the firmware would be correct, but
* the bytes would be pairwise reversed. Since most of the
* firmware quantites are, in fact, bytes, we do an extra
* le16_to_cpu() in the firmware read routine.
*
* The upshot of all this is that the bytes in the firmware
* are in the correct places, but the 16 and 32 bit quantites
* are still in little endian format. We fix that up below by
* doing extra reverses on them */
nv
->
isp_parameter
=
cpu_to_le16
(
nv
->
isp_parameter
);
nv
->
firmware_feature
.
w
=
cpu_to_le16
(
nv
->
firmware_feature
.
w
);
for
(
i
=
0
;
i
<
MAX_BUSES
;
i
++
)
{
nv
->
bus
[
i
].
selection_timeout
=
cpu_to_le16
(
nv
->
bus
[
i
].
selection_timeout
);
nv
->
bus
[
i
].
max_queue_depth
=
cpu_to_le16
(
nv
->
bus
[
i
].
max_queue_depth
);
}
dprintk
(
1
,
"qla1280_read_nvram: Completed Reading NVRAM
\n
"
);
LEAVE
(
"qla1280_read_nvram"
);
...
...
@@ -860,6 +892,7 @@ qla1280_queuecommand(struct scsi_cmnd *cmd, void (*fn)(struct scsi_cmnd *))
struct
Scsi_Host
*
host
=
cmd
->
device
->
host
;
struct
scsi_qla_host
*
ha
=
(
struct
scsi_qla_host
*
)
host
->
hostdata
;
struct
srb
*
sp
=
(
struct
srb
*
)
&
cmd
->
SCp
;
int
status
;
cmd
->
scsi_done
=
fn
;
sp
->
cmd
=
cmd
;
...
...
@@ -867,9 +900,18 @@ qla1280_queuecommand(struct scsi_cmnd *cmd, void (*fn)(struct scsi_cmnd *))
qla1280_print_scsi_cmd
(
5
,
cmd
);
if
(
ha
->
flags
.
enable_64bit_addressing
)
return
qla1280_64bit_start_scsi
(
ha
,
sp
);
return
qla1280_32bit_start_scsi
(
ha
,
sp
);
#ifdef QLA_64BIT_PTR
/*
* Using 64 bit commands if the PCI bridge doesn't support it is a
* bit wasteful, however this should really only happen if one's
* PCI controller is completely broken, like the BCM1250. For
* sane hardware this is not an issue.
*/
status
=
qla1280_64bit_start_scsi
(
ha
,
sp
);
#else
status
=
qla1280_32bit_start_scsi
(
ha
,
sp
);
#endif
return
status
;
}
enum
action
{
...
...
@@ -1558,6 +1600,10 @@ static int
qla1280_return_status
(
struct
response
*
sts
,
struct
scsi_cmnd
*
cp
)
{
int
host_status
=
DID_ERROR
;
uint16_t
comp_status
=
le16_to_cpu
(
sts
->
comp_status
);
uint16_t
state_flags
=
le16_to_cpu
(
sts
->
state_flags
);
uint16_t
residual_length
=
le16_to_cpu
(
sts
->
residual_length
);
uint16_t
scsi_status
=
le16_to_cpu
(
sts
->
scsi_status
);
#if DEBUG_QLA1280_INTR
static
char
*
reason
[]
=
{
"DID_OK"
,
...
...
@@ -1578,26 +1624,27 @@ qla1280_return_status(struct response * sts, struct scsi_cmnd *cp)
#if DEBUG_QLA1280_INTR
/*
dprintk(1, "qla1280_return_status: compl status = 0x%04x\n",
sts->
comp_status);
comp_status);
*/
#endif
switch
(
sts
->
comp_status
)
{
switch
(
comp_status
)
{
case
CS_COMPLETE
:
host_status
=
DID_OK
;
break
;
case
CS_INCOMPLETE
:
if
(
!
(
st
s
->
st
ate_flags
&
SF_GOT_BUS
))
if
(
!
(
state_flags
&
SF_GOT_BUS
))
host_status
=
DID_NO_CONNECT
;
else
if
(
!
(
st
s
->
st
ate_flags
&
SF_GOT_TARGET
))
else
if
(
!
(
state_flags
&
SF_GOT_TARGET
))
host_status
=
DID_BAD_TARGET
;
else
if
(
!
(
st
s
->
st
ate_flags
&
SF_SENT_CDB
))
else
if
(
!
(
state_flags
&
SF_SENT_CDB
))
host_status
=
DID_ERROR
;
else
if
(
!
(
st
s
->
st
ate_flags
&
SF_TRANSFERRED_DATA
))
else
if
(
!
(
state_flags
&
SF_TRANSFERRED_DATA
))
host_status
=
DID_ERROR
;
else
if
(
!
(
st
s
->
st
ate_flags
&
SF_GOT_STATUS
))
else
if
(
!
(
state_flags
&
SF_GOT_STATUS
))
host_status
=
DID_ERROR
;
else
if
(
!
(
st
s
->
st
ate_flags
&
SF_GOT_SENSE
))
else
if
(
!
(
state_flags
&
SF_GOT_SENSE
))
host_status
=
DID_ERROR
;
break
;
...
...
@@ -1614,14 +1661,14 @@ qla1280_return_status(struct response * sts, struct scsi_cmnd *cp)
break
;
case
CS_DATA_OVERRUN
:
dprintk
(
2
,
"Data overrun 0x%x
\n
"
,
sts
->
residual_length
);
dprintk
(
2
,
"Data overrun 0x%x
\n
"
,
residual_length
);
dprintk
(
2
,
"qla1280_isr: response packet data
\n
"
);
qla1280_dump_buffer
(
2
,
(
char
*
)
sts
,
RESPONSE_ENTRY_SIZE
);
host_status
=
DID_ERROR
;
break
;
case
CS_DATA_UNDERRUN
:
if
((
cp
->
request_bufflen
-
sts
->
residual_length
)
<
if
((
cp
->
request_bufflen
-
residual_length
)
<
cp
->
underflow
)
{
printk
(
KERN_WARNING
"scsi: Underflow detected - retrying "
...
...
@@ -1638,12 +1685,12 @@ qla1280_return_status(struct response * sts, struct scsi_cmnd *cp)
#if DEBUG_QLA1280_INTR
dprintk
(
1
,
"qla1280 ISP status: host status (%s) scsi status %x
\n
"
,
reason
[
host_status
],
s
ts
->
s
csi_status
);
reason
[
host_status
],
scsi_status
);
#endif
LEAVE
(
"qla1280_return_status"
);
return
(
s
ts
->
s
csi_status
&
0xff
)
|
(
host_status
<<
16
);
return
(
scsi_status
&
0xff
)
|
(
host_status
<<
16
);
}
/****************************************************************************/
...
...
@@ -2394,23 +2441,6 @@ qla1280_nvram_config(struct scsi_qla_host *ha)
ha
->
flags
.
disable_risc_code_load
=
nv
->
cntr_flags_1
.
disable_loading_risc_code
;
#ifdef QLA_64BIT_PTR
/* Enable 64bit addressing for OS/System combination supporting it */
/* actual NVRAM bit is: nv->cntr_flags_1.enable_64bit_addressing */
/* but we will ignore it and use BITS_PER_LONG macro to setup for */
/* 64 or 32 bit access of host memory in all x86/ia-64/Alpha systems */
ha
->
flags
.
enable_64bit_addressing
=
1
;
#else
ha
->
flags
.
enable_64bit_addressing
=
0
;
#endif
if
(
ha
->
flags
.
enable_64bit_addressing
)
{
dprintk
(
2
,
"scsi(%li): 64 Bit PCI Addressing Enabled
\n
"
,
ha
->
host_no
);
pci_set_dma_mask
(
ha
->
pdev
,
(
dma_addr_t
)
~
0ULL
);
}
/* Set ISP hardware DMA burst */
mb
[
0
]
=
nv
->
isp_config
.
c
;
/* Enable DMA arbitration on dual channel controllers */
...
...
@@ -3315,7 +3345,7 @@ qla1280_64bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
#endif
*
dword_ptr
++
=
cpu_to_le32
(
pci_dma_lo32
(
dma_handle
));
*
dword_ptr
++
=
cpu_to_le32
(
pci_dma_hi32
(
dma_handle
));
*
dword_ptr
=
(
uint32_t
)
cmd
->
request_bufflen
;
*
dword_ptr
=
cpu_to_le32
(
cmd
->
request_bufflen
)
;
dprintk
(
5
,
"qla1280_64bit_start_scsi: No scatter/"
"gather command packet data - b %i, t %i, "
...
...
@@ -3325,10 +3355,6 @@ qla1280_64bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
REQUEST_ENTRY_SIZE
);
}
}
else
{
/* No data transfer */
dword_ptr
=
(
uint32_t
*
)(
pkt
+
1
);
*
dword_ptr
++
=
0
;
*
dword_ptr
++
=
0
;
*
dword_ptr
=
0
;
dprintk
(
5
,
"qla1280_64bit_start_scsi: No data, command "
"packet data - b %i, t %i, l %i
\n
"
,
SCSI_BUS_32
(
cmd
),
SCSI_TCN_32
(
cmd
),
SCSI_LUN_32
(
cmd
));
...
...
@@ -3359,6 +3385,7 @@ qla1280_64bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
}
#ifndef QLA_64BIT_PTR
/*
* qla1280_32bit_start_scsi
* The start SCSI is responsible for building request packets on
...
...
@@ -3593,9 +3620,6 @@ qla1280_32bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
*
dword_ptr
=
cpu_to_le32
(
cmd
->
request_bufflen
);
}
}
else
{
/* No data transfer at all */
dword_ptr
=
(
uint32_t
*
)(
pkt
+
1
);
*
dword_ptr
++
=
0
;
*
dword_ptr
=
0
;
dprintk
(
5
,
"qla1280_32bit_start_scsi: No data, command "
"packet data -
\n
"
);
qla1280_dump_buffer
(
5
,
(
char
*
)
pkt
,
REQUEST_ENTRY_SIZE
);
...
...
@@ -3627,6 +3651,7 @@ qla1280_32bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
return
status
;
}
#endif
/*
* qla1280_req_pkt
...
...
@@ -4686,6 +4711,26 @@ qla1280_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
ha
->
pdev
=
pdev
;
ha
->
devnum
=
devnum
;
/* specifies microcode load address */
#ifdef QLA_64BIT_PTR
if
(
pci_set_dma_mask
(
ha
->
pdev
,
(
dma_addr_t
)
~
0ULL
))
{
if
(
pci_set_dma_mask
(
ha
->
pdev
,
0xffffffff
))
{
printk
(
KERN_WARNING
"scsi(%li): Unable to set a "
" suitable DMA mask - aboring
\n
"
,
ha
->
host_no
);
error
=
-
ENODEV
;
goto
error_free_irq
;
}
}
else
dprintk
(
2
,
"scsi(%li): 64 Bit PCI Addressing Enabled
\n
"
,
ha
->
host_no
);
#else
if
(
pci_set_dma_mask
(
ha
->
pdev
,
0xffffffff
))
{
printk
(
KERN_WARNING
"scsi(%li): Unable to set a "
" suitable DMA mask - aboring
\n
"
,
ha
->
host_no
);
error
=
-
ENODEV
;
goto
error_free_irq
;
}
#endif
ha
->
request_ring
=
pci_alloc_consistent
(
ha
->
pdev
,
((
REQUEST_ENTRY_CNT
+
1
)
*
(
sizeof
(
request_t
))),
&
ha
->
request_dma
);
...
...
@@ -4780,14 +4825,14 @@ qla1280_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
error_disable_adapter:
WRT_REG_WORD
(
&
ha
->
iobase
->
ictrl
,
0
);
#endif
error_free_irq:
free_irq
(
pdev
->
irq
,
ha
);
error_release_region:
#if MEMORY_MAPPED_IO
iounmap
(
ha
->
mmpbase
);
#else
release_region
(
host
->
io_port
,
0xff
);
#endif
error_free_irq:
free_irq
(
pdev
->
irq
,
ha
);
error_free_response_ring:
pci_free_consistent
(
ha
->
pdev
,
((
RESPONSE_ENTRY_CNT
+
1
)
*
(
sizeof
(
struct
response
))),
...
...
drivers/scsi/qla1280.h
View file @
56660d5e
...
...
@@ -309,16 +309,19 @@ struct nvram {
}
cntr_flags_1
;
/* 5 */
struct
{
uint16_t
boot_lun_number
:
5
;
uint16_t
scsi_bus_number
:
1
;
uint16_t
unused_6
:
1
;
uint16_t
unused_7
:
1
;
uint16_t
boot_target_number
:
4
;
uint16_t
unused_12
:
1
;
uint16_t
unused_13
:
1
;
uint16_t
unused_14
:
1
;
uint16_t
unused_15
:
1
;
}
cntr_flags_2
;
/* 6, 7 */
uint8_t
boot_lun_number
:
5
;
uint8_t
scsi_bus_number
:
1
;
uint8_t
unused_6
:
1
;
uint8_t
unused_7
:
1
;
}
cntr_flags_2l
;
/* 7 */
struct
{
uint8_t
boot_target_number
:
4
;
uint8_t
unused_12
:
1
;
uint8_t
unused_13
:
1
;
uint8_t
unused_14
:
1
;
uint8_t
unused_15
:
1
;
}
cntr_flags_2h
;
/* 8 */
uint16_t
unused_8
;
/* 8, 9 */
uint16_t
unused_10
;
/* 10, 11 */
...
...
drivers/scsi/qla2xxx/qla_def.h
View file @
56660d5e
...
...
@@ -1135,8 +1135,8 @@ typedef union {
uint16_t
extended
;
struct
{
uint8_t
reserved
;
uint8_t
standard
;
;
};
uint8_t
standard
;
}
id
;
}
target_id_t
;
#define SET_TARGET_ID(ha, to, from) \
...
...
@@ -1144,7 +1144,7 @@ do { \
if (HAS_EXTENDED_IDS(ha)) \
to.extended = cpu_to_le16(from); \
else \
to.standard = (uint8_t)from; \
to.
id.
standard = (uint8_t)from; \
} while (0)
/*
...
...
drivers/scsi/qla2xxx/qla_init.c
View file @
56660d5e
...
...
@@ -1592,6 +1592,8 @@ qla2x00_configure_loop(scsi_qla_host_t *ha)
if
(
!
atomic_read
(
&
ha
->
loop_down_timer
)
&&
!
(
test_bit
(
LOOP_RESYNC_NEEDED
,
&
ha
->
dpc_flags
)))
{
qla2x00_config_os
(
ha
);
/* If we found all devices then go ready */
if
(
!
(
test_bit
(
LOGIN_RETRY_NEEDED
,
&
ha
->
dpc_flags
)))
{
atomic_set
(
&
ha
->
loop_state
,
LOOP_READY
);
...
...
drivers/scsi/scsi_error.c
View file @
56660d5e
...
...
@@ -1420,23 +1420,21 @@ static void scsi_eh_flush_done_q(struct list_head *done_q)
list_for_each_safe
(
lh
,
lh_sf
,
done_q
)
{
scmd
=
list_entry
(
lh
,
struct
scsi_cmnd
,
eh_entry
);
list_del_init
(
lh
);
if
(
!
scmd
->
device
->
online
)
{
scmd
->
result
|=
(
DRIVER_TIMEOUT
<<
24
);
}
else
{
if
(
++
scmd
->
retries
<
scmd
->
allowed
)
{
SCSI_LOG_ERROR_RECOVERY
(
3
,
printk
(
"%s: flush retry"
" cmd: %p
\n
"
,
current
->
comm
,
scmd
));
if
(
scmd
->
device
->
online
&&
(
++
scmd
->
retries
<
scmd
->
allowed
))
{
SCSI_LOG_ERROR_RECOVERY
(
3
,
printk
(
"%s: flush"
" retry cmd: %p
\n
"
,
current
->
comm
,
scmd
));
scsi_queue_insert
(
scmd
,
SCSI_MLQUEUE_EH_RETRY
);
continue
;
}
}
else
{
if
(
!
scmd
->
result
)
scmd
->
result
|=
(
DRIVER_TIMEOUT
<<
24
);
SCSI_LOG_ERROR_RECOVERY
(
3
,
printk
(
"%s: flush finish"
" cmd: %p
\n
"
,
current
->
comm
,
scmd
));
scsi_finish_command
(
scmd
);
}
SCSI_LOG_ERROR_RECOVERY
(
3
,
printk
(
"%s: flush finish"
" cmd: %p
\n
"
,
current
->
comm
,
scmd
));
scsi_finish_command
(
scmd
);
}
}
...
...
drivers/scsi/scsi_sysfs.c
View file @
56660d5e
...
...
@@ -361,7 +361,6 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev)
if
(
error
)
{
printk
(
KERN_INFO
"error 2
\n
"
);
goto
clean_device
;
return
error
;
}
get_device
(
&
sdev
->
sdev_gendev
);
...
...
@@ -370,8 +369,10 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev)
for
(
i
=
0
;
sdev
->
host
->
hostt
->
sdev_attrs
[
i
];
i
++
)
{
error
=
attr_add
(
&
sdev
->
sdev_gendev
,
sdev
->
host
->
hostt
->
sdev_attrs
[
i
]);
if
(
error
)
if
(
error
)
{
scsi_remove_device
(
sdev
);
goto
out
;
}
}
}
...
...
@@ -380,11 +381,14 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev)
scsi_sysfs_sdev_attrs
[
i
]))
{
error
=
device_create_file
(
&
sdev
->
sdev_gendev
,
scsi_sysfs_sdev_attrs
[
i
]);
if
(
error
)
if
(
error
)
{
scsi_remove_device
(
sdev
);
goto
out
;
}
}
}
out:
return
error
;
clean_device:
...
...
@@ -394,7 +398,6 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev)
put_device
(
&
sdev
->
sdev_gendev
);
return
error
;
}
/**
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment