Commit 9da07cd3 authored by Alan Cox's avatar Alan Cox Committed by Dave Jones

[PATCH] first pass over ultrastor.c (still used for u24f)

parent 4847fb27
...@@ -8,6 +8,9 @@ ...@@ -8,6 +8,9 @@
* John's work modified by Caleb Epstein (cae@jpmorgan.com) and * John's work modified by Caleb Epstein (cae@jpmorgan.com) and
* Eric Youngdale (ericy@cais.com). * Eric Youngdale (ericy@cais.com).
* Thanks to UltraStor for providing the necessary documentation * Thanks to UltraStor for providing the necessary documentation
*
* This is an old driver, for the 14F and 34F you should be using the
* u14-34f driver instead.
*/ */
/* /*
...@@ -164,8 +167,8 @@ ...@@ -164,8 +167,8 @@
packed structure. */ packed structure. */
typedef struct { typedef struct {
unsigned int address; u32 address;
unsigned int num_bytes; u32 num_bytes;
} ultrastor_sg_list; } ultrastor_sg_list;
...@@ -190,7 +193,7 @@ struct mscp { ...@@ -190,7 +193,7 @@ struct mscp {
unsigned char scsi_cdbs[12]; /* SCSI commands */ unsigned char scsi_cdbs[12]; /* SCSI commands */
unsigned char adapter_status; /* non-zero indicates HA error */ unsigned char adapter_status; /* non-zero indicates HA error */
unsigned char target_status; /* non-zero indicates target error */ unsigned char target_status; /* non-zero indicates target error */
unsigned int sense_data PACKED; u32 sense_data PACKED;
/* The following fields are for software only. They are included in /* The following fields are for software only. They are included in
the MSCP structure because they are associated with SCSI requests. */ the MSCP structure because they are associated with SCSI requests. */
void (*done)(Scsi_Cmnd *); void (*done)(Scsi_Cmnd *);
...@@ -289,17 +292,15 @@ static void do_ultrastor_interrupt(int, void *, struct pt_regs *); ...@@ -289,17 +292,15 @@ static void do_ultrastor_interrupt(int, void *, struct pt_regs *);
static inline void build_sg_list(struct mscp *, Scsi_Cmnd *SCpnt); static inline void build_sg_list(struct mscp *, Scsi_Cmnd *SCpnt);
/* Always called with host lock held */
static inline int find_and_clear_bit_16(unsigned short *field) static inline int find_and_clear_bit_16(unsigned short *field)
{ {
int rv; int rv;
unsigned long flags;
save_flags(flags);
cli();
if (*field == 0) panic("No free mscp"); if (*field == 0) panic("No free mscp");
asm("xorl %0,%0\n0:\tbsfw %1,%w0\n\tbtr %0,%1\n\tjnc 0b" asm("xorl %0,%0\n0:\tbsfw %1,%w0\n\tbtr %0,%1\n\tjnc 0b"
: "=&r" (rv), "=m" (*field) : "1" (*field)); : "=&r" (rv), "=m" (*field) : "1" (*field));
restore_flags(flags);
return rv; return rv;
} }
...@@ -320,14 +321,12 @@ static inline unsigned char xchgb(unsigned char reg, ...@@ -320,14 +321,12 @@ static inline unsigned char xchgb(unsigned char reg,
#if ULTRASTOR_DEBUG & (UD_COMMAND | UD_ABORT) #if ULTRASTOR_DEBUG & (UD_COMMAND | UD_ABORT)
static void log_ultrastor_abort(register struct ultrastor_config *config, /* Always called with the host lock held */
static void log_ultrastor_abort(struct ultrastor_config *config,
int command) int command)
{ {
static char fmt[80] = "abort %d (%x); MSCP free pool: %x;"; static char fmt[80] = "abort %d (%x); MSCP free pool: %x;";
register int i; int i;
unsigned long flags;
save_flags(flags);
cli();
for (i = 0; i < ULTRASTOR_MAX_CMDS; i++) for (i = 0; i < ULTRASTOR_MAX_CMDS; i++)
{ {
...@@ -340,7 +339,7 @@ static void log_ultrastor_abort(register struct ultrastor_config *config, ...@@ -340,7 +339,7 @@ static void log_ultrastor_abort(register struct ultrastor_config *config,
fmt[20 + ULTRASTOR_MAX_CMDS * 2] = '\n'; fmt[20 + ULTRASTOR_MAX_CMDS * 2] = '\n';
fmt[21 + ULTRASTOR_MAX_CMDS * 2] = 0; fmt[21 + ULTRASTOR_MAX_CMDS * 2] = 0;
printk(fmt, command, &config->mscp[command], config->mscp_free); printk(fmt, command, &config->mscp[command], config->mscp_free);
restore_flags(flags);
} }
#endif #endif
...@@ -528,7 +527,7 @@ static int ultrastor_14f_detect(Scsi_Host_Template * tpnt) ...@@ -528,7 +527,7 @@ static int ultrastor_14f_detect(Scsi_Host_Template * tpnt)
static int ultrastor_24f_detect(Scsi_Host_Template * tpnt) static int ultrastor_24f_detect(Scsi_Host_Template * tpnt)
{ {
register int i; int i;
struct Scsi_Host * shpnt = NULL; struct Scsi_Host * shpnt = NULL;
#if (ULTRASTOR_DEBUG & UD_DETECT) #if (ULTRASTOR_DEBUG & UD_DETECT)
...@@ -638,13 +637,13 @@ static int ultrastor_24f_detect(Scsi_Host_Template * tpnt) ...@@ -638,13 +637,13 @@ static int ultrastor_24f_detect(Scsi_Host_Template * tpnt)
return FALSE; return FALSE;
} }
int ultrastor_detect(Scsi_Host_Template * tpnt) static int ultrastor_detect(Scsi_Host_Template * tpnt)
{ {
tpnt->proc_name = "ultrastor"; tpnt->proc_name = "ultrastor";
return ultrastor_14f_detect(tpnt) || ultrastor_24f_detect(tpnt); return ultrastor_14f_detect(tpnt) || ultrastor_24f_detect(tpnt);
} }
const char *ultrastor_info(struct Scsi_Host * shpnt) static const char *ultrastor_info(struct Scsi_Host * shpnt)
{ {
static char buf[64]; static char buf[64];
...@@ -662,7 +661,7 @@ const char *ultrastor_info(struct Scsi_Host * shpnt) ...@@ -662,7 +661,7 @@ const char *ultrastor_info(struct Scsi_Host * shpnt)
return buf; return buf;
} }
static inline void build_sg_list(register struct mscp *mscp, Scsi_Cmnd *SCpnt) static inline void build_sg_list(struct mscp *mscp, Scsi_Cmnd *SCpnt)
{ {
struct scatterlist *sl; struct scatterlist *sl;
long transfer_length = 0; long transfer_length = 0;
...@@ -683,14 +682,13 @@ static inline void build_sg_list(register struct mscp *mscp, Scsi_Cmnd *SCpnt) ...@@ -683,14 +682,13 @@ static inline void build_sg_list(register struct mscp *mscp, Scsi_Cmnd *SCpnt)
mscp->transfer_data_length = transfer_length; mscp->transfer_data_length = transfer_length;
} }
int ultrastor_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) static int ultrastor_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
{ {
register struct mscp *my_mscp; struct mscp *my_mscp;
#if ULTRASTOR_MAX_CMDS > 1 #if ULTRASTOR_MAX_CMDS > 1
int mscp_index; int mscp_index;
#endif #endif
unsigned int status; unsigned int status;
unsigned long flags;
/* Next test is for debugging; "can't happen" */ /* Next test is for debugging; "can't happen" */
if ((config.mscp_free & ((1U << ULTRASTOR_MAX_CMDS) - 1)) == 0) if ((config.mscp_free & ((1U << ULTRASTOR_MAX_CMDS) - 1)) == 0)
...@@ -706,14 +704,8 @@ int ultrastor_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) ...@@ -706,14 +704,8 @@ int ultrastor_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
my_mscp = &config.mscp[mscp_index]; my_mscp = &config.mscp[mscp_index];
#if 1
/* This way is faster. */
*(unsigned char *)my_mscp = OP_SCSI | (DTD_SCSI << 3); *(unsigned char *)my_mscp = OP_SCSI | (DTD_SCSI << 3);
#else
my_mscp->opcode = OP_SCSI;
my_mscp->xdir = DTD_SCSI;
my_mscp->dcn = FALSE;
#endif
/* Tape drives don't work properly if the cache is used. The SCSI /* Tape drives don't work properly if the cache is used. The SCSI
READ command for a tape doesn't have a block offset, and the adapter READ command for a tape doesn't have a block offset, and the adapter
incorrectly assumes that all reads from the tape read the same incorrectly assumes that all reads from the tape read the same
...@@ -748,35 +740,31 @@ int ultrastor_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) ...@@ -748,35 +740,31 @@ int ultrastor_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
SCpnt->host_scribble = (unsigned char *)my_mscp; SCpnt->host_scribble = (unsigned char *)my_mscp;
/* Find free OGM slot. On 24F, look for OGM status byte == 0. /* Find free OGM slot. On 24F, look for OGM status byte == 0.
On 14F and 34F, wait for local interrupt pending flag to clear. */ On 14F and 34F, wait for local interrupt pending flag to clear.
retry: FIXME: now we are using new_eh we should punt here and let the
midlayer sort it out */
retry:
if (config.slot) if (config.slot)
while (inb(config.ogm_address - 1) != 0 && while (inb(config.ogm_address - 1) != 0 && config.aborted[mscp_index] == 0xff)
config.aborted[mscp_index] == 0xff) barrier(); barrier();
/* else??? */ /* else??? */
while ((inb(LCL_DOORBELL_INTR(config.doorbell_address)) & while ((inb(LCL_DOORBELL_INTR(config.doorbell_address)) & (config.slot ? 2 : 1)) && config.aborted[mscp_index] == 0xff)
(config.slot ? 2 : 1)) barrier();
&& config.aborted[mscp_index] == 0xff) barrier();
/* To avoid race conditions, make the code to write to the adapter
atomic. This simplifies the abort code. */
save_flags(flags); /* To avoid race conditions, keep the code to write to the adapter
cli(); atomic. This simplifies the abort code. Right now the
scsi mid layer has the host_lock already held
*/
if (inb(LCL_DOORBELL_INTR(config.doorbell_address)) & if (inb(LCL_DOORBELL_INTR(config.doorbell_address)) & (config.slot ? 2 : 1))
(config.slot ? 2 : 1))
{
restore_flags(flags);
goto retry; goto retry;
}
status = xchgb(0, &config.aborted[mscp_index]); status = xchgb(0, &config.aborted[mscp_index]);
if (status != 0xff) { if (status != 0xff) {
restore_flags(flags);
#if ULTRASTOR_DEBUG & (UD_COMMAND | UD_ABORT) #if ULTRASTOR_DEBUG & (UD_COMMAND | UD_ABORT)
printk("USx4F: queuecommand: aborted\n"); printk("USx4F: queuecommand: aborted\n");
...@@ -811,8 +799,6 @@ int ultrastor_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) ...@@ -811,8 +799,6 @@ int ultrastor_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
outb(0x1, LCL_DOORBELL_INTR(config.doorbell_address)); outb(0x1, LCL_DOORBELL_INTR(config.doorbell_address));
} }
restore_flags(flags);
#if (ULTRASTOR_DEBUG & UD_COMMAND) #if (ULTRASTOR_DEBUG & UD_COMMAND)
printk("USx4F: queuecommand: returning\n"); printk("USx4F: queuecommand: returning\n");
#endif #endif
...@@ -835,7 +821,7 @@ int ultrastor_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) ...@@ -835,7 +821,7 @@ int ultrastor_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
*/ */
int ultrastor_abort(Scsi_Cmnd *SCpnt) static int ultrastor_abort(Scsi_Cmnd *SCpnt)
{ {
#if ULTRASTOR_DEBUG & UD_ABORT #if ULTRASTOR_DEBUG & UD_ABORT
char out[108]; char out[108];
...@@ -844,14 +830,16 @@ int ultrastor_abort(Scsi_Cmnd *SCpnt) ...@@ -844,14 +830,16 @@ int ultrastor_abort(Scsi_Cmnd *SCpnt)
#endif #endif
unsigned int mscp_index; unsigned int mscp_index;
unsigned char old_aborted; unsigned char old_aborted;
unsigned long flags;
void (*done)(Scsi_Cmnd *); void (*done)(Scsi_Cmnd *);
struct Scsi_Host *host = SCpnt->host;
if(config.slot) if(config.slot)
return SCSI_ABORT_SNOOZE; /* Do not attempt an abort for the 24f */ return FAILED; /* Do not attempt an abort for the 24f */
/* Simple consistency checking */ /* Simple consistency checking */
if(!SCpnt->host_scribble) if(!SCpnt->host_scribble)
return SCSI_ABORT_NOT_RUNNING; return FAILED;
mscp_index = ((struct mscp *)SCpnt->host_scribble) - config.mscp; mscp_index = ((struct mscp *)SCpnt->host_scribble) - config.mscp;
if (mscp_index >= ULTRASTOR_MAX_CMDS) if (mscp_index >= ULTRASTOR_MAX_CMDS)
...@@ -863,8 +851,8 @@ int ultrastor_abort(Scsi_Cmnd *SCpnt) ...@@ -863,8 +851,8 @@ int ultrastor_abort(Scsi_Cmnd *SCpnt)
int port0 = (config.slot << 12) | 0xc80; int port0 = (config.slot << 12) | 0xc80;
int i; int i;
unsigned long flags; unsigned long flags;
save_flags(flags);
cli(); spin_lock_irqsave(host->host_lock, flags);
strcpy(out, "OGM %d:%x ICM %d:%x ports: "); strcpy(out, "OGM %d:%x ICM %d:%x ports: ");
for (i = 0; i < 16; i++) for (i = 0; i < 16; i++)
{ {
...@@ -879,7 +867,7 @@ int ultrastor_abort(Scsi_Cmnd *SCpnt) ...@@ -879,7 +867,7 @@ int ultrastor_abort(Scsi_Cmnd *SCpnt)
ogm_addr = (unsigned int)isa_bus_to_virt(inl(port0 + 23)); ogm_addr = (unsigned int)isa_bus_to_virt(inl(port0 + 23));
icm_status = inb(port0 + 27); icm_status = inb(port0 + 27);
icm_addr = (unsigned int)isa_bus_to_virt(inl(port0 + 28)); icm_addr = (unsigned int)isa_bus_to_virt(inl(port0 + 28));
restore_flags(flags); spin_lock_irqsave(host->host_lock, flags);
} }
/* First check to see if an interrupt is pending. I suspect the SiS /* First check to see if an interrupt is pending. I suspect the SiS
...@@ -888,14 +876,13 @@ int ultrastor_abort(Scsi_Cmnd *SCpnt) ...@@ -888,14 +876,13 @@ int ultrastor_abort(Scsi_Cmnd *SCpnt)
if (config.slot ? inb(config.icm_address - 1) == 2 : if (config.slot ? inb(config.icm_address - 1) == 2 :
(inb(SYS_DOORBELL_INTR(config.doorbell_address)) & 1)) (inb(SYS_DOORBELL_INTR(config.doorbell_address)) & 1))
{ {
unsigned long flags;
save_flags(flags);
printk("Ux4F: abort while completed command pending\n"); printk("Ux4F: abort while completed command pending\n");
restore_flags(flags);
cli(); spin_lock_irqsave(host->host_lock, flags);
/* FIXME: Ewww... need to think about passing host around properly */
ultrastor_interrupt(0, NULL, NULL); ultrastor_interrupt(0, NULL, NULL);
restore_flags(flags); spin_unlock_irqrestore(host->host_lock, flags);
return SCSI_ABORT_SUCCESS; /* FIXME - is this correct? -ERY */ return SUCCESS;
} }
#endif #endif
...@@ -904,7 +891,7 @@ int ultrastor_abort(Scsi_Cmnd *SCpnt) ...@@ -904,7 +891,7 @@ int ultrastor_abort(Scsi_Cmnd *SCpnt)
/* aborted == 0xff is the signal that queuecommand has not yet sent /* aborted == 0xff is the signal that queuecommand has not yet sent
the command. It will notice the new abort flag and fail. */ the command. It will notice the new abort flag and fail. */
if (old_aborted == 0xff) if (old_aborted == 0xff)
return SCSI_ABORT_SUCCESS; return SUCCESS;
/* On 24F, send an abort MSCP request. The adapter will interrupt /* On 24F, send an abort MSCP request. The adapter will interrupt
and the interrupt handler will call done. */ and the interrupt handler will call done. */
...@@ -912,18 +899,18 @@ int ultrastor_abort(Scsi_Cmnd *SCpnt) ...@@ -912,18 +899,18 @@ int ultrastor_abort(Scsi_Cmnd *SCpnt)
{ {
unsigned long flags; unsigned long flags;
save_flags(flags); spin_lock_irqsave(host->host_lock, flags);
cli();
outl(isa_virt_to_bus(&config.mscp[mscp_index]), config.ogm_address); outl(isa_virt_to_bus(&config.mscp[mscp_index]), config.ogm_address);
inb(0xc80); /* delay */ udelay(8);
outb(0x80, config.ogm_address - 1); outb(0x80, config.ogm_address - 1);
outb(0x2, LCL_DOORBELL_INTR(config.doorbell_address)); outb(0x2, LCL_DOORBELL_INTR(config.doorbell_address));
#if ULTRASTOR_DEBUG & UD_ABORT #if ULTRASTOR_DEBUG & UD_ABORT
log_ultrastor_abort(&config, mscp_index); log_ultrastor_abort(&config, mscp_index);
printk(out, ogm_status, ogm_addr, icm_status, icm_addr); printk(out, ogm_status, ogm_addr, icm_status, icm_addr);
#endif #endif
restore_flags(flags); spin_unlock_irqrestore(host->host_lock, flags);
return SCSI_ABORT_PENDING; /* FIXME: add a wait for the abort to complete */
return SUCCESS;
} }
#if ULTRASTOR_DEBUG & UD_ABORT #if ULTRASTOR_DEBUG & UD_ABORT
...@@ -953,27 +940,30 @@ int ultrastor_abort(Scsi_Cmnd *SCpnt) ...@@ -953,27 +940,30 @@ int ultrastor_abort(Scsi_Cmnd *SCpnt)
done = config.mscp[mscp_index].done; done = config.mscp[mscp_index].done;
config.mscp[mscp_index].done = 0; config.mscp[mscp_index].done = 0;
SCpnt->result = DID_ABORT << 16; SCpnt->result = DID_ABORT << 16;
/* I worry about reentrancy in scsi.c */
/* Take the host lock to guard against scsi layer re-entry */
spin_lock_irqsave(host->host_lock, flags);
done(SCpnt); done(SCpnt);
spin_unlock_irqrestore(host->host_lock, flags);
/* Need to set a timeout here in case command never completes. */ /* Need to set a timeout here in case command never completes. */
return SCSI_ABORT_SUCCESS; return SUCCESS;
} }
int ultrastor_reset(Scsi_Cmnd * SCpnt, unsigned int reset_flags) static int ultrastor_host_reset(Scsi_Cmnd * SCpnt)
{ {
unsigned long flags; unsigned long flags;
register int i; int i;
struct Scsi_Host *host = SCpnt->host;
#if (ULTRASTOR_DEBUG & UD_RESET) #if (ULTRASTOR_DEBUG & UD_RESET)
printk("US14F: reset: called\n"); printk("US14F: reset: called\n");
#endif #endif
if(config.slot) if(config.slot)
return SCSI_RESET_PUNT; /* Do not attempt a reset for the 24f */ return FAILED;
save_flags(flags);
cli();
spin_lock_irqsave(host->host_lock, flags);
/* Reset the adapter and SCSI bus. The SCSI bus reset can be /* Reset the adapter and SCSI bus. The SCSI bus reset can be
inhibited by clearing ultrastor_bus_reset before probe. */ inhibited by clearing ultrastor_bus_reset before probe. */
outb(0xc0, LCL_DOORBELL_INTR(config.doorbell_address)); outb(0xc0, LCL_DOORBELL_INTR(config.doorbell_address));
...@@ -1005,7 +995,10 @@ int ultrastor_reset(Scsi_Cmnd * SCpnt, unsigned int reset_flags) ...@@ -1005,7 +995,10 @@ int ultrastor_reset(Scsi_Cmnd * SCpnt, unsigned int reset_flags)
#endif #endif
/* FIXME - if the device implements soft resets, then the command /* FIXME - if the device implements soft resets, then the command
will still be running. ERY */ will still be running. ERY
Even bigger deal with new_eh!
*/
memset((unsigned char *)config.aborted, 0, sizeof config.aborted); memset((unsigned char *)config.aborted, 0, sizeof config.aborted);
#if ULTRASTOR_MAX_CMDS == 1 #if ULTRASTOR_MAX_CMDS == 1
...@@ -1014,7 +1007,7 @@ int ultrastor_reset(Scsi_Cmnd * SCpnt, unsigned int reset_flags) ...@@ -1014,7 +1007,7 @@ int ultrastor_reset(Scsi_Cmnd * SCpnt, unsigned int reset_flags)
config.mscp_free = ~0; config.mscp_free = ~0;
#endif #endif
restore_flags(flags); spin_unlock_irqrestore(host->host_lock, flags);
return SCSI_RESET_SUCCESS; return SCSI_RESET_SUCCESS;
} }
...@@ -1041,7 +1034,7 @@ static void ultrastor_interrupt(int irq, void *dev_id, struct pt_regs *regs) ...@@ -1041,7 +1034,7 @@ static void ultrastor_interrupt(int irq, void *dev_id, struct pt_regs *regs)
#if ULTRASTOR_MAX_CMDS > 1 #if ULTRASTOR_MAX_CMDS > 1
unsigned int mscp_index; unsigned int mscp_index;
#endif #endif
register struct mscp *mscp; struct mscp *mscp;
void (*done)(Scsi_Cmnd *); void (*done)(Scsi_Cmnd *);
Scsi_Cmnd *SCtmp; Scsi_Cmnd *SCtmp;
......
...@@ -13,13 +13,12 @@ ...@@ -13,13 +13,12 @@
#ifndef _ULTRASTOR_H #ifndef _ULTRASTOR_H
#define _ULTRASTOR_H #define _ULTRASTOR_H
int ultrastor_detect(Scsi_Host_Template *); static int ultrastor_detect(Scsi_Host_Template *);
const char *ultrastor_info(struct Scsi_Host * shpnt); static const char *ultrastor_info(struct Scsi_Host * shpnt);
int ultrastor_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); static int ultrastor_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
int ultrastor_abort(Scsi_Cmnd *); static int ultrastor_abort(Scsi_Cmnd *);
int ultrastor_reset(Scsi_Cmnd *, unsigned int); static int ultrastor_host_reset(Scsi_Cmnd *);
int ultrastor_biosparam(struct scsi_device *, struct block_device *, static int ultrastor_biosparam(struct scsi_device *, struct block_device *, sector_t, int *);
sector_t, int *);
#define ULTRASTOR_14F_MAX_SG 16 #define ULTRASTOR_14F_MAX_SG 16
...@@ -35,8 +34,8 @@ int ultrastor_biosparam(struct scsi_device *, struct block_device *, ...@@ -35,8 +34,8 @@ int ultrastor_biosparam(struct scsi_device *, struct block_device *,
detect: ultrastor_detect, \ detect: ultrastor_detect, \
info: ultrastor_info, \ info: ultrastor_info, \
queuecommand: ultrastor_queuecommand, \ queuecommand: ultrastor_queuecommand, \
abort: ultrastor_abort, \ eh_abort_handler: ultrastor_abort, \
reset: ultrastor_reset, \ eh_host_reset_handler: ultrastor_host_reset, \
bios_param: ultrastor_biosparam, \ bios_param: ultrastor_biosparam, \
can_queue: ULTRASTOR_MAX_CMDS, \ can_queue: ULTRASTOR_MAX_CMDS, \
this_id: 0, \ this_id: 0, \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment