Commit 5b3cf104 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by James Bottomley

[PATCH] feed eata.c through Lindent

the driver oopses on load for me currently, but to debug it I need to
actually be able to read the source..
Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent ac4646f7
...@@ -505,7 +505,7 @@ ...@@ -505,7 +505,7 @@
static int eata2x_detect(struct scsi_host_template *); static int eata2x_detect(struct scsi_host_template *);
static int eata2x_release(struct Scsi_Host *); static int eata2x_release(struct Scsi_Host *);
static int eata2x_queuecommand(struct scsi_cmnd *, static int eata2x_queuecommand(struct scsi_cmnd *,
void (*done)(struct scsi_cmnd *)); void (*done) (struct scsi_cmnd *));
static int eata2x_eh_abort(struct scsi_cmnd *); static int eata2x_eh_abort(struct scsi_cmnd *);
static int eata2x_eh_host_reset(struct scsi_cmnd *); static int eata2x_eh_host_reset(struct scsi_cmnd *);
static int eata2x_bios_param(struct scsi_device *, struct block_device *, static int eata2x_bios_param(struct scsi_device *, struct block_device *,
...@@ -526,7 +526,8 @@ static struct scsi_host_template driver_template = { ...@@ -526,7 +526,8 @@ static struct scsi_host_template driver_template = {
.this_id = 7, .this_id = 7,
.unchecked_isa_dma = 1, .unchecked_isa_dma = 1,
.use_clustering = ENABLE_CLUSTERING .use_clustering = ENABLE_CLUSTERING
}; };
#if !defined(__BIG_ENDIAN_BITFIELD) && !defined(__LITTLE_ENDIAN_BITFIELD) #if !defined(__BIG_ENDIAN_BITFIELD) && !defined(__LITTLE_ENDIAN_BITFIELD)
#error "Adjust your <asm/byteorder.h> defines" #error "Adjust your <asm/byteorder.h> defines"
#endif #endif
...@@ -622,20 +623,27 @@ struct eata_info { ...@@ -622,20 +623,27 @@ struct eata_info {
u_int32_t sign; /* ASCII "EATA" signature */ u_int32_t sign; /* ASCII "EATA" signature */
#if defined(__BIG_ENDIAN_BITFIELD) #if defined(__BIG_ENDIAN_BITFIELD)
unchar version:4, :4; unchar version : 4,
unchar haaval:1, ata:1, drqvld:1, dmasup:1, morsup:1, trnxfr:1, tarsup:1, : 4;
ocsena:1; unchar haaval : 1,
ata : 1,
drqvld : 1,
dmasup : 1,
morsup : 1,
trnxfr : 1,
tarsup : 1,
ocsena : 1;
#else #else
unchar :4, /* unused low nibble */ unchar : 4, /* unused low nibble */
version:4; /* EATA version, should be 0x1 */ version : 4; /* EATA version, should be 0x1 */
unchar ocsena:1, /* Overlap Command Support Enabled */ unchar ocsena : 1, /* Overlap Command Support Enabled */
tarsup:1, /* Target Mode Supported */ tarsup : 1, /* Target Mode Supported */
trnxfr:1, /* Truncate Transfer Cmd NOT Necessary */ trnxfr : 1, /* Truncate Transfer Cmd NOT Necessary */
morsup:1, /* More Supported */ morsup : 1, /* More Supported */
dmasup:1, /* DMA Supported */ dmasup : 1, /* DMA Supported */
drqvld:1, /* DRQ Index (DRQX) is valid */ drqvld : 1, /* DRQ Index (DRQX) is valid */
ata:1, /* This is an ATA device */ ata : 1, /* This is an ATA device */
haaval:1; /* Host Adapter Address Valid */ haaval : 1; /* Host Adapter Address Valid */
#endif #endif
ushort cp_pad_len; /* Number of pad bytes after cp_len */ ushort cp_pad_len; /* Number of pad bytes after cp_len */
...@@ -647,116 +655,145 @@ struct eata_info { ...@@ -647,116 +655,145 @@ struct eata_info {
ushort scatt_size; /* Max number of entries in scatter/gather table */ ushort scatt_size; /* Max number of entries in scatter/gather table */
#if defined(__BIG_ENDIAN_BITFIELD) #if defined(__BIG_ENDIAN_BITFIELD)
unchar drqx:2, second:1, irq_tr:1, irq:4; unchar drqx : 2,
second : 1,
irq_tr : 1,
irq : 4;
unchar sync; unchar sync;
unchar :4, res1:1, large_sg:1, forcaddr:1, isaena:1; unchar : 4,
unchar max_chan:3, max_id:5; res1 : 1,
large_sg : 1,
forcaddr : 1,
isaena : 1;
unchar max_chan : 3,
max_id : 5;
unchar max_lun; unchar max_lun;
unchar eisa:1, pci:1, idquest:1, m1:1, :4; unchar eisa : 1,
pci : 1,
idquest : 1,
m1 : 1,
: 4;
#else #else
unchar irq:4, /* Interrupt Request assigned to this controller */ unchar irq : 4, /* Interrupt Request assigned to this controller */
irq_tr:1, /* 0 for edge triggered, 1 for level triggered */ irq_tr : 1, /* 0 for edge triggered, 1 for level triggered */
second:1, /* 1 if this is a secondary (not primary) controller */ second : 1, /* 1 if this is a secondary (not primary) controller */
drqx:2; /* DRQ Index (0=DMA0, 1=DMA7, 2=DMA6, 3=DMA5) */ drqx : 2; /* DRQ Index (0=DMA0, 1=DMA7, 2=DMA6, 3=DMA5) */
unchar sync; /* 1 if scsi target id 7...0 is running sync scsi */ unchar sync; /* 1 if scsi target id 7...0 is running sync scsi */
/* Structure extension defined in EATA 2.0B */ /* Structure extension defined in EATA 2.0B */
unchar isaena:1, /* ISA i/o addressing is disabled/enabled */ unchar isaena : 1, /* ISA i/o addressing is disabled/enabled */
forcaddr:1, /* Port address has been forced */ forcaddr : 1, /* Port address has been forced */
large_sg:1, /* 1 if large SG lists are supported */ large_sg : 1, /* 1 if large SG lists are supported */
res1:1, res1 : 1,
:4; : 4;
unchar max_id:5, /* Max SCSI target ID number */ unchar max_id : 5, /* Max SCSI target ID number */
max_chan:3; /* Max SCSI channel number on this board */ max_chan : 3; /* Max SCSI channel number on this board */
/* Structure extension defined in EATA 2.0C */ /* Structure extension defined in EATA 2.0C */
unchar max_lun; /* Max SCSI LUN number */ unchar max_lun; /* Max SCSI LUN number */
unchar :4, unchar
m1:1, /* This is a PCI with an M1 chip installed */ : 4,
idquest:1, /* RAIDNUM returned is questionable */ m1 : 1, /* This is a PCI with an M1 chip installed */
pci:1, /* This board is PCI */ idquest : 1, /* RAIDNUM returned is questionable */
eisa:1; /* This board is EISA */ pci : 1, /* This board is PCI */
eisa : 1; /* This board is EISA */
#endif #endif
unchar raidnum; /* Uniquely identifies this HBA in a system */ unchar raidnum; /* Uniquely identifies this HBA in a system */
unchar notused; unchar notused;
ushort ipad[247]; ushort ipad[247];
}; };
/* Board config structure */ /* Board config structure */
struct eata_config { struct eata_config {
ushort len; /* Number of bytes following this field */ ushort len; /* Number of bytes following this field */
#if defined(__BIG_ENDIAN_BITFIELD) #if defined(__BIG_ENDIAN_BITFIELD)
unchar :4, tarena:1, mdpena:1, ocena:1, edis:1; unchar : 4,
tarena : 1,
mdpena : 1,
ocena : 1,
edis : 1;
#else #else
unchar edis:1, /* Disable EATA interface after config command */ unchar edis : 1, /* Disable EATA interface after config command */
ocena:1, /* Overlapped Commands Enabled */ ocena : 1, /* Overlapped Commands Enabled */
mdpena:1, /* Transfer all Modified Data Pointer Messages */ mdpena : 1, /* Transfer all Modified Data Pointer Messages */
tarena:1, /* Target Mode Enabled for this controller */ tarena : 1, /* Target Mode Enabled for this controller */
:4; : 4;
#endif #endif
unchar cpad[511]; unchar cpad[511];
}; };
/* Returned status packet structure */ /* Returned status packet structure */
struct mssp { struct mssp {
#if defined(__BIG_ENDIAN_BITFIELD) #if defined(__BIG_ENDIAN_BITFIELD)
unchar eoc:1, adapter_status:7; unchar eoc : 1,
adapter_status : 7;
#else #else
unchar adapter_status:7, /* State related to current command */ unchar adapter_status : 7, /* State related to current command */
eoc:1; /* End Of Command (1 = command completed) */ eoc : 1; /* End Of Command (1 = command completed) */
#endif #endif
unchar target_status; /* SCSI status received after data transfer */ unchar target_status; /* SCSI status received after data transfer */
unchar unused[2]; unchar unused[2];
u_int32_t inv_res_len; /* Number of bytes not transferred */ u_int32_t inv_res_len; /* Number of bytes not transferred */
u_int32_t cpp_index; /* Index of address set in cp */ u_int32_t cpp_index; /* Index of address set in cp */
char mess[12]; char mess[12];
}; };
struct sg_list { struct sg_list {
unsigned int address; /* Segment Address */ unsigned int address; /* Segment Address */
unsigned int num_bytes; /* Segment Length */ unsigned int num_bytes; /* Segment Length */
}; };
/* MailBox SCSI Command Packet */ /* MailBox SCSI Command Packet */
struct mscp { struct mscp {
#if defined(__BIG_ENDIAN_BITFIELD) #if defined(__BIG_ENDIAN_BITFIELD)
unchar din:1, dout:1, interp:1, :1, sg:1, reqsen:1, init:1, sreset:1; unchar din : 1,
dout : 1,
interp : 1,
: 1,
sg : 1,
reqsen :1,
init : 1,
sreset : 1;
unchar sense_len; unchar sense_len;
unchar unused[3]; unchar unused[3];
unchar :7, fwnest:1; unchar : 7,
unchar :5, hbaci:1, iat:1, phsunit:1; fwnest : 1;
unchar channel:3, target:5; unchar : 5,
unchar one:1, dispri:1, luntar:1, lun:5; hbaci : 1,
iat : 1,
phsunit : 1;
unchar channel : 3,
target : 5;
unchar one : 1,
dispri : 1,
luntar : 1,
lun : 5;
#else #else
unchar sreset:1, /* SCSI Bus Reset Signal should be asserted */ unchar sreset :1, /* SCSI Bus Reset Signal should be asserted */
init:1, /* Re-initialize controller and self test */ init :1, /* Re-initialize controller and self test */
reqsen:1, /* Transfer Request Sense Data to addr using DMA */ reqsen :1, /* Transfer Request Sense Data to addr using DMA */
sg:1, /* Use Scatter/Gather */ sg :1, /* Use Scatter/Gather */
:1, :1,
interp:1, /* The controller interprets cp, not the target */ interp :1, /* The controller interprets cp, not the target */
dout:1, /* Direction of Transfer is Out (Host to Target) */ dout :1, /* Direction of Transfer is Out (Host to Target) */
din:1; /* Direction of Transfer is In (Target to Host) */ din :1; /* Direction of Transfer is In (Target to Host) */
unchar sense_len; /* Request Sense Length */ unchar sense_len; /* Request Sense Length */
unchar unused[3]; unchar unused[3];
unchar fwnest:1, /* Send command to a component of an Array Group */ unchar fwnest : 1, /* Send command to a component of an Array Group */
:7; : 7;
unchar phsunit:1, /* Send to Target Physical Unit (bypass RAID) */ unchar phsunit : 1, /* Send to Target Physical Unit (bypass RAID) */
iat:1, /* Inhibit Address Translation */ iat : 1, /* Inhibit Address Translation */
hbaci:1, /* Inhibit HBA Caching for this command */ hbaci : 1, /* Inhibit HBA Caching for this command */
:5; : 5;
unchar target:5, /* SCSI target ID */ unchar target : 5, /* SCSI target ID */
channel:3; /* SCSI channel number */ channel : 3; /* SCSI channel number */
unchar lun:5, /* SCSI logical unit number */ unchar lun : 5, /* SCSI logical unit number */
luntar:1, /* This cp is for Target (not LUN) */ luntar : 1, /* This cp is for Target (not LUN) */
dispri:1, /* Disconnect Privilege granted */ dispri : 1, /* Disconnect Privilege granted */
one:1; /* 1 */ one : 1; /* 1 */
#endif #endif
unchar mess[3]; /* Massage to/from Target */ unchar mess[3]; /* Massage to/from Target */
...@@ -774,7 +811,7 @@ struct mscp { ...@@ -774,7 +811,7 @@ struct mscp {
following CP_TAIL_SIZE bytes, initialized by detect */ following CP_TAIL_SIZE bytes, initialized by detect */
dma_addr_t cp_dma_addr; /* dma handle for this cp structure */ dma_addr_t cp_dma_addr; /* dma handle for this cp structure */
struct sg_list *sglist; /* pointer to the allocated SG list */ struct sg_list *sglist; /* pointer to the allocated SG list */
}; };
#define CP_TAIL_SIZE (sizeof(struct sglist *) + sizeof(dma_addr_t)) #define CP_TAIL_SIZE (sizeof(struct sglist *) + sizeof(dma_addr_t))
...@@ -797,7 +834,7 @@ struct hostdata { ...@@ -797,7 +834,7 @@ struct hostdata {
struct mssp *sp_cpu_addr; /* cpu addr for DMA buffer sp */ struct mssp *sp_cpu_addr; /* cpu addr for DMA buffer sp */
dma_addr_t sp_dma_addr; /* dma handle for DMA buffer sp */ dma_addr_t sp_dma_addr; /* dma handle for DMA buffer sp */
struct mssp sp; /* Local copy of sp buffer */ struct mssp sp; /* Local copy of sp buffer */
}; };
static struct Scsi_Host *sh[MAX_BOARDS + 1]; static struct Scsi_Host *sh[MAX_BOARDS + 1];
static const char *driver_name = "EATA"; static const char *driver_name = "EATA";
...@@ -829,7 +866,7 @@ static unsigned long io_port[] = { ...@@ -829,7 +866,7 @@ static unsigned long io_port[] = {
/* End of list */ /* End of list */
0x0 0x0
}; };
#define HD(board) ((struct hostdata *) &sh[board]->hostdata) #define HD(board) ((struct hostdata *) &sh[board]->hostdata)
#define BN(board) (HD(board)->board_name) #define BN(board) (HD(board)->board_name)
...@@ -844,7 +881,8 @@ static unsigned long io_port[] = { ...@@ -844,7 +881,8 @@ static unsigned long io_port[] = {
#define REG2H(x) le16_to_cpu(x) #define REG2H(x) le16_to_cpu(x)
static irqreturn_t do_interrupt_handler(int, void *, struct pt_regs *); static irqreturn_t do_interrupt_handler(int, void *, struct pt_regs *);
static void flush_dev(struct scsi_device *, unsigned long, unsigned int, unsigned int); static void flush_dev(struct scsi_device *, unsigned long, unsigned int,
unsigned int);
static int do_trace = 0; static int do_trace = 0;
static int setup_done = 0; static int setup_done = 0;
static int link_statistics; static int link_statistics;
...@@ -896,45 +934,40 @@ static char boot_options[MAX_BOOT_OPTIONS_SIZE]; ...@@ -896,45 +934,40 @@ static char boot_options[MAX_BOOT_OPTIONS_SIZE];
#include <linux/moduleparam.h> #include <linux/moduleparam.h>
module_param_string(eata, boot_options, MAX_BOOT_OPTIONS_SIZE, 0); module_param_string(eata, boot_options, MAX_BOOT_OPTIONS_SIZE, 0);
MODULE_PARM_DESC(eata, " equivalent to the \"eata=...\" kernel boot option." \ MODULE_PARM_DESC(eata, " equivalent to the \"eata=...\" kernel boot option."
" Example: modprobe eata \"eata=0x7410,0x230,lc:y,tm:0,mq:4,ep:n\""); " Example: modprobe eata \"eata=0x7410,0x230,lc:y,tm:0,mq:4,ep:n\"");
MODULE_AUTHOR("Dario Ballabio"); MODULE_AUTHOR("Dario Ballabio");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("EATA/DMA SCSI Driver"); MODULE_DESCRIPTION("EATA/DMA SCSI Driver");
#endif #endif
static int eata2x_slave_configure(struct scsi_device *dev) { static int eata2x_slave_configure(struct scsi_device *dev)
{
int j, tqd, utqd; int j, tqd, utqd;
char *tag_suffix, *link_suffix; char *tag_suffix, *link_suffix;
struct Scsi_Host *host = dev->host; struct Scsi_Host *host = dev->host;
j = ((struct hostdata *) host->hostdata)->board_number; j = ((struct hostdata *)host->hostdata)->board_number;
utqd = MAX_CMD_PER_LUN; utqd = MAX_CMD_PER_LUN;
tqd = max_queue_depth; tqd = max_queue_depth;
if (TLDEV(dev->type) && dev->tagged_supported) if (TLDEV(dev->type) && dev->tagged_supported) {
if (tag_mode == TAG_SIMPLE) { if (tag_mode == TAG_SIMPLE) {
scsi_adjust_queue_depth(dev, MSG_SIMPLE_TAG, tqd); scsi_adjust_queue_depth(dev, MSG_SIMPLE_TAG, tqd);
tag_suffix = ", simple tags"; tag_suffix = ", simple tags";
} } else if (tag_mode == TAG_ORDERED) {
else if (tag_mode == TAG_ORDERED) {
scsi_adjust_queue_depth(dev, MSG_ORDERED_TAG, tqd); scsi_adjust_queue_depth(dev, MSG_ORDERED_TAG, tqd);
tag_suffix = ", ordered tags"; tag_suffix = ", ordered tags";
} } else {
else {
scsi_adjust_queue_depth(dev, 0, tqd); scsi_adjust_queue_depth(dev, 0, tqd);
tag_suffix = ", no tags"; tag_suffix = ", no tags";
} }
} else if (TLDEV(dev->type) && linked_comm) {
else if (TLDEV(dev->type) && linked_comm) {
scsi_adjust_queue_depth(dev, 0, tqd); scsi_adjust_queue_depth(dev, 0, tqd);
tag_suffix = ", untagged"; tag_suffix = ", untagged";
} } else {
else {
scsi_adjust_queue_depth(dev, 0, utqd); scsi_adjust_queue_depth(dev, 0, utqd);
tag_suffix = ""; tag_suffix = "";
} }
...@@ -953,25 +986,27 @@ static int eata2x_slave_configure(struct scsi_device *dev) { ...@@ -953,25 +986,27 @@ static int eata2x_slave_configure(struct scsi_device *dev) {
return 0; return 0;
} }
static int wait_on_busy(unsigned long iobase, unsigned int loop) { static int wait_on_busy(unsigned long iobase, unsigned int loop)
{
while (inb(iobase + REG_AUX_STATUS) & ABSY_ASSERTED) { while (inb(iobase + REG_AUX_STATUS) & ABSY_ASSERTED) {
udelay(1L); udelay(1L);
if (--loop == 0) return 1; if (--loop == 0)
return 1;
} }
return 0; return 0;
} }
static int do_dma(unsigned long iobase, unsigned long addr, unchar cmd) { static int do_dma(unsigned long iobase, unsigned long addr, unchar cmd)
{
unsigned char *byaddr; unsigned char *byaddr;
unsigned long devaddr; unsigned long devaddr;
if (wait_on_busy(iobase, (addr ? MAXLOOP * 100 : MAXLOOP))) return 1; if (wait_on_busy(iobase, (addr ? MAXLOOP * 100 : MAXLOOP)))
return 1;
if (addr) { if (addr) {
devaddr = H2DEV(addr); devaddr = H2DEV(addr);
byaddr = (unsigned char *) &devaddr; byaddr = (unsigned char *)&devaddr;
outb(byaddr[3], iobase + REG_LOW); outb(byaddr[3], iobase + REG_LOW);
outb(byaddr[2], iobase + REG_LM); outb(byaddr[2], iobase + REG_LM);
outb(byaddr[1], iobase + REG_MID); outb(byaddr[1], iobase + REG_MID);
...@@ -982,17 +1017,17 @@ static int do_dma(unsigned long iobase, unsigned long addr, unchar cmd) { ...@@ -982,17 +1017,17 @@ static int do_dma(unsigned long iobase, unsigned long addr, unchar cmd) {
return 0; return 0;
} }
static int read_pio(unsigned long iobase, ushort *start, ushort *end) { static int read_pio(unsigned long iobase, ushort * start, ushort * end)
{
unsigned int loop = MAXLOOP; unsigned int loop = MAXLOOP;
ushort *p; ushort *p;
for (p = start; p <= end; p++) { for (p = start; p <= end; p++) {
while (!(inb(iobase + REG_STATUS) & DRQ_ASSERTED)) { while (!(inb(iobase + REG_STATUS) & DRQ_ASSERTED)) {
udelay(1L); udelay(1L);
if (--loop == 0) return 1; if (--loop == 0)
return 1;
} }
loop = MAXLOOP; loop = MAXLOOP;
*p = REG2H(inw(iobase)); *p = REG2H(inw(iobase));
} }
...@@ -1000,15 +1035,14 @@ static int read_pio(unsigned long iobase, ushort *start, ushort *end) { ...@@ -1000,15 +1035,14 @@ static int read_pio(unsigned long iobase, ushort *start, ushort *end) {
return 0; return 0;
} }
static struct pci_dev *get_pci_dev(unsigned long port_base) { static struct pci_dev *get_pci_dev(unsigned long port_base)
{
#if defined(CONFIG_PCI) #if defined(CONFIG_PCI)
unsigned int addr; unsigned int addr;
struct pci_dev *dev = NULL; struct pci_dev *dev = NULL;
while((dev = pci_get_class(PCI_CLASS_STORAGE_SCSI << 8, dev))) { while ((dev = pci_get_class(PCI_CLASS_STORAGE_SCSI << 8, dev))) {
addr = pci_resource_start (dev, 0); addr = pci_resource_start(dev, 0);
#if defined(DEBUG_PCI_DETECT) #if defined(DEBUG_PCI_DETECT)
printk("%s: get_pci_dev, bus %d, devfn 0x%x, addr 0x%x.\n", printk("%s: get_pci_dev, bus %d, devfn 0x%x, addr 0x%x.\n",
...@@ -1020,53 +1054,51 @@ static struct pci_dev *get_pci_dev(unsigned long port_base) { ...@@ -1020,53 +1054,51 @@ static struct pci_dev *get_pci_dev(unsigned long port_base) {
* cause memory problems, but in general this is a bad thing to do (this * cause memory problems, but in general this is a bad thing to do (this
* driver needs to be converted to the proper PCI api someday... */ * driver needs to be converted to the proper PCI api someday... */
pci_dev_put(dev); pci_dev_put(dev);
if (addr + PCI_BASE_ADDRESS_0 == port_base) return dev; if (addr + PCI_BASE_ADDRESS_0 == port_base)
return dev;
} }
#endif /* end CONFIG_PCI */ #endif /* end CONFIG_PCI */
return NULL; return NULL;
} }
static void enable_pci_ports(void) { static void enable_pci_ports(void)
{
#if defined(CONFIG_PCI) #if defined(CONFIG_PCI)
struct pci_dev *dev = NULL; struct pci_dev *dev = NULL;
while((dev = pci_get_class(PCI_CLASS_STORAGE_SCSI << 8, dev))) { while ((dev = pci_get_class(PCI_CLASS_STORAGE_SCSI << 8, dev))) {
#if defined(DEBUG_PCI_DETECT) #if defined(DEBUG_PCI_DETECT)
printk("%s: enable_pci_ports, bus %d, devfn 0x%x.\n", printk("%s: enable_pci_ports, bus %d, devfn 0x%x.\n",
driver_name, dev->bus->number, dev->devfn); driver_name, dev->bus->number, dev->devfn);
#endif #endif
if (pci_enable_device (dev)) if (pci_enable_device(dev))
printk("%s: warning, pci_enable_device failed, bus %d devfn 0x%x.\n", printk
("%s: warning, pci_enable_device failed, bus %d devfn 0x%x.\n",
driver_name, dev->bus->number, dev->devfn); driver_name, dev->bus->number, dev->devfn);
} }
#endif /* end CONFIG_PCI */ #endif /* end CONFIG_PCI */
} }
static int port_detect \ static int port_detect(unsigned long port_base, unsigned int j,
(unsigned long port_base, unsigned int j, struct scsi_host_template *tpnt) { struct scsi_host_template *tpnt)
{
unsigned char irq, dma_channel, subversion, i, is_pci = 0; unsigned char irq, dma_channel, subversion, i, is_pci = 0;
unsigned char protocol_rev; unsigned char protocol_rev;
struct eata_info info; struct eata_info info;
char *bus_type, dma_name[16]; char *bus_type, dma_name[16];
struct pci_dev *pdev; struct pci_dev *pdev;
/* Allowed DMA channels for ISA (0 indicates reserved) */ /* Allowed DMA channels for ISA (0 indicates reserved) */
unsigned char dma_channel_table[4] = { 5, 6, 7, 0 }; unsigned char dma_channel_table[4] = { 5, 6, 7, 0 };
char name[16]; char name[16];
sprintf(name, "%s%d", driver_name, j); sprintf(name, "%s%d", driver_name, j);
if (!request_region(port_base, REGION_SIZE, driver_name)) { if (!request_region(port_base, REGION_SIZE, driver_name)) {
#if defined(DEBUG_DETECT) #if defined(DEBUG_DETECT)
printk("%s: address 0x%03lx in use, skipping probe.\n", name, port_base); printk("%s: address 0x%03lx in use, skipping probe.\n", name,
port_base);
#endif #endif
goto fail; goto fail;
} }
...@@ -1075,15 +1107,17 @@ static int port_detect \ ...@@ -1075,15 +1107,17 @@ static int port_detect \
if (do_dma(port_base, 0, READ_CONFIG_PIO)) { if (do_dma(port_base, 0, READ_CONFIG_PIO)) {
#if defined(DEBUG_DETECT) #if defined(DEBUG_DETECT)
printk("%s: detect, do_dma failed at 0x%03lx.\n", name, port_base); printk("%s: detect, do_dma failed at 0x%03lx.\n", name,
port_base);
#endif #endif
goto freelock; goto freelock;
} }
/* Read the info structure */ /* Read the info structure */
if (read_pio(port_base, (ushort *)&info, (ushort *)&info.ipad[0])) { if (read_pio(port_base, (ushort *) & info, (ushort *) & info.ipad[0])) {
#if defined(DEBUG_DETECT) #if defined(DEBUG_DETECT)
printk("%s: detect, read_pio failed at 0x%03lx.\n", name, port_base); printk("%s: detect, read_pio failed at 0x%03lx.\n", name,
port_base);
#endif #endif
goto freelock; goto freelock;
} }
...@@ -1105,11 +1139,11 @@ static int port_detect \ ...@@ -1105,11 +1139,11 @@ static int port_detect \
} }
if (info.data_len < EATA_2_0A_SIZE) { if (info.data_len < EATA_2_0A_SIZE) {
printk("%s: config structure size (%d bytes) too short, detaching.\n", printk
("%s: config structure size (%d bytes) too short, detaching.\n",
name, info.data_len); name, info.data_len);
goto freelock; goto freelock;
} } else if (info.data_len == EATA_2_0A_SIZE)
else if (info.data_len == EATA_2_0A_SIZE)
protocol_rev = 'A'; protocol_rev = 'A';
else if (info.data_len == EATA_2_0B_SIZE) else if (info.data_len == EATA_2_0B_SIZE)
protocol_rev = 'B'; protocol_rev = 'B';
...@@ -1121,80 +1155,82 @@ static int port_detect \ ...@@ -1121,80 +1155,82 @@ static int port_detect \
bus_type = "PCI"; bus_type = "PCI";
is_pci = 1; is_pci = 1;
subversion = ESA; subversion = ESA;
} } else if (port_base > MAX_EISA_ADDR
else if (port_base > MAX_EISA_ADDR || (protocol_rev == 'C' && info.pci)) { || (protocol_rev == 'C' && info.pci)) {
bus_type = "PCI"; bus_type = "PCI";
is_pci = 1; is_pci = 1;
subversion = ESA; subversion = ESA;
} } else if (port_base >= MIN_EISA_ADDR
else if (port_base >= MIN_EISA_ADDR || (protocol_rev == 'C' && info.eisa)) { || (protocol_rev == 'C' && info.eisa)) {
bus_type = "EISA"; bus_type = "EISA";
subversion = ESA; subversion = ESA;
} } else if (protocol_rev == 'C' && !info.eisa && !info.pci) {
else if (protocol_rev == 'C' && !info.eisa && !info.pci) {
bus_type = "ISA"; bus_type = "ISA";
subversion = ISA; subversion = ISA;
} } else if (port_base > MAX_ISA_ADDR) {
else if (port_base > MAX_ISA_ADDR) {
bus_type = "PCI"; bus_type = "PCI";
is_pci = 1; is_pci = 1;
subversion = ESA; subversion = ESA;
} } else {
else {
bus_type = "ISA"; bus_type = "ISA";
subversion = ISA; subversion = ISA;
} }
if (!info.haaval || info.ata) { if (!info.haaval || info.ata) {
printk("%s: address 0x%03lx, unusable %s board (%d%d), detaching.\n", printk
("%s: address 0x%03lx, unusable %s board (%d%d), detaching.\n",
name, port_base, bus_type, info.haaval, info.ata); name, port_base, bus_type, info.haaval, info.ata);
goto freelock; goto freelock;
} }
if (info.drqvld) { if (info.drqvld) {
if (subversion == ESA) if (subversion == ESA)
printk("%s: warning, weird %s board using DMA.\n", name, bus_type); printk("%s: warning, weird %s board using DMA.\n", name,
bus_type);
subversion = ISA; subversion = ISA;
dma_channel = dma_channel_table[3 - info.drqx]; dma_channel = dma_channel_table[3 - info.drqx];
} } else {
else {
if (subversion == ISA) if (subversion == ISA)
printk("%s: warning, weird %s board not using DMA.\n", name, bus_type); printk("%s: warning, weird %s board not using DMA.\n",
name, bus_type);
subversion = ESA; subversion = ESA;
dma_channel = NO_DMA; dma_channel = NO_DMA;
} }
if (!info.dmasup) if (!info.dmasup)
printk("%s: warning, DMA protocol support not asserted.\n", name); printk("%s: warning, DMA protocol support not asserted.\n",
name);
irq = info.irq; irq = info.irq;
if (subversion == ESA && !info.irq_tr) if (subversion == ESA && !info.irq_tr)
printk("%s: warning, LEVEL triggering is suggested for IRQ %u.\n", printk
("%s: warning, LEVEL triggering is suggested for IRQ %u.\n",
name, irq); name, irq);
if (is_pci) { if (is_pci) {
pdev = get_pci_dev(port_base); pdev = get_pci_dev(port_base);
if (!pdev) if (!pdev)
printk("%s: warning, failed to get pci_dev structure.\n", name); printk
} ("%s: warning, failed to get pci_dev structure.\n",
else name);
} else
pdev = NULL; pdev = NULL;
if (pdev && (irq != pdev->irq)) { if (pdev && (irq != pdev->irq)) {
printk("%s: IRQ %u mapped to IO-APIC IRQ %u.\n", name, irq, pdev->irq); printk("%s: IRQ %u mapped to IO-APIC IRQ %u.\n", name, irq,
pdev->irq);
irq = pdev->irq; irq = pdev->irq;
} }
/* Board detected, allocate its IRQ */ /* Board detected, allocate its IRQ */
if (request_irq(irq, do_interrupt_handler, if (request_irq(irq, do_interrupt_handler,
SA_INTERRUPT | ((subversion == ESA) ? SA_SHIRQ : 0), SA_INTERRUPT | ((subversion == ESA) ? SA_SHIRQ : 0),
driver_name, (void *) &sha[j])) { driver_name, (void *)&sha[j])) {
printk("%s: unable to allocate IRQ %u, detaching.\n", name, irq); printk("%s: unable to allocate IRQ %u, detaching.\n", name,
irq);
goto freelock; goto freelock;
} }
...@@ -1203,27 +1239,32 @@ static int port_detect \ ...@@ -1203,27 +1239,32 @@ static int port_detect \
name, dma_channel); name, dma_channel);
goto freeirq; goto freeirq;
} }
#if defined(FORCE_CONFIG) #if defined(FORCE_CONFIG)
{ {
struct eata_config *cf; struct eata_config *cf;
dma_addr_t cf_dma_addr; dma_addr_t cf_dma_addr;
cf = pci_alloc_consistent(pdev, sizeof(struct eata_config), &cf_dma_addr); cf = pci_alloc_consistent(pdev, sizeof(struct eata_config),
&cf_dma_addr);
if (!cf) { if (!cf) {
printk("%s: config, pci_alloc_consistent failed, detaching.\n", name); printk
("%s: config, pci_alloc_consistent failed, detaching.\n",
name);
goto freedma; goto freedma;
} }
/* Set board configuration */ /* Set board configuration */
memset((char *)cf, 0, sizeof(struct eata_config)); memset((char *)cf, 0, sizeof(struct eata_config));
cf->len = (ushort) H2DEV16((ushort)510); cf->len = (ushort) H2DEV16((ushort) 510);
cf->ocena = 1; cf->ocena = 1;
if (do_dma(port_base, cf_dma_addr, SET_CONFIG_DMA)) { if (do_dma(port_base, cf_dma_addr, SET_CONFIG_DMA)) {
printk("%s: busy timeout sending configuration, detaching.\n", name); printk
pci_free_consistent(pdev, sizeof(struct eata_config), cf, cf_dma_addr); ("%s: busy timeout sending configuration, detaching.\n",
name);
pci_free_consistent(pdev, sizeof(struct eata_config),
cf, cf_dma_addr);
goto freedma; goto freedma;
} }
...@@ -1261,7 +1302,7 @@ static int port_detect \ ...@@ -1261,7 +1302,7 @@ static int port_detect \
unsigned long flags; unsigned long flags;
sh[j]->unchecked_isa_dma = 1; sh[j]->unchecked_isa_dma = 1;
flags=claim_dma_lock(); flags = claim_dma_lock();
disable_dma(dma_channel); disable_dma(dma_channel);
clear_dma_ff(dma_channel); clear_dma_ff(dma_channel);
set_dma_mode(dma_channel, DMA_MODE_CASCADE); set_dma_mode(dma_channel, DMA_MODE_CASCADE);
...@@ -1287,7 +1328,6 @@ static int port_detect \ ...@@ -1287,7 +1328,6 @@ static int port_detect \
} }
if (protocol_rev != 'A') { if (protocol_rev != 'A') {
if (info.max_chan > 0 && info.max_chan < MAX_CHANNEL) if (info.max_chan > 0 && info.max_chan < MAX_CHANNEL)
sh[j]->max_channel = info.max_chan; sh[j]->max_channel = info.max_chan;
...@@ -1299,30 +1339,38 @@ static int port_detect \ ...@@ -1299,30 +1339,38 @@ static int port_detect \
} }
if (protocol_rev == 'C') { if (protocol_rev == 'C') {
if (info.max_lun > 7 && info.max_lun < MAX_LUN) if (info.max_lun > 7 && info.max_lun < MAX_LUN)
sh[j]->max_lun = info.max_lun + 1; sh[j]->max_lun = info.max_lun + 1;
} }
if (dma_channel == NO_DMA) sprintf(dma_name, "%s", "BMST"); if (dma_channel == NO_DMA)
else sprintf(dma_name, "DMA %u", dma_channel); sprintf(dma_name, "%s", "BMST");
else
sprintf(dma_name, "DMA %u", dma_channel);
spin_unlock_irq(&driver_lock); spin_unlock_irq(&driver_lock);
for (i = 0; i < sh[j]->can_queue; i++) for (i = 0; i < sh[j]->can_queue; i++)
HD(j)->cp[i].cp_dma_addr = pci_map_single(HD(j)->pdev, HD(j)->cp[i].cp_dma_addr = pci_map_single(HD(j)->pdev,
&HD(j)->cp[i], sizeof(struct mscp), PCI_DMA_BIDIRECTIONAL); &HD(j)->cp[i],
sizeof(struct mscp),
PCI_DMA_BIDIRECTIONAL);
for (i = 0; i < sh[j]->can_queue; i++) for (i = 0; i < sh[j]->can_queue; i++) {
if (! ((&HD(j)->cp[i])->sglist = kmalloc( size_t sz = sh[j]->sg_tablesize *sizeof(struct sg_list);
sh[j]->sg_tablesize * sizeof(struct sg_list), unsigned int gfp_mask = (sh[j]->unchecked_isa_dma ? GFP_DMA : 0) | GFP_ATOMIC;
(sh[j]->unchecked_isa_dma ? GFP_DMA : 0) | GFP_ATOMIC))) { (&HD(j)->cp[i])->sglist = kmalloc(sz, gfp_mask);
printk("%s: kmalloc SGlist failed, mbox %d, detaching.\n", BN(j), i); if (!(&HD(j)->cp[i])->sglist) {
printk
("%s: kmalloc SGlist failed, mbox %d, detaching.\n",
BN(j), i);
goto release; goto release;
} }
}
if (! (HD(j)->sp_cpu_addr = pci_alloc_consistent(HD(j)->pdev, if (!(HD(j)->sp_cpu_addr = pci_alloc_consistent(HD(j)->pdev,
sizeof(struct mssp), &HD(j)->sp_dma_addr))) { sizeof(struct mssp),
&HD(j)->sp_dma_addr))) {
printk("%s: pci_alloc_consistent failed, detaching.\n", BN(j)); printk("%s: pci_alloc_consistent failed, detaching.\n", BN(j));
goto release; goto release;
} }
...@@ -1330,14 +1378,17 @@ static int port_detect \ ...@@ -1330,14 +1378,17 @@ static int port_detect \
if (max_queue_depth > MAX_TAGGED_CMD_PER_LUN) if (max_queue_depth > MAX_TAGGED_CMD_PER_LUN)
max_queue_depth = MAX_TAGGED_CMD_PER_LUN; max_queue_depth = MAX_TAGGED_CMD_PER_LUN;
if (max_queue_depth < MAX_CMD_PER_LUN) max_queue_depth = MAX_CMD_PER_LUN; if (max_queue_depth < MAX_CMD_PER_LUN)
max_queue_depth = MAX_CMD_PER_LUN;
if (tag_mode != TAG_DISABLED && tag_mode != TAG_SIMPLE) if (tag_mode != TAG_DISABLED && tag_mode != TAG_SIMPLE)
tag_mode = TAG_ORDERED; tag_mode = TAG_ORDERED;
if (j == 0) { if (j == 0) {
printk("EATA/DMA 2.0x: Copyright (C) 1994-2003 Dario Ballabio.\n"); printk
printk("%s config options -> tm:%d, lc:%c, mq:%d, rs:%c, et:%c, "\ ("EATA/DMA 2.0x: Copyright (C) 1994-2003 Dario Ballabio.\n");
printk
("%s config options -> tm:%d, lc:%c, mq:%d, rs:%c, et:%c, "
"ip:%c, ep:%c, pp:%c.\n", driver_name, tag_mode, "ip:%c, ep:%c, pp:%c.\n", driver_name, tag_mode,
YESNO(linked_comm), max_queue_depth, YESNO(rev_scan), YESNO(linked_comm), max_queue_depth, YESNO(rev_scan),
YESNO(ext_tran), YESNO(isa_probe), YESNO(eisa_probe), YESNO(ext_tran), YESNO(isa_probe), YESNO(eisa_probe),
...@@ -1345,11 +1396,13 @@ static int port_detect \ ...@@ -1345,11 +1396,13 @@ static int port_detect \
} }
printk("%s: 2.0%c, %s 0x%03lx, IRQ %u, %s, SG %d, MB %d.\n", printk("%s: 2.0%c, %s 0x%03lx, IRQ %u, %s, SG %d, MB %d.\n",
BN(j), HD(j)->protocol_rev, bus_type, (unsigned long)sh[j]->io_port, BN(j), HD(j)->protocol_rev, bus_type,
sh[j]->irq, dma_name, sh[j]->sg_tablesize, sh[j]->can_queue); (unsigned long)sh[j]->io_port, sh[j]->irq, dma_name,
sh[j]->sg_tablesize, sh[j]->can_queue);
if (sh[j]->max_id > 8 || sh[j]->max_lun > 8) if (sh[j]->max_id > 8 || sh[j]->max_lun > 8)
printk("%s: wide SCSI support enabled, max_id %u, max_lun %u.\n", printk
("%s: wide SCSI support enabled, max_id %u, max_lun %u.\n",
BN(j), sh[j]->max_id, sh[j]->max_lun); BN(j), sh[j]->max_id, sh[j]->max_lun);
for (i = 0; i <= sh[j]->max_channel; i++) for (i = 0; i <= sh[j]->max_channel; i++)
...@@ -1357,55 +1410,59 @@ static int port_detect \ ...@@ -1357,55 +1410,59 @@ static int port_detect \
BN(j), i, info.host_addr[3 - i]); BN(j), i, info.host_addr[3 - i]);
#if defined(DEBUG_DETECT) #if defined(DEBUG_DETECT)
printk("%s: Vers. 0x%x, ocs %u, tar %u, trnxfr %u, more %u, SYNC 0x%x, "\ printk("%s: Vers. 0x%x, ocs %u, tar %u, trnxfr %u, more %u, SYNC 0x%x, "
"sec. %u, infol %d, cpl %d spl %d.\n", name, info.version, "sec. %u, infol %d, cpl %d spl %d.\n", name, info.version,
info.ocsena, info.tarsup, info.trnxfr, info.morsup, info.sync, info.ocsena, info.tarsup, info.trnxfr, info.morsup, info.sync,
info.second, info.data_len, info.cp_len, info.second, info.data_len, info.cp_len, info.sp_len);
info.sp_len);
if (protocol_rev == 'B' || protocol_rev == 'C') if (protocol_rev == 'B' || protocol_rev == 'C')
printk("%s: isaena %u, forcaddr %u, max_id %u, max_chan %u, "\ printk("%s: isaena %u, forcaddr %u, max_id %u, max_chan %u, "
"large_sg %u, res1 %u.\n", name, info.isaena, info.forcaddr, "large_sg %u, res1 %u.\n", name, info.isaena,
info.max_id, info.max_chan, info.large_sg, info.res1); info.forcaddr, info.max_id, info.max_chan, info.large_sg,
info.res1);
if (protocol_rev == 'C') if (protocol_rev == 'C')
printk("%s: max_lun %u, m1 %u, idquest %u, pci %u, eisa %u, "\ printk("%s: max_lun %u, m1 %u, idquest %u, pci %u, eisa %u, "
"raidnum %u.\n", name, info.max_lun, info.m1, info.idquest, "raidnum %u.\n", name, info.max_lun, info.m1,
info.pci, info.eisa, info.raidnum); info.idquest, info.pci, info.eisa, info.raidnum);
#endif #endif
if (HD(j)->pdev) { if (HD(j)->pdev) {
pci_set_master(HD(j)->pdev); pci_set_master(HD(j)->pdev);
if (pci_set_dma_mask(HD(j)->pdev, 0xffffffff)) if (pci_set_dma_mask(HD(j)->pdev, 0xffffffff))
printk("%s: warning, pci_set_dma_mask failed.\n", BN(j)); printk("%s: warning, pci_set_dma_mask failed.\n",
BN(j));
} }
return 1; return 1;
freedma: freedma:
if (subversion == ISA) free_dma(dma_channel); if (subversion == ISA)
freeirq: free_dma(dma_channel);
freeirq:
free_irq(irq, &sha[j]); free_irq(irq, &sha[j]);
freelock: freelock:
spin_unlock_irq(&driver_lock); spin_unlock_irq(&driver_lock);
release_region(port_base, REGION_SIZE); release_region(port_base, REGION_SIZE);
fail: fail:
return 0; return 0;
release: release:
eata2x_release(sh[j]); eata2x_release(sh[j]);
return 0; return 0;
} }
static void internal_setup(char *str, int *ints) { static void internal_setup(char *str, int *ints)
{
int i, argc = ints[0]; int i, argc = ints[0];
char *cur = str, *pc; char *cur = str, *pc;
if (argc > 0) { if (argc > 0) {
if (argc > MAX_INT_PARAM)
argc = MAX_INT_PARAM;
if (argc > MAX_INT_PARAM) argc = MAX_INT_PARAM; for (i = 0; i < argc; i++)
io_port[i] = ints[i + 1];
for (i = 0; i < argc; i++) io_port[i] = ints[i + 1];
io_port[i] = 0; io_port[i] = 0;
setup_done = 1; setup_done = 1;
...@@ -1414,28 +1471,43 @@ static void internal_setup(char *str, int *ints) { ...@@ -1414,28 +1471,43 @@ static void internal_setup(char *str, int *ints) {
while (cur && (pc = strchr(cur, ':'))) { while (cur && (pc = strchr(cur, ':'))) {
int val = 0, c = *++pc; int val = 0, c = *++pc;
if (c == 'n' || c == 'N') val = 0; if (c == 'n' || c == 'N')
else if (c == 'y' || c == 'Y') val = 1; val = 0;
else val = (int) simple_strtoul(pc, NULL, 0); else if (c == 'y' || c == 'Y')
val = 1;
if (!strncmp(cur, "lc:", 3)) linked_comm = val; else
else if (!strncmp(cur, "tm:", 3)) tag_mode = val; val = (int)simple_strtoul(pc, NULL, 0);
else if (!strncmp(cur, "tc:", 3)) tag_mode = val;
else if (!strncmp(cur, "mq:", 3)) max_queue_depth = val; if (!strncmp(cur, "lc:", 3))
else if (!strncmp(cur, "ls:", 3)) link_statistics = val; linked_comm = val;
else if (!strncmp(cur, "et:", 3)) ext_tran = val; else if (!strncmp(cur, "tm:", 3))
else if (!strncmp(cur, "rs:", 3)) rev_scan = val; tag_mode = val;
else if (!strncmp(cur, "ip:", 3)) isa_probe = val; else if (!strncmp(cur, "tc:", 3))
else if (!strncmp(cur, "ep:", 3)) eisa_probe = val; tag_mode = val;
else if (!strncmp(cur, "pp:", 3)) pci_probe = val; else if (!strncmp(cur, "mq:", 3))
max_queue_depth = val;
if ((cur = strchr(cur, ','))) ++cur; else if (!strncmp(cur, "ls:", 3))
link_statistics = val;
else if (!strncmp(cur, "et:", 3))
ext_tran = val;
else if (!strncmp(cur, "rs:", 3))
rev_scan = val;
else if (!strncmp(cur, "ip:", 3))
isa_probe = val;
else if (!strncmp(cur, "ep:", 3))
eisa_probe = val;
else if (!strncmp(cur, "pp:", 3))
pci_probe = val;
if ((cur = strchr(cur, ',')))
++cur;
} }
return; return;
} }
static int option_setup(char *str) { static int option_setup(char *str)
{
int ints[MAX_INT_PARAM]; int ints[MAX_INT_PARAM];
char *cur = str; char *cur = str;
int i = 1; int i = 1;
...@@ -1443,7 +1515,8 @@ static int option_setup(char *str) { ...@@ -1443,7 +1515,8 @@ static int option_setup(char *str) {
while (cur && isdigit(*cur) && i <= MAX_INT_PARAM) { while (cur && isdigit(*cur) && i <= MAX_INT_PARAM) {
ints[i++] = simple_strtoul(cur, NULL, 0); ints[i++] = simple_strtoul(cur, NULL, 0);
if ((cur = strchr(cur, ',')) != NULL) cur++; if ((cur = strchr(cur, ',')) != NULL)
cur++;
} }
ints[0] = i - 1; ints[0] = i - 1;
...@@ -1451,29 +1524,28 @@ static int option_setup(char *str) { ...@@ -1451,29 +1524,28 @@ static int option_setup(char *str) {
return 1; return 1;
} }
static void add_pci_ports(void) { static void add_pci_ports(void)
{
#if defined(CONFIG_PCI) #if defined(CONFIG_PCI)
unsigned int addr, k; unsigned int addr, k;
struct pci_dev *dev = NULL; struct pci_dev *dev = NULL;
for (k = 0; k < MAX_PCI; k++) { for (k = 0; k < MAX_PCI; k++) {
if (!(dev = pci_get_class(PCI_CLASS_STORAGE_SCSI << 8, dev))) break; if (!(dev = pci_get_class(PCI_CLASS_STORAGE_SCSI << 8, dev)))
break;
if (pci_enable_device (dev)) {
if (pci_enable_device(dev)) {
#if defined(DEBUG_PCI_DETECT) #if defined(DEBUG_PCI_DETECT)
printk("%s: detect, bus %d, devfn 0x%x, pci_enable_device failed.\n", printk
("%s: detect, bus %d, devfn 0x%x, pci_enable_device failed.\n",
driver_name, dev->bus->number, dev->devfn); driver_name, dev->bus->number, dev->devfn);
#endif #endif
continue; continue;
} }
addr = pci_resource_start (dev, 0); addr = pci_resource_start(dev, 0);
#if defined(DEBUG_PCI_DETECT) #if defined(DEBUG_PCI_DETECT)
printk("%s: detect, seq. %d, bus %d, devfn 0x%x, addr 0x%x.\n", printk("%s: detect, seq. %d, bus %d, devfn 0x%x, addr 0x%x.\n",
...@@ -1487,63 +1559,75 @@ static void add_pci_ports(void) { ...@@ -1487,63 +1559,75 @@ static void add_pci_ports(void) {
pci_dev_put(dev); pci_dev_put(dev);
#endif /* end CONFIG_PCI */ #endif /* end CONFIG_PCI */
return;
} }
static int eata2x_detect(struct scsi_host_template *tpnt) { static int eata2x_detect(struct scsi_host_template *tpnt)
{
unsigned int j = 0, k; unsigned int j = 0, k;
tpnt->proc_name = "eata2x"; tpnt->proc_name = "eata2x";
if(strlen(boot_options)) option_setup(boot_options); if (strlen(boot_options))
option_setup(boot_options);
#if defined(MODULE) #if defined(MODULE)
/* io_port could have been modified when loading as a module */ /* io_port could have been modified when loading as a module */
if(io_port[0] != SKIP) { if (io_port[0] != SKIP) {
setup_done = 1; setup_done = 1;
io_port[MAX_INT_PARAM] = 0; io_port[MAX_INT_PARAM] = 0;
} }
#endif #endif
for (k = 0; k < MAX_BOARDS + 1; k++) sh[k] = NULL; for (k = 0; k < MAX_BOARDS + 1; k++)
sh[k] = NULL;
for (k = MAX_INT_PARAM; io_port[k]; k++) for (k = MAX_INT_PARAM; io_port[k]; k++)
if (io_port[k] == SKIP) continue; if (io_port[k] == SKIP)
continue;
else if (io_port[k] <= MAX_ISA_ADDR) { else if (io_port[k] <= MAX_ISA_ADDR) {
if (!isa_probe) io_port[k] = SKIP; if (!isa_probe)
} io_port[k] = SKIP;
else if (io_port[k] >= MIN_EISA_ADDR && io_port[k] <= MAX_EISA_ADDR) { } else if (io_port[k] >= MIN_EISA_ADDR
if (!eisa_probe) io_port[k] = SKIP; && io_port[k] <= MAX_EISA_ADDR) {
if (!eisa_probe)
io_port[k] = SKIP;
} }
if (pci_probe) { if (pci_probe) {
if (!setup_done) add_pci_ports(); if (!setup_done)
else enable_pci_ports(); add_pci_ports();
else
enable_pci_ports();
} }
for (k = 0; io_port[k]; k++) { for (k = 0; io_port[k]; k++) {
if (io_port[k] == SKIP) continue; if (io_port[k] == SKIP)
continue;
if (j < MAX_BOARDS && port_detect(io_port[k], j, tpnt)) j++; if (j < MAX_BOARDS && port_detect(io_port[k], j, tpnt))
j++;
} }
num_boards = j; num_boards = j;
return j; return j;
} }
static void map_dma(unsigned int i, unsigned int j) { static void map_dma(unsigned int i, unsigned int j)
{
unsigned int k, count, pci_dir; unsigned int k, count, pci_dir;
struct scatterlist *sgpnt; struct scatterlist *sgpnt;
struct mscp *cpp; struct mscp *cpp;
struct scsi_cmnd *SCpnt; struct scsi_cmnd *SCpnt;
cpp = &HD(j)->cp[i]; SCpnt = cpp->SCpnt; cpp = &HD(j)->cp[i];
SCpnt = cpp->SCpnt;
pci_dir = SCpnt->sc_data_direction; pci_dir = SCpnt->sc_data_direction;
if (SCpnt->sense_buffer) if (SCpnt->sense_buffer)
cpp->sense_addr = H2DEV(pci_map_single(HD(j)->pdev, SCpnt->sense_buffer, cpp->sense_addr =
H2DEV(pci_map_single
(HD(j)->pdev, SCpnt->sense_buffer,
sizeof SCpnt->sense_buffer, PCI_DMA_FROMDEVICE)); sizeof SCpnt->sense_buffer, PCI_DMA_FROMDEVICE));
cpp->sense_len = sizeof SCpnt->sense_buffer; cpp->sense_len = sizeof SCpnt->sense_buffer;
...@@ -1551,17 +1635,22 @@ static void map_dma(unsigned int i, unsigned int j) { ...@@ -1551,17 +1635,22 @@ static void map_dma(unsigned int i, unsigned int j) {
if (!SCpnt->use_sg) { if (!SCpnt->use_sg) {
/* If we get here with PCI_DMA_NONE, pci_map_single triggers a BUG() */ /* If we get here with PCI_DMA_NONE, pci_map_single triggers a BUG() */
if (!SCpnt->request_bufflen) pci_dir = PCI_DMA_BIDIRECTIONAL; if (!SCpnt->request_bufflen)
pci_dir = PCI_DMA_BIDIRECTIONAL;
if (SCpnt->request_buffer) if (SCpnt->request_buffer)
cpp->data_address = H2DEV(pci_map_single(HD(j)->pdev, cpp->data_address = H2DEV(pci_map_single(HD(j)->pdev,
SCpnt->request_buffer, SCpnt->request_bufflen, pci_dir)); SCpnt->
request_buffer,
SCpnt->
request_bufflen,
pci_dir));
cpp->data_len = H2DEV(SCpnt->request_bufflen); cpp->data_len = H2DEV(SCpnt->request_bufflen);
return; return;
} }
sgpnt = (struct scatterlist *) SCpnt->request_buffer; sgpnt = (struct scatterlist *)SCpnt->request_buffer;
count = pci_map_sg(HD(j)->pdev, sgpnt, SCpnt->use_sg, pci_dir); count = pci_map_sg(HD(j)->pdev, sgpnt, SCpnt->use_sg, pci_dir);
for (k = 0; k < count; k++) { for (k = 0; k < count; k++) {
...@@ -1571,16 +1660,20 @@ static void map_dma(unsigned int i, unsigned int j) { ...@@ -1571,16 +1660,20 @@ static void map_dma(unsigned int i, unsigned int j) {
cpp->sg = 1; cpp->sg = 1;
cpp->data_address = H2DEV(pci_map_single(HD(j)->pdev, cpp->sglist, cpp->data_address = H2DEV(pci_map_single(HD(j)->pdev, cpp->sglist,
SCpnt->use_sg * sizeof(struct sg_list), pci_dir)); SCpnt->use_sg *
sizeof(struct sg_list),
pci_dir));
cpp->data_len = H2DEV((SCpnt->use_sg * sizeof(struct sg_list))); cpp->data_len = H2DEV((SCpnt->use_sg * sizeof(struct sg_list)));
} }
static void unmap_dma(unsigned int i, unsigned int j) { static void unmap_dma(unsigned int i, unsigned int j)
{
unsigned int pci_dir; unsigned int pci_dir;
struct mscp *cpp; struct mscp *cpp;
struct scsi_cmnd *SCpnt; struct scsi_cmnd *SCpnt;
cpp = &HD(j)->cp[i]; SCpnt = cpp->SCpnt; cpp = &HD(j)->cp[i];
SCpnt = cpp->SCpnt;
pci_dir = SCpnt->sc_data_direction; pci_dir = SCpnt->sc_data_direction;
if (DEV2H(cpp->sense_addr)) if (DEV2H(cpp->sense_addr))
...@@ -1588,39 +1681,47 @@ static void unmap_dma(unsigned int i, unsigned int j) { ...@@ -1588,39 +1681,47 @@ static void unmap_dma(unsigned int i, unsigned int j) {
DEV2H(cpp->sense_len), PCI_DMA_FROMDEVICE); DEV2H(cpp->sense_len), PCI_DMA_FROMDEVICE);
if (SCpnt->use_sg) if (SCpnt->use_sg)
pci_unmap_sg(HD(j)->pdev, SCpnt->request_buffer, SCpnt->use_sg, pci_dir); pci_unmap_sg(HD(j)->pdev, SCpnt->request_buffer, SCpnt->use_sg,
pci_dir);
if (!DEV2H(cpp->data_len)) pci_dir = PCI_DMA_BIDIRECTIONAL; if (!DEV2H(cpp->data_len))
pci_dir = PCI_DMA_BIDIRECTIONAL;
if (DEV2H(cpp->data_address)) if (DEV2H(cpp->data_address))
pci_unmap_single(HD(j)->pdev, DEV2H(cpp->data_address), pci_unmap_single(HD(j)->pdev, DEV2H(cpp->data_address),
DEV2H(cpp->data_len), pci_dir); DEV2H(cpp->data_len), pci_dir);
} }
static void sync_dma(unsigned int i, unsigned int j) { static void sync_dma(unsigned int i, unsigned int j)
{
unsigned int pci_dir; unsigned int pci_dir;
struct mscp *cpp; struct mscp *cpp;
struct scsi_cmnd *SCpnt; struct scsi_cmnd *SCpnt;
cpp = &HD(j)->cp[i]; SCpnt = cpp->SCpnt; cpp = &HD(j)->cp[i];
SCpnt = cpp->SCpnt;
pci_dir = SCpnt->sc_data_direction; pci_dir = SCpnt->sc_data_direction;
if (DEV2H(cpp->sense_addr)) if (DEV2H(cpp->sense_addr))
pci_dma_sync_single_for_cpu(HD(j)->pdev, DEV2H(cpp->sense_addr), pci_dma_sync_single_for_cpu(HD(j)->pdev, DEV2H(cpp->sense_addr),
DEV2H(cpp->sense_len), PCI_DMA_FROMDEVICE); DEV2H(cpp->sense_len),
PCI_DMA_FROMDEVICE);
if (SCpnt->use_sg) if (SCpnt->use_sg)
pci_dma_sync_sg_for_cpu(HD(j)->pdev, SCpnt->request_buffer, pci_dma_sync_sg_for_cpu(HD(j)->pdev, SCpnt->request_buffer,
SCpnt->use_sg, pci_dir); SCpnt->use_sg, pci_dir);
if (!DEV2H(cpp->data_len)) pci_dir = PCI_DMA_BIDIRECTIONAL; if (!DEV2H(cpp->data_len))
pci_dir = PCI_DMA_BIDIRECTIONAL;
if (DEV2H(cpp->data_address)) if (DEV2H(cpp->data_address))
pci_dma_sync_single_for_cpu(HD(j)->pdev, DEV2H(cpp->data_address), pci_dma_sync_single_for_cpu(HD(j)->pdev,
DEV2H(cpp->data_address),
DEV2H(cpp->data_len), pci_dir); DEV2H(cpp->data_len), pci_dir);
} }
static void scsi_to_dev_dir(unsigned int i, unsigned int j) { static void scsi_to_dev_dir(unsigned int i, unsigned int j)
{
unsigned int k; unsigned int k;
static const unsigned char data_out_cmds[] = { static const unsigned char data_out_cmds[] = {
...@@ -1638,19 +1739,18 @@ static void scsi_to_dev_dir(unsigned int i, unsigned int j) { ...@@ -1638,19 +1739,18 @@ static void scsi_to_dev_dir(unsigned int i, unsigned int j) {
struct mscp *cpp; struct mscp *cpp;
struct scsi_cmnd *SCpnt; struct scsi_cmnd *SCpnt;
cpp = &HD(j)->cp[i]; SCpnt = cpp->SCpnt; cpp = &HD(j)->cp[i];
SCpnt = cpp->SCpnt;
if (SCpnt->sc_data_direction == DMA_FROM_DEVICE) { if (SCpnt->sc_data_direction == DMA_FROM_DEVICE) {
cpp->din = 1; cpp->din = 1;
cpp->dout = 0; cpp->dout = 0;
return; return;
} } else if (SCpnt->sc_data_direction == DMA_TO_DEVICE) {
else if (SCpnt->sc_data_direction == DMA_TO_DEVICE) {
cpp->din = 0; cpp->din = 0;
cpp->dout = 1; cpp->dout = 1;
return; return;
} } else if (SCpnt->sc_data_direction == DMA_NONE) {
else if (SCpnt->sc_data_direction == DMA_NONE) {
cpp->din = 0; cpp->din = 0;
cpp->dout = 0; cpp->dout = 0;
return; return;
...@@ -1674,12 +1774,14 @@ static void scsi_to_dev_dir(unsigned int i, unsigned int j) { ...@@ -1674,12 +1774,14 @@ static void scsi_to_dev_dir(unsigned int i, unsigned int j) {
} }
static int eata2x_queuecommand(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) { static int eata2x_queuecommand(struct scsi_cmnd *SCpnt,
void (*done) (struct scsi_cmnd *))
{
unsigned int i, j, k; unsigned int i, j, k;
struct mscp *cpp; struct mscp *cpp;
/* j is the board number */ /* j is the board number */
j = ((struct hostdata *) SCpnt->device->host->hostdata)->board_number; j = ((struct hostdata *)SCpnt->device->host->hostdata)->board_number;
if (SCpnt->host_scribble) if (SCpnt->host_scribble)
panic("%s: qcomm, pid %ld, SCpnt %p already active.\n", panic("%s: qcomm, pid %ld, SCpnt %p already active.\n",
...@@ -1691,7 +1793,8 @@ static int eata2x_queuecommand(struct scsi_cmnd *SCpnt, void (*done)(struct scsi ...@@ -1691,7 +1793,8 @@ static int eata2x_queuecommand(struct scsi_cmnd *SCpnt, void (*done)(struct scsi
for (k = 0; k < sh[j]->can_queue; k++, i++) { for (k = 0; k < sh[j]->can_queue; k++, i++) {
if (i >= sh[j]->can_queue) i = 0; if (i >= sh[j]->can_queue)
i = 0;
if (HD(j)->cp_stat[i] == FREE) { if (HD(j)->cp_stat[i] == FREE) {
HD(j)->last_cp_used = i; HD(j)->last_cp_used = i;
...@@ -1714,16 +1817,18 @@ static int eata2x_queuecommand(struct scsi_cmnd *SCpnt, void (*done)(struct scsi ...@@ -1714,16 +1817,18 @@ static int eata2x_queuecommand(struct scsi_cmnd *SCpnt, void (*done)(struct scsi
SCpnt->scsi_done = done; SCpnt->scsi_done = done;
cpp->cpp_index = i; cpp->cpp_index = i;
SCpnt->host_scribble = (unsigned char *) &cpp->cpp_index; SCpnt->host_scribble = (unsigned char *)&cpp->cpp_index;
if (do_trace) printk("%s: qcomm, mbox %d, target %d.%d:%d, pid %ld.\n", if (do_trace)
printk("%s: qcomm, mbox %d, target %d.%d:%d, pid %ld.\n",
BN(j), i, SCpnt->device->channel, SCpnt->device->id, BN(j), i, SCpnt->device->channel, SCpnt->device->id,
SCpnt->device->lun, SCpnt->pid); SCpnt->device->lun, SCpnt->pid);
cpp->reqsen = 1; cpp->reqsen = 1;
cpp->dispri = 1; cpp->dispri = 1;
#if 0 #if 0
if (SCpnt->device->type == TYPE_TAPE) cpp->hbaci = 1; if (SCpnt->device->type == TYPE_TAPE)
cpp->hbaci = 1;
#endif #endif
cpp->one = 1; cpp->one = 1;
cpp->channel = SCpnt->device->channel; cpp->channel = SCpnt->device->channel;
...@@ -1750,7 +1855,8 @@ static int eata2x_queuecommand(struct scsi_cmnd *SCpnt, void (*done)(struct scsi ...@@ -1750,7 +1855,8 @@ static int eata2x_queuecommand(struct scsi_cmnd *SCpnt, void (*done)(struct scsi
unmap_dma(i, j); unmap_dma(i, j);
SCpnt->host_scribble = NULL; SCpnt->host_scribble = NULL;
printk("%s: qcomm, target %d.%d:%d, pid %ld, adapter busy.\n", printk("%s: qcomm, target %d.%d:%d, pid %ld, adapter busy.\n",
BN(j), SCpnt->device->channel, SCpnt->device->id, SCpnt->device->lun, SCpnt->pid); BN(j), SCpnt->device->channel, SCpnt->device->id,
SCpnt->device->lun, SCpnt->pid);
return 1; return 1;
} }
...@@ -1758,20 +1864,23 @@ static int eata2x_queuecommand(struct scsi_cmnd *SCpnt, void (*done)(struct scsi ...@@ -1758,20 +1864,23 @@ static int eata2x_queuecommand(struct scsi_cmnd *SCpnt, void (*done)(struct scsi
return 0; return 0;
} }
static int eata2x_eh_abort(struct scsi_cmnd *SCarg) { static int eata2x_eh_abort(struct scsi_cmnd *SCarg)
{
unsigned int i, j; unsigned int i, j;
j = ((struct hostdata *) SCarg->device->host->hostdata)->board_number; j = ((struct hostdata *)SCarg->device->host->hostdata)->board_number;
if (SCarg->host_scribble == NULL) { if (SCarg->host_scribble == NULL) {
printk("%s: abort, target %d.%d:%d, pid %ld inactive.\n", printk("%s: abort, target %d.%d:%d, pid %ld inactive.\n",
BN(j), SCarg->device->channel, SCarg->device->id, SCarg->device->lun, SCarg->pid); BN(j), SCarg->device->channel, SCarg->device->id,
SCarg->device->lun, SCarg->pid);
return SUCCESS; return SUCCESS;
} }
i = *(unsigned int *)SCarg->host_scribble; i = *(unsigned int *)SCarg->host_scribble;
printk("%s: abort, mbox %d, target %d.%d:%d, pid %ld.\n", printk("%s: abort, mbox %d, target %d.%d:%d, pid %ld.\n",
BN(j), i, SCarg->device->channel, SCarg->device->id, SCarg->device->lun, SCarg->pid); BN(j), i, SCarg->device->channel, SCarg->device->id,
SCarg->device->lun, SCarg->pid);
if (i >= sh[j]->can_queue) if (i >= sh[j]->can_queue)
panic("%s: abort, invalid SCarg->host_scribble.\n", BN(j)); panic("%s: abort, invalid SCarg->host_scribble.\n", BN(j));
...@@ -1794,13 +1903,15 @@ static int eata2x_eh_abort(struct scsi_cmnd *SCarg) { ...@@ -1794,13 +1903,15 @@ static int eata2x_eh_abort(struct scsi_cmnd *SCarg) {
BN(j), i, SCarg, HD(j)->cp[i].SCpnt); BN(j), i, SCarg, HD(j)->cp[i].SCpnt);
if (inb(sh[j]->io_port + REG_AUX_STATUS) & IRQ_ASSERTED) if (inb(sh[j]->io_port + REG_AUX_STATUS) & IRQ_ASSERTED)
printk("%s: abort, mbox %d, interrupt pending.\n", BN(j), i); printk("%s: abort, mbox %d, interrupt pending.\n",
BN(j), i);
if (SCarg->eh_state == SCSI_STATE_TIMEOUT) { if (SCarg->eh_state == SCSI_STATE_TIMEOUT) {
unmap_dma(i, j); unmap_dma(i, j);
SCarg->host_scribble = NULL; SCarg->host_scribble = NULL;
HD(j)->cp_stat[i] = FREE; HD(j)->cp_stat[i] = FREE;
printk("%s, abort, mbox %d, eh_state timeout, pid %ld.\n", printk
("%s, abort, mbox %d, eh_state timeout, pid %ld.\n",
BN(j), i, SCarg->pid); BN(j), i, SCarg->pid);
return SUCCESS; return SUCCESS;
} }
...@@ -1832,14 +1943,16 @@ static int eata2x_eh_abort(struct scsi_cmnd *SCarg) { ...@@ -1832,14 +1943,16 @@ static int eata2x_eh_abort(struct scsi_cmnd *SCarg) {
panic("%s: abort, mbox %d, invalid cp_stat.\n", BN(j), i); panic("%s: abort, mbox %d, invalid cp_stat.\n", BN(j), i);
} }
static int eata2x_eh_host_reset(struct scsi_cmnd *SCarg) { static int eata2x_eh_host_reset(struct scsi_cmnd *SCarg)
{
unsigned int i, j, time, k, c, limit = 0; unsigned int i, j, time, k, c, limit = 0;
int arg_done = 0; int arg_done = 0;
struct scsi_cmnd *SCpnt; struct scsi_cmnd *SCpnt;
j = ((struct hostdata *) SCarg->device->host->hostdata)->board_number; j = ((struct hostdata *)SCarg->device->host->hostdata)->board_number;
printk("%s: reset, enter, target %d.%d:%d, pid %ld.\n", printk("%s: reset, enter, target %d.%d:%d, pid %ld.\n",
BN(j), SCarg->device->channel, SCarg->device->id, SCarg->device->lun, SCarg->pid); BN(j), SCarg->device->channel, SCarg->device->id,
SCarg->device->lun, SCarg->pid);
if (SCarg->host_scribble == NULL) if (SCarg->host_scribble == NULL)
printk("%s: reset, pid %ld inactive.\n", BN(j), SCarg->pid); printk("%s: reset, pid %ld inactive.\n", BN(j), SCarg->pid);
...@@ -1864,11 +1977,13 @@ static int eata2x_eh_host_reset(struct scsi_cmnd *SCarg) { ...@@ -1864,11 +1977,13 @@ static int eata2x_eh_host_reset(struct scsi_cmnd *SCarg) {
for (i = 0; i < sh[j]->can_queue; i++) { for (i = 0; i < sh[j]->can_queue; i++) {
if (HD(j)->cp_stat[i] == FREE) continue; if (HD(j)->cp_stat[i] == FREE)
continue;
if (HD(j)->cp_stat[i] == LOCKED) { if (HD(j)->cp_stat[i] == LOCKED) {
HD(j)->cp_stat[i] = FREE; HD(j)->cp_stat[i] = FREE;
printk("%s: reset, locked mbox %d forced free.\n", BN(j), i); printk("%s: reset, locked mbox %d forced free.\n",
BN(j), i);
continue; continue;
} }
...@@ -1891,12 +2006,15 @@ static int eata2x_eh_host_reset(struct scsi_cmnd *SCarg) { ...@@ -1891,12 +2006,15 @@ static int eata2x_eh_host_reset(struct scsi_cmnd *SCarg) {
panic("%s: reset, mbox %d, garbled SCpnt.\n", BN(j), i); panic("%s: reset, mbox %d, garbled SCpnt.\n", BN(j), i);
if (*(unsigned int *)SCpnt->host_scribble != i) if (*(unsigned int *)SCpnt->host_scribble != i)
panic("%s: reset, mbox %d, index mismatch.\n", BN(j), i); panic("%s: reset, mbox %d, index mismatch.\n", BN(j),
i);
if (SCpnt->scsi_done == NULL) if (SCpnt->scsi_done == NULL)
panic("%s: reset, mbox %d, SCpnt->scsi_done == NULL.\n", BN(j), i); panic("%s: reset, mbox %d, SCpnt->scsi_done == NULL.\n",
BN(j), i);
if (SCpnt == SCarg) arg_done = 1; if (SCpnt == SCarg)
arg_done = 1;
} }
if (do_dma(sh[j]->io_port, 0, RESET_PIO)) { if (do_dma(sh[j]->io_port, 0, RESET_PIO)) {
...@@ -1914,7 +2032,8 @@ static int eata2x_eh_host_reset(struct scsi_cmnd *SCarg) { ...@@ -1914,7 +2032,8 @@ static int eata2x_eh_host_reset(struct scsi_cmnd *SCarg) {
spin_unlock_irq(sh[j]->host_lock); spin_unlock_irq(sh[j]->host_lock);
time = jiffies; time = jiffies;
while ((jiffies - time) < (10 * HZ) && limit++ < 200000) udelay(100L); while ((jiffies - time) < (10 * HZ) && limit++ < 200000)
udelay(100L);
spin_lock_irq(sh[j]->host_lock); spin_lock_irq(sh[j]->host_lock);
printk("%s: reset, interrupts disabled, loops %d.\n", BN(j), limit); printk("%s: reset, interrupts disabled, loops %d.\n", BN(j), limit);
...@@ -1930,7 +2049,8 @@ static int eata2x_eh_host_reset(struct scsi_cmnd *SCarg) { ...@@ -1930,7 +2049,8 @@ static int eata2x_eh_host_reset(struct scsi_cmnd *SCarg) {
/* This mailbox is still waiting for its interrupt */ /* This mailbox is still waiting for its interrupt */
HD(j)->cp_stat[i] = LOCKED; HD(j)->cp_stat[i] = LOCKED;
printk("%s, reset, mbox %d locked, DID_RESET, pid %ld done.\n", printk
("%s, reset, mbox %d locked, DID_RESET, pid %ld done.\n",
BN(j), i, SCpnt->pid); BN(j), i, SCpnt->pid);
} }
...@@ -1943,12 +2063,12 @@ static int eata2x_eh_host_reset(struct scsi_cmnd *SCarg) { ...@@ -1943,12 +2063,12 @@ static int eata2x_eh_host_reset(struct scsi_cmnd *SCarg) {
/* This mailbox was never queued to the adapter */ /* This mailbox was never queued to the adapter */
HD(j)->cp_stat[i] = FREE; HD(j)->cp_stat[i] = FREE;
printk("%s, reset, mbox %d aborting, DID_RESET, pid %ld done.\n", printk
("%s, reset, mbox %d aborting, DID_RESET, pid %ld done.\n",
BN(j), i, SCpnt->pid); BN(j), i, SCpnt->pid);
} }
else else
/* Any other mailbox has already been set free by interrupt */ /* Any other mailbox has already been set free by interrupt */
continue; continue;
...@@ -1958,14 +2078,17 @@ static int eata2x_eh_host_reset(struct scsi_cmnd *SCarg) { ...@@ -1958,14 +2078,17 @@ static int eata2x_eh_host_reset(struct scsi_cmnd *SCarg) {
HD(j)->in_reset = 0; HD(j)->in_reset = 0;
do_trace = 0; do_trace = 0;
if (arg_done) printk("%s: reset, exit, pid %ld done.\n", BN(j), SCarg->pid); if (arg_done)
else printk("%s: reset, exit.\n", BN(j)); printk("%s: reset, exit, pid %ld done.\n", BN(j), SCarg->pid);
else
printk("%s: reset, exit.\n", BN(j));
return SUCCESS; return SUCCESS;
} }
int eata2x_bios_param(struct scsi_device *sdev, struct block_device *bdev, int eata2x_bios_param(struct scsi_device *sdev, struct block_device *bdev,
sector_t capacity, int *dkinfo) { sector_t capacity, int *dkinfo)
{
unsigned int size = capacity; unsigned int size = capacity;
if (ext_tran || (scsicam_bios_param(bdev, capacity, dkinfo) < 0)) { if (ext_tran || (scsicam_bios_param(bdev, capacity, dkinfo) < 0)) {
...@@ -1973,9 +2096,8 @@ int eata2x_bios_param(struct scsi_device *sdev, struct block_device *bdev, ...@@ -1973,9 +2096,8 @@ int eata2x_bios_param(struct scsi_device *sdev, struct block_device *bdev,
dkinfo[1] = 63; dkinfo[1] = 63;
dkinfo[2] = size / (dkinfo[0] * dkinfo[1]); dkinfo[2] = size / (dkinfo[0] * dkinfo[1]);
} }
#if defined (DEBUG_GEOMETRY) #if defined (DEBUG_GEOMETRY)
printk ("%s: bios_param, head=%d, sec=%d, cyl=%d.\n", driver_name, printk("%s: bios_param, head=%d, sec=%d, cyl=%d.\n", driver_name,
dkinfo[0], dkinfo[1], dkinfo[2]); dkinfo[0], dkinfo[1], dkinfo[2]);
#endif #endif
...@@ -1983,7 +2105,8 @@ int eata2x_bios_param(struct scsi_device *sdev, struct block_device *bdev, ...@@ -1983,7 +2105,8 @@ int eata2x_bios_param(struct scsi_device *sdev, struct block_device *bdev,
} }
static void sort(unsigned long sk[], unsigned int da[], unsigned int n, static void sort(unsigned long sk[], unsigned int da[], unsigned int n,
unsigned int rev) { unsigned int rev)
{
unsigned int i, j, k, y; unsigned int i, j, k, y;
unsigned long x; unsigned long x;
...@@ -1992,23 +2115,29 @@ static void sort(unsigned long sk[], unsigned int da[], unsigned int n, ...@@ -1992,23 +2115,29 @@ static void sort(unsigned long sk[], unsigned int da[], unsigned int n,
for (j = k + 1; j < n; j++) for (j = k + 1; j < n; j++)
if (rev) { if (rev) {
if (sk[j] > sk[k]) k = j; if (sk[j] > sk[k])
} k = j;
else { } else {
if (sk[j] < sk[k]) k = j; if (sk[j] < sk[k])
k = j;
} }
if (k != i) { if (k != i) {
x = sk[k]; sk[k] = sk[i]; sk[i] = x; x = sk[k];
y = da[k]; da[k] = da[i]; da[i] = y; sk[k] = sk[i];
sk[i] = x;
y = da[k];
da[k] = da[i];
da[i] = y;
} }
} }
return; return;
} }
static int reorder(unsigned int j, unsigned long cursec, static int reorder(unsigned int j, unsigned long cursec,
unsigned int ihdlr, unsigned int il[], unsigned int n_ready) { unsigned int ihdlr, unsigned int il[], unsigned int n_ready)
{
struct scsi_cmnd *SCpnt; struct scsi_cmnd *SCpnt;
struct mscp *cpp; struct mscp *cpp;
unsigned int k, n; unsigned int k, n;
...@@ -2024,29 +2153,38 @@ static int reorder(unsigned int j, unsigned long cursec, ...@@ -2024,29 +2153,38 @@ static int reorder(unsigned int j, unsigned long cursec,
static unsigned long seeksorted = 0, seeknosort = 0; static unsigned long seeksorted = 0, seeknosort = 0;
if (link_statistics && !(++flushcount % link_statistics)) if (link_statistics && !(++flushcount % link_statistics))
printk("fc %d bc %d ic %d oc %d rc %d rs %d sc %d re %d"\ printk("fc %d bc %d ic %d oc %d rc %d rs %d sc %d re %d"
" av %ldK as %ldK.\n", flushcount, batchcount, inputcount, " av %ldK as %ldK.\n", flushcount, batchcount,
ovlcount, readycount, readysorted, sortcount, revcount, inputcount, ovlcount, readycount, readysorted, sortcount,
seeknosort / (readycount + 1), revcount, seeknosort / (readycount + 1),
seeksorted / (readycount + 1)); seeksorted / (readycount + 1));
if (n_ready <= 1) return 0; if (n_ready <= 1)
return 0;
for (n = 0; n < n_ready; n++) { for (n = 0; n < n_ready; n++) {
k = il[n]; cpp = &HD(j)->cp[k]; SCpnt = cpp->SCpnt; k = il[n];
cpp = &HD(j)->cp[k];
SCpnt = cpp->SCpnt;
if (!cpp->din) input_only = 0; if (!cpp->din)
input_only = 0;
if (SCpnt->request->sector < minsec) minsec = SCpnt->request->sector; if (SCpnt->request->sector < minsec)
if (SCpnt->request->sector > maxsec) maxsec = SCpnt->request->sector; minsec = SCpnt->request->sector;
if (SCpnt->request->sector > maxsec)
maxsec = SCpnt->request->sector;
sl[n] = SCpnt->request->sector; sl[n] = SCpnt->request->sector;
ioseek += SCpnt->request->nr_sectors; ioseek += SCpnt->request->nr_sectors;
if (!n) continue; if (!n)
continue;
if (sl[n] < sl[n - 1]) s = 0; if (sl[n] < sl[n - 1])
if (sl[n] > sl[n - 1]) r = 0; s = 0;
if (sl[n] > sl[n - 1])
r = 0;
if (link_statistics) { if (link_statistics) {
if (sl[n] > sl[n - 1]) if (sl[n] > sl[n - 1])
...@@ -2058,81 +2196,125 @@ static int reorder(unsigned int j, unsigned long cursec, ...@@ -2058,81 +2196,125 @@ static int reorder(unsigned int j, unsigned long cursec,
} }
if (link_statistics) { if (link_statistics) {
if (cursec > sl[0]) seek += cursec - sl[0]; else seek += sl[0] - cursec; if (cursec > sl[0])
seek += cursec - sl[0];
else
seek += sl[0] - cursec;
} }
if (cursec > ((maxsec + minsec) / 2)) rev = 1; if (cursec > ((maxsec + minsec) / 2))
rev = 1;
if (ioseek > ((maxsec - minsec) / 2)) rev = 0; if (ioseek > ((maxsec - minsec) / 2))
rev = 0;
if (!((rev && r) || (!rev && s))) sort(sl, il, n_ready, rev); if (!((rev && r) || (!rev && s)))
sort(sl, il, n_ready, rev);
if (!input_only) for (n = 0; n < n_ready; n++) { if (!input_only)
k = il[n]; cpp = &HD(j)->cp[k]; SCpnt = cpp->SCpnt; for (n = 0; n < n_ready; n++) {
ll[n] = SCpnt->request->nr_sectors; pl[n] = SCpnt->pid; k = il[n];
cpp = &HD(j)->cp[k];
SCpnt = cpp->SCpnt;
ll[n] = SCpnt->request->nr_sectors;
pl[n] = SCpnt->pid;
if (!n) continue; if (!n)
continue;
if ((sl[n] == sl[n - 1]) || (!rev && ((sl[n - 1] + ll[n - 1]) > sl[n])) if ((sl[n] == sl[n - 1])
|| (rev && ((sl[n] + ll[n]) > sl[n - 1]))) overlap = 1; || (!rev && ((sl[n - 1] + ll[n - 1]) > sl[n]))
|| (rev && ((sl[n] + ll[n]) > sl[n - 1])))
overlap = 1;
} }
if (overlap) sort(pl, il, n_ready, 0); if (overlap)
sort(pl, il, n_ready, 0);
if (link_statistics) { if (link_statistics) {
if (cursec > sl[0]) iseek = cursec - sl[0]; else iseek = sl[0] - cursec; if (cursec > sl[0])
batchcount++; readycount += n_ready; seeknosort += seek / 1024; iseek = cursec - sl[0];
if (input_only) inputcount++; else
if (overlap) { ovlcount++; seeksorted += iseek / 1024; } iseek = sl[0] - cursec;
else seeksorted += (iseek + maxsec - minsec) / 1024; batchcount++;
if (rev && !r) { revcount++; readysorted += n_ready; } readycount += n_ready;
if (!rev && !s) { sortcount++; readysorted += n_ready; } seeknosort += seek / 1024;
if (input_only)
inputcount++;
if (overlap) {
ovlcount++;
seeksorted += iseek / 1024;
} else
seeksorted += (iseek + maxsec - minsec) / 1024;
if (rev && !r) {
revcount++;
readysorted += n_ready;
}
if (!rev && !s) {
sortcount++;
readysorted += n_ready;
}
} }
#if defined(DEBUG_LINKED_COMMANDS) #if defined(DEBUG_LINKED_COMMANDS)
if (link_statistics && (overlap || !(flushcount % link_statistics))) if (link_statistics && (overlap || !(flushcount % link_statistics)))
for (n = 0; n < n_ready; n++) { for (n = 0; n < n_ready; n++) {
k = il[n]; cpp = &HD(j)->cp[k]; SCpnt = cpp->SCpnt; k = il[n];
printk("%s %d.%d:%d pid %ld mb %d fc %d nr %d sec %ld ns %ld"\ cpp = &HD(j)->cp[k];
SCpnt = cpp->SCpnt;
printk
("%s %d.%d:%d pid %ld mb %d fc %d nr %d sec %ld ns %ld"
" cur %ld s:%c r:%c rev:%c in:%c ov:%c xd %d.\n", " cur %ld s:%c r:%c rev:%c in:%c ov:%c xd %d.\n",
(ihdlr ? "ihdlr" : "qcomm"), SCpnt->device->channel, SCpnt->device->id, (ihdlr ? "ihdlr" : "qcomm"),
SCpnt->device->lun, SCpnt->pid, k, flushcount, n_ready, SCpnt->device->channel, SCpnt->device->id,
SCpnt->request->sector, SCpnt->request->nr_sectors, cursec, SCpnt->device->lun, SCpnt->pid, k, flushcount,
YESNO(s), YESNO(r), YESNO(rev), YESNO(input_only), n_ready, SCpnt->request->sector,
SCpnt->request->nr_sectors, cursec, YESNO(s),
YESNO(r), YESNO(rev), YESNO(input_only),
YESNO(overlap), cpp->din); YESNO(overlap), cpp->din);
} }
#endif #endif
return overlap; return overlap;
} }
static void flush_dev(struct scsi_device *dev, unsigned long cursec, unsigned int j, static void flush_dev(struct scsi_device *dev, unsigned long cursec,
unsigned int ihdlr) { unsigned int j, unsigned int ihdlr)
{
struct scsi_cmnd *SCpnt; struct scsi_cmnd *SCpnt;
struct mscp *cpp; struct mscp *cpp;
unsigned int k, n, n_ready = 0, il[MAX_MAILBOXES]; unsigned int k, n, n_ready = 0, il[MAX_MAILBOXES];
for (k = 0; k < sh[j]->can_queue; k++) { for (k = 0; k < sh[j]->can_queue; k++) {
if (HD(j)->cp_stat[k] != READY && HD(j)->cp_stat[k] != IN_USE) continue; if (HD(j)->cp_stat[k] != READY && HD(j)->cp_stat[k] != IN_USE)
continue;
cpp = &HD(j)->cp[k]; SCpnt = cpp->SCpnt; cpp = &HD(j)->cp[k];
SCpnt = cpp->SCpnt;
if (SCpnt->device != dev) continue; if (SCpnt->device != dev)
continue;
if (HD(j)->cp_stat[k] == IN_USE) return; if (HD(j)->cp_stat[k] == IN_USE)
return;
il[n_ready++] = k; il[n_ready++] = k;
} }
if (reorder(j, cursec, ihdlr, il, n_ready)) n_ready = 1; if (reorder(j, cursec, ihdlr, il, n_ready))
n_ready = 1;
for (n = 0; n < n_ready; n++) { for (n = 0; n < n_ready; n++) {
k = il[n]; cpp = &HD(j)->cp[k]; SCpnt = cpp->SCpnt; k = il[n];
cpp = &HD(j)->cp[k];
SCpnt = cpp->SCpnt;
if (do_dma(sh[j]->io_port, cpp->cp_dma_addr, SEND_CP_DMA)) { if (do_dma(sh[j]->io_port, cpp->cp_dma_addr, SEND_CP_DMA)) {
printk("%s: %s, target %d.%d:%d, pid %ld, mbox %d, adapter"\ printk
" busy, will abort.\n", BN(j), (ihdlr ? "ihdlr" : "qcomm"), ("%s: %s, target %d.%d:%d, pid %ld, mbox %d, adapter"
SCpnt->device->channel, SCpnt->device->id, SCpnt->device->lun, SCpnt->pid, k); " busy, will abort.\n", BN(j),
(ihdlr ? "ihdlr" : "qcomm"),
SCpnt->device->channel, SCpnt->device->id,
SCpnt->device->lun, SCpnt->pid, k);
HD(j)->cp_stat[k] = ABORTING; HD(j)->cp_stat[k] = ABORTING;
continue; continue;
} }
...@@ -2142,27 +2324,32 @@ static void flush_dev(struct scsi_device *dev, unsigned long cursec, unsigned in ...@@ -2142,27 +2324,32 @@ static void flush_dev(struct scsi_device *dev, unsigned long cursec, unsigned in
} }
static irqreturn_t ihdlr(int irq, unsigned int j) { static irqreturn_t ihdlr(int irq, unsigned int j)
{
struct scsi_cmnd *SCpnt; struct scsi_cmnd *SCpnt;
unsigned int i, k, c, status, tstatus, reg; unsigned int i, k, c, status, tstatus, reg;
struct mssp *spp; struct mssp *spp;
struct mscp *cpp; struct mscp *cpp;
if (sh[j]->irq != irq) if (sh[j]->irq != irq)
panic("%s: ihdlr, irq %d, sh[j]->irq %d.\n", BN(j), irq, sh[j]->irq); panic("%s: ihdlr, irq %d, sh[j]->irq %d.\n", BN(j), irq,
sh[j]->irq);
/* Check if this board need to be serviced */ /* Check if this board need to be serviced */
if (!(inb(sh[j]->io_port + REG_AUX_STATUS) & IRQ_ASSERTED)) goto none; if (!(inb(sh[j]->io_port + REG_AUX_STATUS) & IRQ_ASSERTED))
goto none;
HD(j)->iocount++; HD(j)->iocount++;
if (do_trace) printk("%s: ihdlr, enter, irq %d, count %d.\n", BN(j), irq, if (do_trace)
printk("%s: ihdlr, enter, irq %d, count %d.\n", BN(j), irq,
HD(j)->iocount); HD(j)->iocount);
/* Check if this board is still busy */ /* Check if this board is still busy */
if (wait_on_busy(sh[j]->io_port, 20 * MAXLOOP)) { if (wait_on_busy(sh[j]->io_port, 20 * MAXLOOP)) {
reg = inb(sh[j]->io_port + REG_STATUS); reg = inb(sh[j]->io_port + REG_STATUS);
printk("%s: ihdlr, busy timeout error, irq %d, reg 0x%x, count %d.\n", printk
("%s: ihdlr, busy timeout error, irq %d, reg 0x%x, count %d.\n",
BN(j), irq, reg, HD(j)->iocount); BN(j), irq, reg, HD(j)->iocount);
goto none; goto none;
} }
...@@ -2182,10 +2369,11 @@ static irqreturn_t ihdlr(int irq, unsigned int j) { ...@@ -2182,10 +2369,11 @@ static irqreturn_t ihdlr(int irq, unsigned int j) {
{ {
unsigned char *bytesp; unsigned char *bytesp;
int cnt; int cnt;
bytesp= (unsigned char *) spp; bytesp = (unsigned char *)spp;
if (HD(j)->iocount < 200) { if (HD(j)->iocount < 200) {
printk("sp[] ="); printk("sp[] =");
for (cnt=0; cnt < 15; cnt++) printk(" 0x%x", bytesp[cnt]); for (cnt = 0; cnt < 15; cnt++)
printk(" 0x%x", bytesp[cnt]);
printk("\n"); printk("\n");
} }
} }
...@@ -2193,13 +2381,16 @@ static irqreturn_t ihdlr(int irq, unsigned int j) { ...@@ -2193,13 +2381,16 @@ static irqreturn_t ihdlr(int irq, unsigned int j) {
/* Reject any sp with supspect data */ /* Reject any sp with supspect data */
if (spp->eoc == 0 && HD(j)->iocount > 1) if (spp->eoc == 0 && HD(j)->iocount > 1)
printk("%s: ihdlr, spp->eoc == 0, irq %d, reg 0x%x, count %d.\n", printk
("%s: ihdlr, spp->eoc == 0, irq %d, reg 0x%x, count %d.\n",
BN(j), irq, reg, HD(j)->iocount); BN(j), irq, reg, HD(j)->iocount);
if (spp->cpp_index < 0 || spp->cpp_index >= sh[j]->can_queue) if (spp->cpp_index < 0 || spp->cpp_index >= sh[j]->can_queue)
printk("%s: ihdlr, bad spp->cpp_index %d, irq %d, reg 0x%x, count %d.\n", printk
("%s: ihdlr, bad spp->cpp_index %d, irq %d, reg 0x%x, count %d.\n",
BN(j), spp->cpp_index, irq, reg, HD(j)->iocount); BN(j), spp->cpp_index, irq, reg, HD(j)->iocount);
if (spp->eoc == 0 || spp->cpp_index < 0 if (spp->eoc == 0 || spp->cpp_index < 0
|| spp->cpp_index >= sh[j]->can_queue) goto handled; || spp->cpp_index >= sh[j]->can_queue)
goto handled;
/* Find the mailbox to be serviced on this board */ /* Find the mailbox to be serviced on this board */
i = spp->cpp_index; i = spp->cpp_index;
...@@ -2207,25 +2398,23 @@ static irqreturn_t ihdlr(int irq, unsigned int j) { ...@@ -2207,25 +2398,23 @@ static irqreturn_t ihdlr(int irq, unsigned int j) {
cpp = &(HD(j)->cp[i]); cpp = &(HD(j)->cp[i]);
#if defined(DEBUG_GENERATE_ABORTS) #if defined(DEBUG_GENERATE_ABORTS)
if ((HD(j)->iocount > 500) && ((HD(j)->iocount % 500) < 3)) goto handled; if ((HD(j)->iocount > 500) && ((HD(j)->iocount % 500) < 3))
goto handled;
#endif #endif
if (HD(j)->cp_stat[i] == IGNORE) { if (HD(j)->cp_stat[i] == IGNORE) {
HD(j)->cp_stat[i] = FREE; HD(j)->cp_stat[i] = FREE;
goto handled; goto handled;
} } else if (HD(j)->cp_stat[i] == LOCKED) {
else if (HD(j)->cp_stat[i] == LOCKED) {
HD(j)->cp_stat[i] = FREE; HD(j)->cp_stat[i] = FREE;
printk("%s: ihdlr, mbox %d unlocked, count %d.\n", BN(j), i, printk("%s: ihdlr, mbox %d unlocked, count %d.\n", BN(j), i,
HD(j)->iocount); HD(j)->iocount);
goto handled; goto handled;
} } else if (HD(j)->cp_stat[i] == FREE) {
else if (HD(j)->cp_stat[i] == FREE) {
printk("%s: ihdlr, mbox %d is free, count %d.\n", BN(j), i, printk("%s: ihdlr, mbox %d is free, count %d.\n", BN(j), i,
HD(j)->iocount); HD(j)->iocount);
goto handled; goto handled;
} } else if (HD(j)->cp_stat[i] == IN_RESET)
else if (HD(j)->cp_stat[i] == IN_RESET)
printk("%s: ihdlr, mbox %d is in reset.\n", BN(j), i); printk("%s: ihdlr, mbox %d is in reset.\n", BN(j), i);
else if (HD(j)->cp_stat[i] != IN_USE) else if (HD(j)->cp_stat[i] != IN_USE)
panic("%s: ihdlr, mbox %d, invalid cp_stat: %d.\n", panic("%s: ihdlr, mbox %d, invalid cp_stat: %d.\n",
...@@ -2234,15 +2423,17 @@ static irqreturn_t ihdlr(int irq, unsigned int j) { ...@@ -2234,15 +2423,17 @@ static irqreturn_t ihdlr(int irq, unsigned int j) {
HD(j)->cp_stat[i] = FREE; HD(j)->cp_stat[i] = FREE;
SCpnt = cpp->SCpnt; SCpnt = cpp->SCpnt;
if (SCpnt == NULL) panic("%s: ihdlr, mbox %d, SCpnt == NULL.\n", BN(j), i); if (SCpnt == NULL)
panic("%s: ihdlr, mbox %d, SCpnt == NULL.\n", BN(j), i);
if (SCpnt->host_scribble == NULL) if (SCpnt->host_scribble == NULL)
panic("%s: ihdlr, mbox %d, pid %ld, SCpnt %p garbled.\n", BN(j), i, panic("%s: ihdlr, mbox %d, pid %ld, SCpnt %p garbled.\n", BN(j),
SCpnt->pid, SCpnt); i, SCpnt->pid, SCpnt);
if (*(unsigned int *)SCpnt->host_scribble != i) if (*(unsigned int *)SCpnt->host_scribble != i)
panic("%s: ihdlr, mbox %d, pid %ld, index mismatch %d.\n", panic("%s: ihdlr, mbox %d, pid %ld, index mismatch %d.\n",
BN(j), i, SCpnt->pid, *(unsigned int *)SCpnt->host_scribble); BN(j), i, SCpnt->pid,
*(unsigned int *)SCpnt->host_scribble);
sync_dma(i, j); sync_dma(i, j);
...@@ -2266,7 +2457,9 @@ static irqreturn_t ihdlr(int irq, unsigned int j) { ...@@ -2266,7 +2457,9 @@ static irqreturn_t ihdlr(int irq, unsigned int j) {
/* If there was a bus reset, redo operation on each target */ /* If there was a bus reset, redo operation on each target */
else if (tstatus != GOOD && SCpnt->device->type == TYPE_DISK else if (tstatus != GOOD && SCpnt->device->type == TYPE_DISK
&& HD(j)->target_redo[SCpnt->device->id][SCpnt->device->channel]) && HD(j)->target_redo[SCpnt->device->id][SCpnt->
device->
channel])
status = DID_BUS_BUSY << 16; status = DID_BUS_BUSY << 16;
/* Works around a flaw in scsi.c */ /* Works around a flaw in scsi.c */
...@@ -2279,30 +2472,34 @@ static irqreturn_t ihdlr(int irq, unsigned int j) { ...@@ -2279,30 +2472,34 @@ static irqreturn_t ihdlr(int irq, unsigned int j) {
status = DID_OK << 16; status = DID_OK << 16;
if (tstatus == GOOD) if (tstatus == GOOD)
HD(j)->target_redo[SCpnt->device->id][SCpnt->device->channel] = 0; HD(j)->target_redo[SCpnt->device->id][SCpnt->device->
channel] = 0;
if (spp->target_status && SCpnt->device->type == TYPE_DISK && if (spp->target_status && SCpnt->device->type == TYPE_DISK &&
(!(tstatus == CHECK_CONDITION && HD(j)->iocount <= 1000 && (!(tstatus == CHECK_CONDITION && HD(j)->iocount <= 1000 &&
(SCpnt->sense_buffer[2] & 0xf) == NOT_READY))) (SCpnt->sense_buffer[2] & 0xf) == NOT_READY)))
printk("%s: ihdlr, target %d.%d:%d, pid %ld, "\ printk("%s: ihdlr, target %d.%d:%d, pid %ld, "
"target_status 0x%x, sense key 0x%x.\n", BN(j), "target_status 0x%x, sense key 0x%x.\n", BN(j),
SCpnt->device->channel, SCpnt->device->id, SCpnt->device->lun, SCpnt->device->channel, SCpnt->device->id,
SCpnt->pid, spp->target_status, SCpnt->device->lun, SCpnt->pid,
SCpnt->sense_buffer[2]); spp->target_status, SCpnt->sense_buffer[2]);
HD(j)->target_to[SCpnt->device->id][SCpnt->device->channel] = 0; HD(j)->target_to[SCpnt->device->id][SCpnt->device->channel] = 0;
if (HD(j)->last_retried_pid == SCpnt->pid) HD(j)->retries = 0; if (HD(j)->last_retried_pid == SCpnt->pid)
HD(j)->retries = 0;
break; break;
case ASST: /* Selection Time Out */ case ASST: /* Selection Time Out */
case 0x02: /* Command Time Out */ case 0x02: /* Command Time Out */
if (HD(j)->target_to[SCpnt->device->id][SCpnt->device->channel] > 1) if (HD(j)->
target_to[SCpnt->device->id][SCpnt->device->channel] > 1)
status = DID_ERROR << 16; status = DID_ERROR << 16;
else { else {
status = DID_TIME_OUT << 16; status = DID_TIME_OUT << 16;
HD(j)->target_to[SCpnt->device->id][SCpnt->device->channel]++; HD(j)->target_to[SCpnt->device->id][SCpnt->device->
channel]++;
} }
break; break;
...@@ -2326,8 +2523,7 @@ static irqreturn_t ihdlr(int irq, unsigned int j) { ...@@ -2326,8 +2523,7 @@ static irqreturn_t ihdlr(int irq, unsigned int j) {
HD(j)->retries++; HD(j)->retries++;
HD(j)->last_retried_pid = SCpnt->pid; HD(j)->last_retried_pid = SCpnt->pid;
} } else
else
status = DID_ERROR << 16; status = DID_ERROR << 16;
break; break;
...@@ -2354,11 +2550,11 @@ static irqreturn_t ihdlr(int irq, unsigned int j) { ...@@ -2354,11 +2550,11 @@ static irqreturn_t ihdlr(int irq, unsigned int j) {
spp->adapter_status != ASST && HD(j)->iocount <= 1000) || spp->adapter_status != ASST && HD(j)->iocount <= 1000) ||
do_trace || msg_byte(spp->target_status)) do_trace || msg_byte(spp->target_status))
#endif #endif
printk("%s: ihdlr, mbox %2d, err 0x%x:%x,"\ printk("%s: ihdlr, mbox %2d, err 0x%x:%x,"
" target %d.%d:%d, pid %ld, reg 0x%x, count %d.\n", " target %d.%d:%d, pid %ld, reg 0x%x, count %d.\n",
BN(j), i, spp->adapter_status, spp->target_status, BN(j), i, spp->adapter_status, spp->target_status,
SCpnt->device->channel, SCpnt->device->id, SCpnt->device->lun, SCpnt->pid, SCpnt->device->channel, SCpnt->device->id,
reg, HD(j)->iocount); SCpnt->device->lun, SCpnt->pid, reg, HD(j)->iocount);
unmap_dma(i, j); unmap_dma(i, j);
...@@ -2367,23 +2563,26 @@ static irqreturn_t ihdlr(int irq, unsigned int j) { ...@@ -2367,23 +2563,26 @@ static irqreturn_t ihdlr(int irq, unsigned int j) {
SCpnt->scsi_done(SCpnt); SCpnt->scsi_done(SCpnt);
if (do_trace) printk("%s: ihdlr, exit, irq %d, count %d.\n", BN(j), irq, if (do_trace)
printk("%s: ihdlr, exit, irq %d, count %d.\n", BN(j), irq,
HD(j)->iocount); HD(j)->iocount);
handled: handled:
return IRQ_HANDLED; return IRQ_HANDLED;
none: none:
return IRQ_NONE; return IRQ_NONE;
} }
static irqreturn_t do_interrupt_handler(int irq, void *shap, static irqreturn_t do_interrupt_handler(int irq, void *shap,
struct pt_regs *regs) { struct pt_regs *regs)
{
unsigned int j; unsigned int j;
unsigned long spin_flags; unsigned long spin_flags;
irqreturn_t ret; irqreturn_t ret;
/* Check if the interrupt must be processed by this handler */ /* Check if the interrupt must be processed by this handler */
if ((j = (unsigned int)((char *)shap - sha)) >= num_boards) return IRQ_NONE; if ((j = (unsigned int)((char *)shap - sha)) >= num_boards)
return IRQ_NONE;
spin_lock_irqsave(sh[j]->host_lock, spin_flags); spin_lock_irqsave(sh[j]->host_lock, spin_flags);
ret = ihdlr(irq, j); ret = ihdlr(irq, j);
...@@ -2391,16 +2590,18 @@ static irqreturn_t do_interrupt_handler(int irq, void *shap, ...@@ -2391,16 +2590,18 @@ static irqreturn_t do_interrupt_handler(int irq, void *shap,
return ret; return ret;
} }
static int eata2x_release(struct Scsi_Host *shpnt) { static int eata2x_release(struct Scsi_Host *shpnt)
{
unsigned int i, j; unsigned int i, j;
for (j = 0; sh[j] != NULL && sh[j] != shpnt; j++); for (j = 0; sh[j] != NULL && sh[j] != shpnt; j++) ;
if (sh[j] == NULL) panic("%s: release, invalid Scsi_Host pointer.\n", if (sh[j] == NULL)
driver_name); panic("%s: release, invalid Scsi_Host pointer.\n", driver_name);
for (i = 0; i < sh[j]->can_queue; i++) for (i = 0; i < sh[j]->can_queue; i++)
if ((&HD(j)->cp[i])->sglist) kfree((&HD(j)->cp[i])->sglist); if ((&HD(j)->cp[i])->sglist)
kfree((&HD(j)->cp[i])->sglist);
for (i = 0; i < sh[j]->can_queue; i++) for (i = 0; i < sh[j]->can_queue; i++)
pci_unmap_single(HD(j)->pdev, HD(j)->cp[i].cp_dma_addr, pci_unmap_single(HD(j)->pdev, HD(j)->cp[i].cp_dma_addr,
...@@ -2412,7 +2613,8 @@ static int eata2x_release(struct Scsi_Host *shpnt) { ...@@ -2412,7 +2613,8 @@ static int eata2x_release(struct Scsi_Host *shpnt) {
free_irq(sh[j]->irq, &sha[j]); free_irq(sh[j]->irq, &sha[j]);
if (sh[j]->dma_channel != NO_DMA) free_dma(sh[j]->dma_channel); if (sh[j]->dma_channel != NO_DMA)
free_dma(sh[j]->dma_channel);
release_region(sh[j]->io_port, sh[j]->n_io_port); release_region(sh[j]->io_port, sh[j]->n_io_port);
scsi_unregister(sh[j]); scsi_unregister(sh[j]);
......
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