Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
linux-davinci
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
linux
linux-davinci
Commits
9636273d
Commit
9636273d
authored
May 20, 2005
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Plain Diff
Automatic merge of
rsync://www.parisc-linux.org/~jejb/git/scsi-for-linus-2.6.git
parents
2df9fa36
2bf2c568
Changes
8
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
530 additions
and
1310 deletions
+530
-1310
drivers/scsi/aic7xxx/aic7770_osm.c
drivers/scsi/aic7xxx/aic7770_osm.c
+1
-51
drivers/scsi/aic7xxx/aic7xxx_osm.c
drivers/scsi/aic7xxx/aic7xxx_osm.c
+336
-1064
drivers/scsi/aic7xxx/aic7xxx_osm.h
drivers/scsi/aic7xxx/aic7xxx_osm.h
+25
-144
drivers/scsi/aic7xxx/aic7xxx_osm_pci.c
drivers/scsi/aic7xxx/aic7xxx_osm_pci.c
+1
-10
drivers/scsi/aic7xxx/aic7xxx_proc.c
drivers/scsi/aic7xxx/aic7xxx_proc.c
+0
-13
drivers/scsi/aic7xxx/aiclib.c
drivers/scsi/aic7xxx/aiclib.c
+0
-1
drivers/scsi/scsi_transport_spi.c
drivers/scsi/scsi_transport_spi.c
+161
-27
include/scsi/scsi_transport_spi.h
include/scsi/scsi_transport_spi.h
+6
-0
No files found.
drivers/scsi/aic7xxx/aic7770_osm.c
View file @
9636273d
...
...
@@ -41,7 +41,6 @@
#include "aic7xxx_osm.h"
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
#include <linux/device.h>
#include <linux/eisa.h>
...
...
@@ -62,13 +61,6 @@ static struct eisa_driver aic7770_driver = {
};
typedef
struct
device
*
aic7770_dev_t
;
#else
#define MINSLOT 1
#define NUMSLOTS 16
#define IDOFFSET 0x80
typedef
void
*
aic7770_dev_t
;
#endif
static
int
aic7770_linux_config
(
struct
aic7770_identity
*
entry
,
aic7770_dev_t
dev
,
u_int
eisaBase
);
...
...
@@ -76,7 +68,6 @@ static int aic7770_linux_config(struct aic7770_identity *entry,
int
ahc_linux_eisa_init
(
void
)
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
struct
eisa_device_id
*
eid
;
struct
aic7770_identity
*
id
;
int
i
;
...
...
@@ -110,44 +101,6 @@ ahc_linux_eisa_init(void)
eid
->
sig
[
0
]
=
0
;
return
eisa_driver_register
(
&
aic7770_driver
);
#else
/* LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) */
struct
aic7770_identity
*
entry
;
u_int
slot
;
u_int
eisaBase
;
u_int
i
;
int
ret
=
-
ENODEV
;
if
(
aic7xxx_probe_eisa_vl
==
0
)
return
ret
;
eisaBase
=
0x1000
+
AHC_EISA_SLOT_OFFSET
;
for
(
slot
=
1
;
slot
<
NUMSLOTS
;
eisaBase
+=
0x1000
,
slot
++
)
{
uint32_t
eisa_id
;
size_t
id_size
;
if
(
request_region
(
eisaBase
,
AHC_EISA_IOSIZE
,
"aic7xxx"
)
==
0
)
continue
;
eisa_id
=
0
;
id_size
=
sizeof
(
eisa_id
);
for
(
i
=
0
;
i
<
4
;
i
++
)
{
/* VLcards require priming*/
outb
(
0x80
+
i
,
eisaBase
+
IDOFFSET
);
eisa_id
|=
inb
(
eisaBase
+
IDOFFSET
+
i
)
<<
((
id_size
-
i
-
1
)
*
8
);
}
release_region
(
eisaBase
,
AHC_EISA_IOSIZE
);
if
(
eisa_id
&
0x80000000
)
continue
;
/* no EISA card in slot */
entry
=
aic7770_find_device
(
eisa_id
);
if
(
entry
!=
NULL
)
{
aic7770_linux_config
(
entry
,
NULL
,
eisaBase
);
ret
=
0
;
}
}
return
ret
;
#endif
}
void
...
...
@@ -187,11 +140,10 @@ aic7770_linux_config(struct aic7770_identity *entry, aic7770_dev_t dev,
ahc_free
(
ahc
);
return
(
error
);
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
dev
->
driver_data
=
(
void
*
)
ahc
;
if
(
aic7xxx_detect_complete
)
error
=
ahc_linux_register_host
(
ahc
,
&
aic7xxx_driver_template
);
#endif
return
(
error
);
}
...
...
@@ -225,7 +177,6 @@ aic7770_map_int(struct ahc_softc *ahc, u_int irq)
return
(
-
error
);
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
static
int
aic7770_eisa_dev_probe
(
struct
device
*
dev
)
{
...
...
@@ -261,4 +212,3 @@ aic7770_eisa_dev_remove(struct device *dev)
return
(
0
);
}
#endif
drivers/scsi/aic7xxx/aic7xxx_osm.c
View file @
9636273d
This diff is collapsed.
Click to expand it.
drivers/scsi/aic7xxx/aic7xxx_osm.h
View file @
9636273d
This diff is collapsed.
Click to expand it.
drivers/scsi/aic7xxx/aic7xxx_osm_pci.c
View file @
9636273d
...
...
@@ -221,13 +221,11 @@ ahc_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
&&
ahc_linux_get_memsize
()
>
0x80000000
&&
pci_set_dma_mask
(
pdev
,
mask_39bit
)
==
0
)
{
ahc
->
flags
|=
AHC_39BIT_ADDRESSING
;
ahc
->
platform_data
->
hw_dma_mask
=
mask_39bit
;
}
else
{
if
(
pci_set_dma_mask
(
pdev
,
DMA_32BIT_MASK
))
{
printk
(
KERN_WARNING
"aic7xxx: No suitable DMA available.
\n
"
);
return
(
-
ENODEV
);
}
ahc
->
platform_data
->
hw_dma_mask
=
DMA_32BIT_MASK
;
}
ahc
->
dev_softc
=
pci
;
error
=
ahc_pci_config
(
ahc
,
entry
);
...
...
@@ -236,15 +234,8 @@ ahc_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
return
(
-
error
);
}
pci_set_drvdata
(
pdev
,
ahc
);
if
(
aic7xxx_detect_complete
)
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
if
(
aic7xxx_detect_complete
)
ahc_linux_register_host
(
ahc
,
&
aic7xxx_driver_template
);
#else
printf
(
"aic7xxx: ignoring PCI device found after "
"initialization
\n
"
);
return
(
-
ENODEV
);
#endif
}
return
(
0
);
}
...
...
drivers/scsi/aic7xxx/aic7xxx_proc.c
View file @
9636273d
...
...
@@ -289,13 +289,8 @@ done:
* Return information to handle /proc support for the driver.
*/
int
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
ahc_linux_proc_info
(
char
*
buffer
,
char
**
start
,
off_t
offset
,
int
length
,
int
hostno
,
int
inout
)
#else
ahc_linux_proc_info
(
struct
Scsi_Host
*
shost
,
char
*
buffer
,
char
**
start
,
off_t
offset
,
int
length
,
int
inout
)
#endif
{
struct
ahc_softc
*
ahc
;
struct
info_str
info
;
...
...
@@ -307,15 +302,7 @@ ahc_linux_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
retval
=
-
EINVAL
;
ahc_list_lock
(
&
s
);
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
TAILQ_FOREACH
(
ahc
,
&
ahc_tailq
,
links
)
{
if
(
ahc
->
platform_data
->
host
->
host_no
==
hostno
)
break
;
}
#else
ahc
=
ahc_find_softc
(
*
(
struct
ahc_softc
**
)
shost
->
hostdata
);
#endif
if
(
ahc
==
NULL
)
goto
done
;
...
...
drivers/scsi/aic7xxx/aiclib.c
View file @
9636273d
...
...
@@ -35,7 +35,6 @@
#include <linux/version.h>
/* Core SCSI definitions */
#include "scsi.h"
#include <scsi/scsi_host.h>
#include "aiclib.h"
#include "cam.h"
...
...
drivers/scsi/scsi_transport_spi.c
View file @
9636273d
...
...
@@ -35,7 +35,7 @@
#define SPI_PRINTK(x, l, f, a...) dev_printk(l, &(x)->dev, f , ##a)
#define SPI_NUM_ATTRS 1
0
/* increase this if you add attributes */
#define SPI_NUM_ATTRS 1
3
/* increase this if you add attributes */
#define SPI_OTHER_ATTRS 1
/* Increase this if you add "always
* on" attributes */
#define SPI_HOST_ATTRS 1
...
...
@@ -219,8 +219,11 @@ static int spi_setup_transport_attrs(struct device *dev)
struct
scsi_target
*
starget
=
to_scsi_target
(
dev
);
spi_period
(
starget
)
=
-
1
;
/* illegal value */
spi_min_period
(
starget
)
=
0
;
spi_offset
(
starget
)
=
0
;
/* async */
spi_max_offset
(
starget
)
=
255
;
spi_width
(
starget
)
=
0
;
/* narrow */
spi_max_width
(
starget
)
=
1
;
spi_iu
(
starget
)
=
0
;
/* no IU */
spi_dt
(
starget
)
=
0
;
/* ST */
spi_qas
(
starget
)
=
0
;
...
...
@@ -235,6 +238,34 @@ static int spi_setup_transport_attrs(struct device *dev)
return
0
;
}
#define spi_transport_show_simple(field, format_string) \
\
static ssize_t \
show_spi_transport_##field(struct class_device *cdev, char *buf) \
{ \
struct scsi_target *starget = transport_class_to_starget(cdev); \
struct spi_transport_attrs *tp; \
\
tp = (struct spi_transport_attrs *)&starget->starget_data; \
return snprintf(buf, 20, format_string, tp->field); \
}
#define spi_transport_store_simple(field, format_string) \
\
static ssize_t \
store_spi_transport_##field(struct class_device *cdev, const char *buf, \
size_t count) \
{ \
int val; \
struct scsi_target *starget = transport_class_to_starget(cdev); \
struct spi_transport_attrs *tp; \
\
tp = (struct spi_transport_attrs *)&starget->starget_data; \
val = simple_strtoul(buf, NULL, 0); \
tp->field = val; \
return count; \
}
#define spi_transport_show_function(field, format_string) \
\
static ssize_t \
...
...
@@ -265,6 +296,25 @@ store_spi_transport_##field(struct class_device *cdev, const char *buf, \
return count; \
}
#define spi_transport_store_max(field, format_string) \
static ssize_t \
store_spi_transport_##field(struct class_device *cdev, const char *buf, \
size_t count) \
{ \
int val; \
struct scsi_target *starget = transport_class_to_starget(cdev); \
struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); \
struct spi_internal *i = to_spi_internal(shost->transportt); \
struct spi_transport_attrs *tp \
= (struct spi_transport_attrs *)&starget->starget_data; \
\
val = simple_strtoul(buf, NULL, 0); \
if (val > tp->max_##field) \
val = tp->max_##field; \
i->f->set_##field(starget, val); \
return count; \
}
#define spi_transport_rd_attr(field, format_string) \
spi_transport_show_function(field, format_string) \
spi_transport_store_function(field, format_string) \
...
...
@@ -272,9 +322,24 @@ static CLASS_DEVICE_ATTR(field, S_IRUGO | S_IWUSR, \
show_spi_transport_##field, \
store_spi_transport_##field);
#define spi_transport_simple_attr(field, format_string) \
spi_transport_show_simple(field, format_string) \
spi_transport_store_simple(field, format_string) \
static CLASS_DEVICE_ATTR(field, S_IRUGO | S_IWUSR, \
show_spi_transport_##field, \
store_spi_transport_##field);
#define spi_transport_max_attr(field, format_string) \
spi_transport_show_function(field, format_string) \
spi_transport_store_max(field, format_string) \
spi_transport_simple_attr(max_##field, format_string) \
static CLASS_DEVICE_ATTR(field, S_IRUGO | S_IWUSR, \
show_spi_transport_##field, \
store_spi_transport_##field);
/* The Parallel SCSI Tranport Attributes: */
spi_transport_
rd
_attr
(
offset
,
"%d
\n
"
);
spi_transport_
rd
_attr
(
width
,
"%d
\n
"
);
spi_transport_
max
_attr
(
offset
,
"%d
\n
"
);
spi_transport_
max
_attr
(
width
,
"%d
\n
"
);
spi_transport_rd_attr
(
iu
,
"%d
\n
"
);
spi_transport_rd_attr
(
dt
,
"%d
\n
"
);
spi_transport_rd_attr
(
qas
,
"%d
\n
"
);
...
...
@@ -300,26 +365,18 @@ static CLASS_DEVICE_ATTR(revalidate, S_IWUSR, NULL, store_spi_revalidate);
/* Translate the period into ns according to the current spec
* for SDTR/PPR messages */
static
ssize_t
show_spi_transport_period
(
struct
class_device
*
cdev
,
char
*
buf
)
static
ssize_t
show_spi_transport_period_helper
(
struct
class_device
*
cdev
,
char
*
buf
,
int
period
)
{
struct
scsi_target
*
starget
=
transport_class_to_starget
(
cdev
);
struct
Scsi_Host
*
shost
=
dev_to_shost
(
starget
->
dev
.
parent
);
struct
spi_transport_attrs
*
tp
;
int
len
,
picosec
;
struct
spi_internal
*
i
=
to_spi_internal
(
shost
->
transportt
);
tp
=
(
struct
spi_transport_attrs
*
)
&
starget
->
starget_data
;
if
(
i
->
f
->
get_period
)
i
->
f
->
get_period
(
starget
);
if
(
tp
->
period
<
0
||
tp
->
period
>
0xff
)
{
if
(
period
<
0
||
period
>
0xff
)
{
picosec
=
-
1
;
}
else
if
(
tp
->
period
<=
SPI_STATIC_PPR
)
{
picosec
=
ppr_to_ps
[
tp
->
period
];
}
else
if
(
period
<=
SPI_STATIC_PPR
)
{
picosec
=
ppr_to_ps
[
period
];
}
else
{
picosec
=
tp
->
period
*
4000
;
picosec
=
period
*
4000
;
}
if
(
picosec
==
-
1
)
{
...
...
@@ -334,12 +391,9 @@ static ssize_t show_spi_transport_period(struct class_device *cdev, char *buf)
}
static
ssize_t
store_spi_transport_period
(
struct
class_device
*
cdev
,
const
char
*
buf
,
size_t
count
)
store_spi_transport_period
_helper
(
struct
class_device
*
cdev
,
const
char
*
buf
,
size_t
count
,
int
*
periodp
)
{
struct
scsi_target
*
starget
=
transport_class_to_starget
(
cdev
);
struct
Scsi_Host
*
shost
=
dev_to_shost
(
starget
->
dev
.
parent
);
struct
spi_internal
*
i
=
to_spi_internal
(
shost
->
transportt
);
int
j
,
picosec
,
period
=
-
1
;
char
*
endp
;
...
...
@@ -368,15 +422,79 @@ store_spi_transport_period(struct class_device *cdev, const char *buf,
if
(
period
>
0xff
)
period
=
0xff
;
i
->
f
->
set_period
(
starget
,
period
)
;
*
periodp
=
period
;
return
count
;
}
static
ssize_t
show_spi_transport_period
(
struct
class_device
*
cdev
,
char
*
buf
)
{
struct
scsi_target
*
starget
=
transport_class_to_starget
(
cdev
);
struct
Scsi_Host
*
shost
=
dev_to_shost
(
starget
->
dev
.
parent
);
struct
spi_internal
*
i
=
to_spi_internal
(
shost
->
transportt
);
struct
spi_transport_attrs
*
tp
=
(
struct
spi_transport_attrs
*
)
&
starget
->
starget_data
;
if
(
i
->
f
->
get_period
)
i
->
f
->
get_period
(
starget
);
return
show_spi_transport_period_helper
(
cdev
,
buf
,
tp
->
period
);
}
static
ssize_t
store_spi_transport_period
(
struct
class_device
*
cdev
,
const
char
*
buf
,
size_t
count
)
{
struct
scsi_target
*
starget
=
transport_class_to_starget
(
cdev
);
struct
Scsi_Host
*
shost
=
dev_to_shost
(
starget
->
dev
.
parent
);
struct
spi_internal
*
i
=
to_spi_internal
(
shost
->
transportt
);
struct
spi_transport_attrs
*
tp
=
(
struct
spi_transport_attrs
*
)
&
starget
->
starget_data
;
int
period
,
retval
;
retval
=
store_spi_transport_period_helper
(
cdev
,
buf
,
count
,
&
period
);
if
(
period
<
tp
->
min_period
)
period
=
tp
->
min_period
;
i
->
f
->
set_period
(
starget
,
period
);
return
retval
;
}
static
CLASS_DEVICE_ATTR
(
period
,
S_IRUGO
|
S_IWUSR
,
show_spi_transport_period
,
store_spi_transport_period
);
static
ssize_t
show_spi_transport_min_period
(
struct
class_device
*
cdev
,
char
*
buf
)
{
struct
scsi_target
*
starget
=
transport_class_to_starget
(
cdev
);
struct
spi_transport_attrs
*
tp
=
(
struct
spi_transport_attrs
*
)
&
starget
->
starget_data
;
return
show_spi_transport_period_helper
(
cdev
,
buf
,
tp
->
min_period
);
}
static
ssize_t
store_spi_transport_min_period
(
struct
class_device
*
cdev
,
const
char
*
buf
,
size_t
count
)
{
struct
scsi_target
*
starget
=
transport_class_to_starget
(
cdev
);
struct
spi_transport_attrs
*
tp
=
(
struct
spi_transport_attrs
*
)
&
starget
->
starget_data
;
return
store_spi_transport_period_helper
(
cdev
,
buf
,
count
,
&
tp
->
min_period
);
}
static
CLASS_DEVICE_ATTR
(
min_period
,
S_IRUGO
|
S_IWUSR
,
show_spi_transport_min_period
,
store_spi_transport_min_period
);
static
ssize_t
show_spi_host_signalling
(
struct
class_device
*
cdev
,
char
*
buf
)
{
struct
Scsi_Host
*
shost
=
transport_class_to_shost
(
cdev
);
...
...
@@ -642,6 +760,7 @@ spi_dv_device_internal(struct scsi_request *sreq, u8 *buffer)
{
struct
spi_internal
*
i
=
to_spi_internal
(
sreq
->
sr_host
->
transportt
);
struct
scsi_device
*
sdev
=
sreq
->
sr_device
;
struct
scsi_target
*
starget
=
sdev
->
sdev_target
;
int
len
=
sdev
->
inquiry_len
;
/* first set us up for narrow async */
DV_SET
(
offset
,
0
);
...
...
@@ -655,9 +774,11 @@ spi_dv_device_internal(struct scsi_request *sreq, u8 *buffer)
}
/* test width */
if
(
i
->
f
->
set_width
&&
sdev
->
wdtr
)
{
if
(
i
->
f
->
set_width
&&
s
pi_max_width
(
starget
)
&&
s
dev
->
wdtr
)
{
i
->
f
->
set_width
(
sdev
->
sdev_target
,
1
);
printk
(
"WIDTH IS %d
\n
"
,
spi_max_width
(
starget
));
if
(
spi_dv_device_compare_inquiry
(
sreq
,
buffer
,
buffer
+
len
,
DV_LOOPS
)
...
...
@@ -684,8 +805,8 @@ spi_dv_device_internal(struct scsi_request *sreq, u8 *buffer)
retry:
/* now set up to the maximum */
DV_SET
(
offset
,
255
);
DV_SET
(
period
,
1
);
DV_SET
(
offset
,
spi_max_offset
(
starget
)
);
DV_SET
(
period
,
spi_min_period
(
starget
)
);
if
(
len
==
0
)
{
SPI_PRINTK
(
sdev
->
sdev_target
,
KERN_INFO
,
"Domain Validation skipping write tests
\n
"
);
...
...
@@ -892,6 +1013,16 @@ EXPORT_SYMBOL(spi_display_xfer_agreement);
if (i->f->show_##field) \
count++
#define SETUP_RELATED_ATTRIBUTE(field, rel_field) \
i->private_attrs[count] = class_device_attr_##field; \
if (!i->f->set_##rel_field) { \
i->private_attrs[count].attr.mode = S_IRUGO; \
i->private_attrs[count].store = NULL; \
} \
i->attrs[count] = &i->private_attrs[count]; \
if (i->f->show_##rel_field) \
count++
#define SETUP_HOST_ATTRIBUTE(field) \
i->private_host_attrs[count] = class_device_attr_##field; \
if (!i->f->set_##field) { \
...
...
@@ -975,8 +1106,11 @@ spi_attach_transport(struct spi_function_template *ft)
i
->
f
=
ft
;
SETUP_ATTRIBUTE
(
period
);
SETUP_RELATED_ATTRIBUTE
(
min_period
,
period
);
SETUP_ATTRIBUTE
(
offset
);
SETUP_RELATED_ATTRIBUTE
(
max_offset
,
offset
);
SETUP_ATTRIBUTE
(
width
);
SETUP_RELATED_ATTRIBUTE
(
max_width
,
width
);
SETUP_ATTRIBUTE
(
iu
);
SETUP_ATTRIBUTE
(
dt
);
SETUP_ATTRIBUTE
(
qas
);
...
...
include/scsi/scsi_transport_spi.h
View file @
9636273d
...
...
@@ -27,8 +27,11 @@ struct scsi_transport_template;
struct
spi_transport_attrs
{
int
period
;
/* value in the PPR/SDTR command */
int
min_period
;
int
offset
;
int
max_offset
;
unsigned
int
width
:
1
;
/* 0 - narrow, 1 - wide */
unsigned
int
max_width
:
1
;
unsigned
int
iu
:
1
;
/* Information Units enabled */
unsigned
int
dt
:
1
;
/* DT clocking enabled */
unsigned
int
qas
:
1
;
/* Quick Arbitration and Selection enabled */
...
...
@@ -63,8 +66,11 @@ struct spi_host_attrs {
/* accessor functions */
#define spi_period(x) (((struct spi_transport_attrs *)&(x)->starget_data)->period)
#define spi_min_period(x) (((struct spi_transport_attrs *)&(x)->starget_data)->min_period)
#define spi_offset(x) (((struct spi_transport_attrs *)&(x)->starget_data)->offset)
#define spi_max_offset(x) (((struct spi_transport_attrs *)&(x)->starget_data)->max_offset)
#define spi_width(x) (((struct spi_transport_attrs *)&(x)->starget_data)->width)
#define spi_max_width(x) (((struct spi_transport_attrs *)&(x)->starget_data)->max_width)
#define spi_iu(x) (((struct spi_transport_attrs *)&(x)->starget_data)->iu)
#define spi_dt(x) (((struct spi_transport_attrs *)&(x)->starget_data)->dt)
#define spi_qas(x) (((struct spi_transport_attrs *)&(x)->starget_data)->qas)
...
...
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