Commit d0cac32f authored by Linus Torvalds's avatar Linus Torvalds

Merge master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-rc-fixes-2.6

* master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-rc-fixes-2.6:
  [SCSI] psi240i.c: fix an array overrun
  [SCSI] gdth: Fix && typos
  [SCSI] iscsi class: update version
  [SCSI] iscsi_tcp: fix xmittask oops
  [SCSI] iscsi: add newlines to debug messages
  [SCSI] iscsi: always release crypto
  [SCSI] sg: fix incorrect last scatg length
  [SCSI] 3ware 9000 add support for 9650SE
  [SCSI] aic94xx SCSI timeout fix: SMP retry fix.
  [SCSI] aic94xx SCSI timeout fix
parents 626db29f 05052f7f
This diff is collapsed.
...@@ -289,7 +289,6 @@ static twa_message_type twa_error_table[] = { ...@@ -289,7 +289,6 @@ static twa_message_type twa_error_table[] = {
#define TW_STATUS_VALID_INTERRUPT 0x00DF0000 #define TW_STATUS_VALID_INTERRUPT 0x00DF0000
/* PCI related defines */ /* PCI related defines */
#define TW_NUMDEVICES 1
#define TW_PCI_CLEAR_PARITY_ERRORS 0xc100 #define TW_PCI_CLEAR_PARITY_ERRORS 0xc100
#define TW_PCI_CLEAR_PCI_ABORT 0x2000 #define TW_PCI_CLEAR_PCI_ABORT 0x2000
...@@ -335,6 +334,7 @@ static twa_message_type twa_error_table[] = { ...@@ -335,6 +334,7 @@ static twa_message_type twa_error_table[] = {
#define TW_ALIGNMENT_9000 4 /* 4 bytes */ #define TW_ALIGNMENT_9000 4 /* 4 bytes */
#define TW_ALIGNMENT_9000_SGL 0x3 #define TW_ALIGNMENT_9000_SGL 0x3
#define TW_MAX_UNITS 16 #define TW_MAX_UNITS 16
#define TW_MAX_UNITS_9650SE 32
#define TW_INIT_MESSAGE_CREDITS 0x100 #define TW_INIT_MESSAGE_CREDITS 0x100
#define TW_INIT_COMMAND_PACKET_SIZE 0x3 #define TW_INIT_COMMAND_PACKET_SIZE 0x3
#define TW_INIT_COMMAND_PACKET_SIZE_EXTENDED 0x6 #define TW_INIT_COMMAND_PACKET_SIZE_EXTENDED 0x6
...@@ -354,7 +354,6 @@ static twa_message_type twa_error_table[] = { ...@@ -354,7 +354,6 @@ static twa_message_type twa_error_table[] = {
#define TW_MAX_RESPONSE_DRAIN 256 #define TW_MAX_RESPONSE_DRAIN 256
#define TW_MAX_AEN_DRAIN 40 #define TW_MAX_AEN_DRAIN 40
#define TW_IN_RESET 2 #define TW_IN_RESET 2
#define TW_IN_CHRDEV_IOCTL 3
#define TW_IN_ATTENTION_LOOP 4 #define TW_IN_ATTENTION_LOOP 4
#define TW_MAX_SECTORS 256 #define TW_MAX_SECTORS 256
#define TW_AEN_WAIT_TIME 1000 #define TW_AEN_WAIT_TIME 1000
...@@ -417,6 +416,9 @@ static twa_message_type twa_error_table[] = { ...@@ -417,6 +416,9 @@ static twa_message_type twa_error_table[] = {
#ifndef PCI_DEVICE_ID_3WARE_9550SX #ifndef PCI_DEVICE_ID_3WARE_9550SX
#define PCI_DEVICE_ID_3WARE_9550SX 0x1003 #define PCI_DEVICE_ID_3WARE_9550SX 0x1003
#endif #endif
#ifndef PCI_DEVICE_ID_3WARE_9650SE
#define PCI_DEVICE_ID_3WARE_9650SE 0x1004
#endif
/* Bitmask macros to eliminate bitfields */ /* Bitmask macros to eliminate bitfields */
...@@ -442,6 +444,7 @@ static twa_message_type twa_error_table[] = { ...@@ -442,6 +444,7 @@ static twa_message_type twa_error_table[] = {
#define TW_CONTROL_REG_ADDR(x) (x->base_addr) #define TW_CONTROL_REG_ADDR(x) (x->base_addr)
#define TW_STATUS_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + 0x4) #define TW_STATUS_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + 0x4)
#define TW_COMMAND_QUEUE_REG_ADDR(x) (sizeof(dma_addr_t) > 4 ? ((unsigned char __iomem *)x->base_addr + 0x20) : ((unsigned char __iomem *)x->base_addr + 0x8)) #define TW_COMMAND_QUEUE_REG_ADDR(x) (sizeof(dma_addr_t) > 4 ? ((unsigned char __iomem *)x->base_addr + 0x20) : ((unsigned char __iomem *)x->base_addr + 0x8))
#define TW_COMMAND_QUEUE_REG_ADDR_LARGE(x) ((unsigned char __iomem *)x->base_addr + 0x20)
#define TW_RESPONSE_QUEUE_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + 0xC) #define TW_RESPONSE_QUEUE_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + 0xC)
#define TW_RESPONSE_QUEUE_REG_ADDR_LARGE(x) ((unsigned char __iomem *)x->base_addr + 0x30) #define TW_RESPONSE_QUEUE_REG_ADDR_LARGE(x) ((unsigned char __iomem *)x->base_addr + 0x30)
#define TW_CLEAR_ALL_INTERRUPTS(x) (writel(TW_STATUS_VALID_INTERRUPT, TW_CONTROL_REG_ADDR(x))) #define TW_CLEAR_ALL_INTERRUPTS(x) (writel(TW_STATUS_VALID_INTERRUPT, TW_CONTROL_REG_ADDR(x)))
...@@ -626,6 +629,9 @@ typedef struct TAG_TW_Compatibility_Info ...@@ -626,6 +629,9 @@ typedef struct TAG_TW_Compatibility_Info
unsigned short driver_srl_low; unsigned short driver_srl_low;
unsigned short driver_branch_low; unsigned short driver_branch_low;
unsigned short driver_build_low; unsigned short driver_build_low;
unsigned short fw_on_ctlr_srl;
unsigned short fw_on_ctlr_branch;
unsigned short fw_on_ctlr_build;
} TW_Compatibility_Info; } TW_Compatibility_Info;
#pragma pack() #pragma pack()
...@@ -668,9 +674,7 @@ typedef struct TAG_TW_Device_Extension { ...@@ -668,9 +674,7 @@ typedef struct TAG_TW_Device_Extension {
wait_queue_head_t ioctl_wqueue; wait_queue_head_t ioctl_wqueue;
struct mutex ioctl_lock; struct mutex ioctl_lock;
char aen_clobber; char aen_clobber;
unsigned short working_srl; TW_Compatibility_Info tw_compat_info;
unsigned short working_branch;
unsigned short working_build;
} TW_Device_Extension; } TW_Device_Extension;
#endif /* _3W_9XXX_H */ #endif /* _3W_9XXX_H */
......
...@@ -112,6 +112,21 @@ static int asd_init_phy(struct asd_phy *phy) ...@@ -112,6 +112,21 @@ static int asd_init_phy(struct asd_phy *phy)
return 0; return 0;
} }
static void asd_init_ports(struct asd_ha_struct *asd_ha)
{
int i;
spin_lock_init(&asd_ha->asd_ports_lock);
for (i = 0; i < ASD_MAX_PHYS; i++) {
struct asd_port *asd_port = &asd_ha->asd_ports[i];
memset(asd_port->sas_addr, 0, SAS_ADDR_SIZE);
memset(asd_port->attached_sas_addr, 0, SAS_ADDR_SIZE);
asd_port->phy_mask = 0;
asd_port->num_phys = 0;
}
}
static int asd_init_phys(struct asd_ha_struct *asd_ha) static int asd_init_phys(struct asd_ha_struct *asd_ha)
{ {
u8 i; u8 i;
...@@ -121,6 +136,7 @@ static int asd_init_phys(struct asd_ha_struct *asd_ha) ...@@ -121,6 +136,7 @@ static int asd_init_phys(struct asd_ha_struct *asd_ha)
struct asd_phy *phy = &asd_ha->phys[i]; struct asd_phy *phy = &asd_ha->phys[i];
phy->phy_desc = &asd_ha->hw_prof.phy_desc[i]; phy->phy_desc = &asd_ha->hw_prof.phy_desc[i];
phy->asd_port = NULL;
phy->sas_phy.enabled = 0; phy->sas_phy.enabled = 0;
phy->sas_phy.id = i; phy->sas_phy.id = i;
...@@ -658,6 +674,8 @@ int asd_init_hw(struct asd_ha_struct *asd_ha) ...@@ -658,6 +674,8 @@ int asd_init_hw(struct asd_ha_struct *asd_ha)
goto Out; goto Out;
} }
asd_init_ports(asd_ha);
err = asd_init_scbs(asd_ha); err = asd_init_scbs(asd_ha);
if (err) { if (err) {
asd_printk("couldn't initialize scbs for %s\n", asd_printk("couldn't initialize scbs for %s\n",
......
...@@ -193,6 +193,16 @@ struct asd_seq_data { ...@@ -193,6 +193,16 @@ struct asd_seq_data {
struct asd_ascb **escb_arr; /* array of pointers to escbs */ struct asd_ascb **escb_arr; /* array of pointers to escbs */
}; };
/* This is an internal port structure. These are used to get accurate
* phy_mask for updating DDB 0.
*/
struct asd_port {
u8 sas_addr[SAS_ADDR_SIZE];
u8 attached_sas_addr[SAS_ADDR_SIZE];
u32 phy_mask;
int num_phys;
};
/* This is the Host Adapter structure. It describes the hardware /* This is the Host Adapter structure. It describes the hardware
* SAS adapter. * SAS adapter.
*/ */
...@@ -211,6 +221,8 @@ struct asd_ha_struct { ...@@ -211,6 +221,8 @@ struct asd_ha_struct {
struct hw_profile hw_prof; struct hw_profile hw_prof;
struct asd_phy phys[ASD_MAX_PHYS]; struct asd_phy phys[ASD_MAX_PHYS];
spinlock_t asd_ports_lock;
struct asd_port asd_ports[ASD_MAX_PHYS];
struct asd_sas_port ports[ASD_MAX_PHYS]; struct asd_sas_port ports[ASD_MAX_PHYS];
struct dma_pool *scb_pool; struct dma_pool *scb_pool;
......
...@@ -786,8 +786,6 @@ static void asd_remove_driver_attrs(struct device_driver *driver) ...@@ -786,8 +786,6 @@ static void asd_remove_driver_attrs(struct device_driver *driver)
} }
static struct sas_domain_function_template aic94xx_transport_functions = { static struct sas_domain_function_template aic94xx_transport_functions = {
.lldd_port_formed = asd_update_port_links,
.lldd_dev_found = asd_dev_found, .lldd_dev_found = asd_dev_found,
.lldd_dev_gone = asd_dev_gone, .lldd_dev_gone = asd_dev_gone,
......
...@@ -733,6 +733,7 @@ struct asd_phy { ...@@ -733,6 +733,7 @@ struct asd_phy {
struct sas_identify_frame *identify_frame; struct sas_identify_frame *identify_frame;
struct asd_dma_tok *id_frm_tok; struct asd_dma_tok *id_frm_tok;
struct asd_port *asd_port;
u8 frame_rcvd[ASD_EDB_SIZE]; u8 frame_rcvd[ASD_EDB_SIZE];
}; };
......
...@@ -168,6 +168,70 @@ static inline void asd_get_attached_sas_addr(struct asd_phy *phy, u8 *sas_addr) ...@@ -168,6 +168,70 @@ static inline void asd_get_attached_sas_addr(struct asd_phy *phy, u8 *sas_addr)
} }
} }
static void asd_form_port(struct asd_ha_struct *asd_ha, struct asd_phy *phy)
{
int i;
struct asd_port *free_port = NULL;
struct asd_port *port;
struct asd_sas_phy *sas_phy = &phy->sas_phy;
unsigned long flags;
spin_lock_irqsave(&asd_ha->asd_ports_lock, flags);
if (!phy->asd_port) {
for (i = 0; i < ASD_MAX_PHYS; i++) {
port = &asd_ha->asd_ports[i];
/* Check for wide port */
if (port->num_phys > 0 &&
memcmp(port->sas_addr, sas_phy->sas_addr,
SAS_ADDR_SIZE) == 0 &&
memcmp(port->attached_sas_addr,
sas_phy->attached_sas_addr,
SAS_ADDR_SIZE) == 0) {
break;
}
/* Find a free port */
if (port->num_phys == 0 && free_port == NULL) {
free_port = port;
}
}
/* Use a free port if this doesn't form a wide port */
if (i >= ASD_MAX_PHYS) {
port = free_port;
BUG_ON(!port);
memcpy(port->sas_addr, sas_phy->sas_addr,
SAS_ADDR_SIZE);
memcpy(port->attached_sas_addr,
sas_phy->attached_sas_addr,
SAS_ADDR_SIZE);
}
port->num_phys++;
port->phy_mask |= (1U << sas_phy->id);
phy->asd_port = port;
}
ASD_DPRINTK("%s: updating phy_mask 0x%x for phy%d\n",
__FUNCTION__, phy->asd_port->phy_mask, sas_phy->id);
asd_update_port_links(asd_ha, phy);
spin_unlock_irqrestore(&asd_ha->asd_ports_lock, flags);
}
static void asd_deform_port(struct asd_ha_struct *asd_ha, struct asd_phy *phy)
{
struct asd_port *port = phy->asd_port;
struct asd_sas_phy *sas_phy = &phy->sas_phy;
unsigned long flags;
spin_lock_irqsave(&asd_ha->asd_ports_lock, flags);
if (port) {
port->num_phys--;
port->phy_mask &= ~(1U << sas_phy->id);
phy->asd_port = NULL;
}
spin_unlock_irqrestore(&asd_ha->asd_ports_lock, flags);
}
static inline void asd_bytes_dmaed_tasklet(struct asd_ascb *ascb, static inline void asd_bytes_dmaed_tasklet(struct asd_ascb *ascb,
struct done_list_struct *dl, struct done_list_struct *dl,
int edb_id, int phy_id) int edb_id, int phy_id)
...@@ -187,6 +251,7 @@ static inline void asd_bytes_dmaed_tasklet(struct asd_ascb *ascb, ...@@ -187,6 +251,7 @@ static inline void asd_bytes_dmaed_tasklet(struct asd_ascb *ascb,
asd_get_attached_sas_addr(phy, phy->sas_phy.attached_sas_addr); asd_get_attached_sas_addr(phy, phy->sas_phy.attached_sas_addr);
spin_unlock_irqrestore(&phy->sas_phy.frame_rcvd_lock, flags); spin_unlock_irqrestore(&phy->sas_phy.frame_rcvd_lock, flags);
asd_dump_frame_rcvd(phy, dl); asd_dump_frame_rcvd(phy, dl);
asd_form_port(ascb->ha, phy);
sas_ha->notify_port_event(&phy->sas_phy, PORTE_BYTES_DMAED); sas_ha->notify_port_event(&phy->sas_phy, PORTE_BYTES_DMAED);
} }
...@@ -197,6 +262,7 @@ static inline void asd_link_reset_err_tasklet(struct asd_ascb *ascb, ...@@ -197,6 +262,7 @@ static inline void asd_link_reset_err_tasklet(struct asd_ascb *ascb,
struct asd_ha_struct *asd_ha = ascb->ha; struct asd_ha_struct *asd_ha = ascb->ha;
struct sas_ha_struct *sas_ha = &asd_ha->sas_ha; struct sas_ha_struct *sas_ha = &asd_ha->sas_ha;
struct asd_sas_phy *sas_phy = sas_ha->sas_phy[phy_id]; struct asd_sas_phy *sas_phy = sas_ha->sas_phy[phy_id];
struct asd_phy *phy = &asd_ha->phys[phy_id];
u8 lr_error = dl->status_block[1]; u8 lr_error = dl->status_block[1];
u8 retries_left = dl->status_block[2]; u8 retries_left = dl->status_block[2];
...@@ -221,6 +287,7 @@ static inline void asd_link_reset_err_tasklet(struct asd_ascb *ascb, ...@@ -221,6 +287,7 @@ static inline void asd_link_reset_err_tasklet(struct asd_ascb *ascb,
asd_turn_led(asd_ha, phy_id, 0); asd_turn_led(asd_ha, phy_id, 0);
sas_phy_disconnected(sas_phy); sas_phy_disconnected(sas_phy);
asd_deform_port(asd_ha, phy);
sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR); sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR);
if (retries_left == 0) { if (retries_left == 0) {
...@@ -248,6 +315,8 @@ static inline void asd_primitive_rcvd_tasklet(struct asd_ascb *ascb, ...@@ -248,6 +315,8 @@ static inline void asd_primitive_rcvd_tasklet(struct asd_ascb *ascb,
unsigned long flags; unsigned long flags;
struct sas_ha_struct *sas_ha = &ascb->ha->sas_ha; struct sas_ha_struct *sas_ha = &ascb->ha->sas_ha;
struct asd_sas_phy *sas_phy = sas_ha->sas_phy[phy_id]; struct asd_sas_phy *sas_phy = sas_ha->sas_phy[phy_id];
struct asd_ha_struct *asd_ha = ascb->ha;
struct asd_phy *phy = &asd_ha->phys[phy_id];
u8 reg = dl->status_block[1]; u8 reg = dl->status_block[1];
u32 cont = dl->status_block[2] << ((reg & 3)*8); u32 cont = dl->status_block[2] << ((reg & 3)*8);
...@@ -284,6 +353,7 @@ static inline void asd_primitive_rcvd_tasklet(struct asd_ascb *ascb, ...@@ -284,6 +353,7 @@ static inline void asd_primitive_rcvd_tasklet(struct asd_ascb *ascb,
phy_id); phy_id);
/* The sequencer disables all phys on that port. /* The sequencer disables all phys on that port.
* We have to re-enable the phys ourselves. */ * We have to re-enable the phys ourselves. */
asd_deform_port(asd_ha, phy);
sas_ha->notify_port_event(sas_phy, PORTE_HARD_RESET); sas_ha->notify_port_event(sas_phy, PORTE_HARD_RESET);
break; break;
...@@ -351,6 +421,7 @@ static void escb_tasklet_complete(struct asd_ascb *ascb, ...@@ -351,6 +421,7 @@ static void escb_tasklet_complete(struct asd_ascb *ascb,
u8 sb_opcode = dl->status_block[0]; u8 sb_opcode = dl->status_block[0];
int phy_id = sb_opcode & DL_PHY_MASK; int phy_id = sb_opcode & DL_PHY_MASK;
struct asd_sas_phy *sas_phy = sas_ha->sas_phy[phy_id]; struct asd_sas_phy *sas_phy = sas_ha->sas_phy[phy_id];
struct asd_phy *phy = &asd_ha->phys[phy_id];
if (edb > 6 || edb < 0) { if (edb > 6 || edb < 0) {
ASD_DPRINTK("edb is 0x%x! dl->opcode is 0x%x\n", ASD_DPRINTK("edb is 0x%x! dl->opcode is 0x%x\n",
...@@ -395,6 +466,7 @@ static void escb_tasklet_complete(struct asd_ascb *ascb, ...@@ -395,6 +466,7 @@ static void escb_tasklet_complete(struct asd_ascb *ascb,
asd_turn_led(asd_ha, phy_id, 0); asd_turn_led(asd_ha, phy_id, 0);
/* the device is gone */ /* the device is gone */
sas_phy_disconnected(sas_phy); sas_phy_disconnected(sas_phy);
asd_deform_port(asd_ha, phy);
sas_ha->notify_port_event(sas_phy, PORTE_TIMER_EVENT); sas_ha->notify_port_event(sas_phy, PORTE_TIMER_EVENT);
break; break;
case REQ_TASK_ABORT: case REQ_TASK_ABORT:
......
...@@ -1369,10 +1369,9 @@ int asd_start_seqs(struct asd_ha_struct *asd_ha) ...@@ -1369,10 +1369,9 @@ int asd_start_seqs(struct asd_ha_struct *asd_ha)
* port_map_by_links is also used as the conn_mask byte in the * port_map_by_links is also used as the conn_mask byte in the
* initiator/target port DDB. * initiator/target port DDB.
*/ */
void asd_update_port_links(struct asd_sas_phy *sas_phy) void asd_update_port_links(struct asd_ha_struct *asd_ha, struct asd_phy *phy)
{ {
struct asd_ha_struct *asd_ha = sas_phy->ha->lldd_ha; const u8 phy_mask = (u8) phy->asd_port->phy_mask;
const u8 phy_mask = (u8) sas_phy->port->phy_mask;
u8 phy_is_up; u8 phy_is_up;
u8 mask; u8 mask;
int i, err; int i, err;
......
...@@ -64,7 +64,7 @@ int asd_unpause_lseq(struct asd_ha_struct *asd_ha, u8 lseq_mask); ...@@ -64,7 +64,7 @@ int asd_unpause_lseq(struct asd_ha_struct *asd_ha, u8 lseq_mask);
int asd_init_seqs(struct asd_ha_struct *asd_ha); int asd_init_seqs(struct asd_ha_struct *asd_ha);
int asd_start_seqs(struct asd_ha_struct *asd_ha); int asd_start_seqs(struct asd_ha_struct *asd_ha);
void asd_update_port_links(struct asd_sas_phy *phy); void asd_update_port_links(struct asd_ha_struct *asd_ha, struct asd_phy *phy);
#endif #endif
#endif #endif
...@@ -3531,7 +3531,7 @@ static irqreturn_t gdth_interrupt(int irq,void *dev_id) ...@@ -3531,7 +3531,7 @@ static irqreturn_t gdth_interrupt(int irq,void *dev_id)
IStatus &= ~0x80; IStatus &= ~0x80;
#ifdef INT_COAL #ifdef INT_COAL
if (coalesced) if (coalesced)
ha->status = pcs->ext_status && 0xffff; ha->status = pcs->ext_status & 0xffff;
else else
#endif #endif
ha->status = gdth_readw(&dp6m_ptr->i960r.status); ha->status = gdth_readw(&dp6m_ptr->i960r.status);
...@@ -3543,7 +3543,7 @@ static irqreturn_t gdth_interrupt(int irq,void *dev_id) ...@@ -3543,7 +3543,7 @@ static irqreturn_t gdth_interrupt(int irq,void *dev_id)
if (coalesced) { if (coalesced) {
ha->info = pcs->info0; ha->info = pcs->info0;
ha->info2 = pcs->info1; ha->info2 = pcs->info1;
ha->service = (pcs->ext_status >> 16) && 0xffff; ha->service = (pcs->ext_status >> 16) & 0xffff;
} else } else
#endif #endif
{ {
......
...@@ -415,8 +415,8 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) ...@@ -415,8 +415,8 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
iscsi_solicit_data_init(conn, ctask, r2t); iscsi_solicit_data_init(conn, ctask, r2t);
tcp_ctask->exp_r2tsn = r2tsn + 1; tcp_ctask->exp_r2tsn = r2tsn + 1;
tcp_ctask->xmstate |= XMSTATE_SOL_HDR;
__kfifo_put(tcp_ctask->r2tqueue, (void*)&r2t, sizeof(void*)); __kfifo_put(tcp_ctask->r2tqueue, (void*)&r2t, sizeof(void*));
tcp_ctask->xmstate |= XMSTATE_SOL_HDR;
list_move_tail(&ctask->running, &conn->xmitqueue); list_move_tail(&ctask->running, &conn->xmitqueue);
scsi_queue_work(session->host, &conn->xmitwork); scsi_queue_work(session->host, &conn->xmitwork);
...@@ -1627,9 +1627,12 @@ static int iscsi_send_sol_pdu(struct iscsi_conn *conn, ...@@ -1627,9 +1627,12 @@ static int iscsi_send_sol_pdu(struct iscsi_conn *conn,
if (tcp_ctask->xmstate & XMSTATE_SOL_HDR) { if (tcp_ctask->xmstate & XMSTATE_SOL_HDR) {
tcp_ctask->xmstate &= ~XMSTATE_SOL_HDR; tcp_ctask->xmstate &= ~XMSTATE_SOL_HDR;
tcp_ctask->xmstate |= XMSTATE_SOL_DATA; tcp_ctask->xmstate |= XMSTATE_SOL_DATA;
if (!tcp_ctask->r2t) if (!tcp_ctask->r2t) {
spin_lock_bh(&session->lock);
__kfifo_get(tcp_ctask->r2tqueue, (void*)&tcp_ctask->r2t, __kfifo_get(tcp_ctask->r2tqueue, (void*)&tcp_ctask->r2t,
sizeof(void*)); sizeof(void*));
spin_unlock_bh(&session->lock);
}
send_hdr: send_hdr:
r2t = tcp_ctask->r2t; r2t = tcp_ctask->r2t;
dtask = &r2t->dtask; dtask = &r2t->dtask;
...@@ -1816,21 +1819,14 @@ iscsi_tcp_conn_destroy(struct iscsi_cls_conn *cls_conn) ...@@ -1816,21 +1819,14 @@ iscsi_tcp_conn_destroy(struct iscsi_cls_conn *cls_conn)
{ {
struct iscsi_conn *conn = cls_conn->dd_data; struct iscsi_conn *conn = cls_conn->dd_data;
struct iscsi_tcp_conn *tcp_conn = conn->dd_data; struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
int digest = 0;
if (conn->hdrdgst_en || conn->datadgst_en)
digest = 1;
iscsi_tcp_release_conn(conn); iscsi_tcp_release_conn(conn);
iscsi_conn_teardown(cls_conn); iscsi_conn_teardown(cls_conn);
/* now free tcp_conn */ if (tcp_conn->tx_hash.tfm)
if (digest) { crypto_free_hash(tcp_conn->tx_hash.tfm);
if (tcp_conn->tx_hash.tfm) if (tcp_conn->rx_hash.tfm)
crypto_free_hash(tcp_conn->tx_hash.tfm); crypto_free_hash(tcp_conn->rx_hash.tfm);
if (tcp_conn->rx_hash.tfm)
crypto_free_hash(tcp_conn->rx_hash.tfm);
}
kfree(tcp_conn); kfree(tcp_conn);
} }
......
...@@ -975,13 +975,13 @@ int iscsi_eh_host_reset(struct scsi_cmnd *sc) ...@@ -975,13 +975,13 @@ int iscsi_eh_host_reset(struct scsi_cmnd *sc)
if (session->state == ISCSI_STATE_TERMINATE) { if (session->state == ISCSI_STATE_TERMINATE) {
failed: failed:
debug_scsi("failing host reset: session terminated " debug_scsi("failing host reset: session terminated "
"[CID %d age %d]", conn->id, session->age); "[CID %d age %d]\n", conn->id, session->age);
spin_unlock_bh(&session->lock); spin_unlock_bh(&session->lock);
return FAILED; return FAILED;
} }
if (sc->SCp.phase == session->age) { if (sc->SCp.phase == session->age) {
debug_scsi("failing connection CID %d due to SCSI host reset", debug_scsi("failing connection CID %d due to SCSI host reset\n",
conn->id); conn->id);
fail_session = 1; fail_session = 1;
} }
...@@ -1054,7 +1054,8 @@ static int iscsi_exec_abort_task(struct scsi_cmnd *sc, ...@@ -1054,7 +1054,8 @@ static int iscsi_exec_abort_task(struct scsi_cmnd *sc,
NULL, 0); NULL, 0);
if (rc) { if (rc) {
iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
debug_scsi("abort sent failure [itt 0x%x] %d", ctask->itt, rc); debug_scsi("abort sent failure [itt 0x%x] %d\n", ctask->itt,
rc);
return rc; return rc;
} }
...@@ -1071,7 +1072,7 @@ static int iscsi_exec_abort_task(struct scsi_cmnd *sc, ...@@ -1071,7 +1072,7 @@ static int iscsi_exec_abort_task(struct scsi_cmnd *sc,
conn->tmabort_timer.function = iscsi_tmabort_timedout; conn->tmabort_timer.function = iscsi_tmabort_timedout;
conn->tmabort_timer.data = (unsigned long)ctask; conn->tmabort_timer.data = (unsigned long)ctask;
add_timer(&conn->tmabort_timer); add_timer(&conn->tmabort_timer);
debug_scsi("abort set timeout [itt 0x%x]", ctask->itt); debug_scsi("abort set timeout [itt 0x%x]\n", ctask->itt);
} }
spin_unlock_bh(&session->lock); spin_unlock_bh(&session->lock);
mutex_unlock(&conn->xmitmutex); mutex_unlock(&conn->xmitmutex);
......
...@@ -71,55 +71,65 @@ static void smp_task_done(struct sas_task *task) ...@@ -71,55 +71,65 @@ static void smp_task_done(struct sas_task *task)
static int smp_execute_task(struct domain_device *dev, void *req, int req_size, static int smp_execute_task(struct domain_device *dev, void *req, int req_size,
void *resp, int resp_size) void *resp, int resp_size)
{ {
int res; int res, retry;
struct sas_task *task = sas_alloc_task(GFP_KERNEL); struct sas_task *task = NULL;
struct sas_internal *i = struct sas_internal *i =
to_sas_internal(dev->port->ha->core.shost->transportt); to_sas_internal(dev->port->ha->core.shost->transportt);
if (!task) for (retry = 0; retry < 3; retry++) {
return -ENOMEM; task = sas_alloc_task(GFP_KERNEL);
if (!task)
task->dev = dev; return -ENOMEM;
task->task_proto = dev->tproto;
sg_init_one(&task->smp_task.smp_req, req, req_size);
sg_init_one(&task->smp_task.smp_resp, resp, resp_size);
task->task_done = smp_task_done; task->dev = dev;
task->task_proto = dev->tproto;
sg_init_one(&task->smp_task.smp_req, req, req_size);
sg_init_one(&task->smp_task.smp_resp, resp, resp_size);
task->timer.data = (unsigned long) task; task->task_done = smp_task_done;
task->timer.function = smp_task_timedout;
task->timer.expires = jiffies + SMP_TIMEOUT*HZ;
add_timer(&task->timer);
res = i->dft->lldd_execute_task(task, 1, GFP_KERNEL); task->timer.data = (unsigned long) task;
task->timer.function = smp_task_timedout;
task->timer.expires = jiffies + SMP_TIMEOUT*HZ;
add_timer(&task->timer);
if (res) { res = i->dft->lldd_execute_task(task, 1, GFP_KERNEL);
del_timer(&task->timer);
SAS_DPRINTK("executing SMP task failed:%d\n", res);
goto ex_err;
}
wait_for_completion(&task->completion); if (res) {
res = -ETASK; del_timer(&task->timer);
if ((task->task_state_flags & SAS_TASK_STATE_ABORTED)) { SAS_DPRINTK("executing SMP task failed:%d\n", res);
SAS_DPRINTK("smp task timed out or aborted\n");
i->dft->lldd_abort_task(task);
if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) {
SAS_DPRINTK("SMP task aborted and not done\n");
goto ex_err; goto ex_err;
} }
wait_for_completion(&task->completion);
res = -ETASK;
if ((task->task_state_flags & SAS_TASK_STATE_ABORTED)) {
SAS_DPRINTK("smp task timed out or aborted\n");
i->dft->lldd_abort_task(task);
if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) {
SAS_DPRINTK("SMP task aborted and not done\n");
goto ex_err;
}
}
if (task->task_status.resp == SAS_TASK_COMPLETE &&
task->task_status.stat == SAM_GOOD) {
res = 0;
break;
} else {
SAS_DPRINTK("%s: task to dev %016llx response: 0x%x "
"status 0x%x\n", __FUNCTION__,
SAS_ADDR(dev->sas_addr),
task->task_status.resp,
task->task_status.stat);
sas_free_task(task);
task = NULL;
}
} }
if (task->task_status.resp == SAS_TASK_COMPLETE &&
task->task_status.stat == SAM_GOOD)
res = 0;
else
SAS_DPRINTK("%s: task to dev %016llx response: 0x%x "
"status 0x%x\n", __FUNCTION__,
SAS_ADDR(dev->sas_addr),
task->task_status.resp,
task->task_status.stat);
ex_err: ex_err:
sas_free_task(task); BUG_ON(retry == 3 && task != NULL);
if (task != NULL) {
sas_free_task(task);
}
return res; return res;
} }
......
...@@ -328,7 +328,7 @@ static void Irq_Handler (int irq, void *dev_id) ...@@ -328,7 +328,7 @@ static void Irq_Handler (int irq, void *dev_id)
pinquiryData->AdditionalLength = 35 - 4; pinquiryData->AdditionalLength = 35 - 4;
// Fill in vendor identification fields. // Fill in vendor identification fields.
for ( z = 0; z < 20; z += 2 ) for ( z = 0; z < 8; z += 2 )
{ {
pinquiryData->VendorId[z] = ((UCHAR *)identifyData.ModelNumber)[z + 1]; pinquiryData->VendorId[z] = ((UCHAR *)identifyData.ModelNumber)[z + 1];
pinquiryData->VendorId[z + 1] = ((UCHAR *)identifyData.ModelNumber)[z]; pinquiryData->VendorId[z + 1] = ((UCHAR *)identifyData.ModelNumber)[z];
......
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
#define ISCSI_SESSION_ATTRS 11 #define ISCSI_SESSION_ATTRS 11
#define ISCSI_CONN_ATTRS 11 #define ISCSI_CONN_ATTRS 11
#define ISCSI_HOST_ATTRS 0 #define ISCSI_HOST_ATTRS 0
#define ISCSI_TRANSPORT_VERSION "2.0-685" #define ISCSI_TRANSPORT_VERSION "2.0-724"
struct iscsi_internal { struct iscsi_internal {
int daemon_pid; int daemon_pid;
......
...@@ -60,7 +60,7 @@ static int sg_version_num = 30534; /* 2 digits for each component */ ...@@ -60,7 +60,7 @@ static int sg_version_num = 30534; /* 2 digits for each component */
#ifdef CONFIG_SCSI_PROC_FS #ifdef CONFIG_SCSI_PROC_FS
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
static char *sg_version_date = "20060920"; static char *sg_version_date = "20061027";
static int sg_proc_init(void); static int sg_proc_init(void);
static void sg_proc_cleanup(void); static void sg_proc_cleanup(void);
...@@ -710,12 +710,12 @@ sg_common_write(Sg_fd * sfp, Sg_request * srp, ...@@ -710,12 +710,12 @@ sg_common_write(Sg_fd * sfp, Sg_request * srp,
(int) cmnd[0], (int) hp->cmd_len)); (int) cmnd[0], (int) hp->cmd_len));
if ((k = sg_start_req(srp))) { if ((k = sg_start_req(srp))) {
SCSI_LOG_TIMEOUT(1, printk("sg_write: start_req err=%d\n", k)); SCSI_LOG_TIMEOUT(1, printk("sg_common_write: start_req err=%d\n", k));
sg_finish_rem_req(srp); sg_finish_rem_req(srp);
return k; /* probably out of space --> ENOMEM */ return k; /* probably out of space --> ENOMEM */
} }
if ((k = sg_write_xfer(srp))) { if ((k = sg_write_xfer(srp))) {
SCSI_LOG_TIMEOUT(1, printk("sg_write: write_xfer, bad address\n")); SCSI_LOG_TIMEOUT(1, printk("sg_common_write: write_xfer, bad address\n"));
sg_finish_rem_req(srp); sg_finish_rem_req(srp);
return k; return k;
} }
...@@ -746,7 +746,7 @@ sg_common_write(Sg_fd * sfp, Sg_request * srp, ...@@ -746,7 +746,7 @@ sg_common_write(Sg_fd * sfp, Sg_request * srp,
hp->dxfer_len, srp->data.k_use_sg, timeout, hp->dxfer_len, srp->data.k_use_sg, timeout,
SG_DEFAULT_RETRIES, srp, sg_cmd_done, SG_DEFAULT_RETRIES, srp, sg_cmd_done,
GFP_ATOMIC)) { GFP_ATOMIC)) {
SCSI_LOG_TIMEOUT(1, printk("sg_write: scsi_execute_async failed\n")); SCSI_LOG_TIMEOUT(1, printk("sg_common_write: scsi_execute_async failed\n"));
/* /*
* most likely out of mem, but could also be a bad map * most likely out of mem, but could also be a bad map
*/ */
...@@ -1283,7 +1283,7 @@ sg_cmd_done(void *data, char *sense, int result, int resid) ...@@ -1283,7 +1283,7 @@ sg_cmd_done(void *data, char *sense, int result, int resid)
sg_finish_rem_req(srp); sg_finish_rem_req(srp);
srp = NULL; srp = NULL;
if (NULL == sfp->headrp) { if (NULL == sfp->headrp) {
SCSI_LOG_TIMEOUT(1, printk("sg...bh: already closed, final cleanup\n")); SCSI_LOG_TIMEOUT(1, printk("sg_cmd_done: already closed, final cleanup\n"));
if (0 == sg_remove_sfp(sdp, sfp)) { /* device still present */ if (0 == sg_remove_sfp(sdp, sfp)) { /* device still present */
scsi_device_put(sdp->device); scsi_device_put(sdp->device);
} }
...@@ -1512,12 +1512,12 @@ sg_remove(struct class_device *cl_dev, struct class_interface *cl_intf) ...@@ -1512,12 +1512,12 @@ sg_remove(struct class_device *cl_dev, struct class_interface *cl_intf)
POLL_HUP); POLL_HUP);
} }
} }
SCSI_LOG_TIMEOUT(3, printk("sg_detach: dev=%d, dirty\n", k)); SCSI_LOG_TIMEOUT(3, printk("sg_remove: dev=%d, dirty\n", k));
if (NULL == sdp->headfp) { if (NULL == sdp->headfp) {
sg_dev_arr[k] = NULL; sg_dev_arr[k] = NULL;
} }
} else { /* nothing active, simple case */ } else { /* nothing active, simple case */
SCSI_LOG_TIMEOUT(3, printk("sg_detach: dev=%d\n", k)); SCSI_LOG_TIMEOUT(3, printk("sg_remove: dev=%d\n", k));
sg_dev_arr[k] = NULL; sg_dev_arr[k] = NULL;
} }
sg_nr_dev--; sg_nr_dev--;
...@@ -1876,14 +1876,15 @@ sg_build_indirect(Sg_scatter_hold * schp, Sg_fd * sfp, int buff_size) ...@@ -1876,14 +1876,15 @@ sg_build_indirect(Sg_scatter_hold * schp, Sg_fd * sfp, int buff_size)
} }
} }
sg->page = p; sg->page = p;
sg->length = ret_sz; sg->length = (ret_sz > num) ? num : ret_sz;
SCSI_LOG_TIMEOUT(5, printk("sg_build_build: k=%d, a=0x%p, len=%d\n", SCSI_LOG_TIMEOUT(5, printk("sg_build_indirect: k=%d, num=%d, "
k, p, ret_sz)); "ret_sz=%d\n", k, num, ret_sz));
} /* end of for loop */ } /* end of for loop */
schp->k_use_sg = k; schp->k_use_sg = k;
SCSI_LOG_TIMEOUT(5, printk("sg_build_indirect: k_use_sg=%d, rem_sz=%d\n", k, rem_sz)); SCSI_LOG_TIMEOUT(5, printk("sg_build_indirect: k_use_sg=%d, "
"rem_sz=%d\n", k, rem_sz));
schp->bufflen = blk_size; schp->bufflen = blk_size;
if (rem_sz > 0) /* must have failed */ if (rem_sz > 0) /* must have failed */
...@@ -2014,7 +2015,7 @@ sg_remove_scat(Sg_scatter_hold * schp) ...@@ -2014,7 +2015,7 @@ sg_remove_scat(Sg_scatter_hold * schp)
for (k = 0; (k < schp->k_use_sg) && sg->page; for (k = 0; (k < schp->k_use_sg) && sg->page;
++k, ++sg) { ++k, ++sg) {
SCSI_LOG_TIMEOUT(5, printk( SCSI_LOG_TIMEOUT(5, printk(
"sg_remove_scat: k=%d, a=0x%p, len=%d\n", "sg_remove_scat: k=%d, pg=0x%p, len=%d\n",
k, sg->page, sg->length)); k, sg->page, sg->length));
sg_page_free(sg->page, sg->length); sg_page_free(sg->page, sg->length);
} }
......
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